【Android】22.0 許可權處理(四)——應用程式版本控制:Git的使用

weixin_34402408發表於2019-02-21
1.0 當然,其實本篇和許可權處理沒有什麼關係。但是:

我們需要用到上一篇博文中ProviderTest專案來當小白鼠,當然,這個專案能不能執行,無所謂。
連結在此:【Android】21.0 許可權處理(三)——訪問其他程式資料:提供資料給別的程式使用
備註:本篇內容獨立,與上篇沒有任何關係,事實上你可以用任何一個專案來操作,下面會先把這個ProviderTest專案的程式碼貼出來,所以事實上不需要去管ProviderTest專案是幹嘛的。

2.0 Git:分散式版本控制系統

百度百科連結:GIT (分散式版本控制系統)

備註: Git的“親爹”是linux作業系統的“親爹”——林納斯·託瓦茲(Linus Torvalds),所以,不只是Android開發,Git能用到的地方很多……

再備註: Git就是開發時,用來方便你控制自己寫的“山寨QQ”軟體現在是1.0版本還是2.0版本,然後還可以查到1.0幹了什麼,2.0相對於1.0修改了什麼,還可以回滾到1.0版本(覺得我這話還是沒法理解的,請往上走去找度娘)

再再備註: 有了Git,很簡單就可以實現——多人同時開發一個專案。

3.0 對,你的感覺沒錯,Git是需要另外安裝的,它是一個軟體。

Windowslinux安裝網上都有很多辦法。而且,Windows系統和linux系統安裝同樣的簡單粗暴:

Windows
下載連結:Git最新版本下載官網
(你沒看錯,這個官網網站名字就叫“Git下載Downloading Git”)
從上面這個連結你可以從官網上下載到最新的Git軟體

Linux:
開啟shell介面,輸入:

sudo apt-get install git-core

(GitLinux都是同一個作者,所以其實在Linux系統上安裝反而最簡單方便)

具體圖文安裝教程如下(我知道,有的人的確需要帶路黨才不會出錯,我做的就是這樣的事情):
連結:Windows下的git安裝教程(其實除了選一下安裝目錄,也就是一直下一步)
連結:linux下安裝git(其實就是一句執行命令的事情)

備註:上面linux系統安裝這個連結,是基於Centos linux系統環境下,也就是RedHat Enterprise Linux (RHEL)Fedora系列通用的教程。其實常用的linux發行版一般都會內建好GitUbuntu系統應該只會更簡單,比如去“應用商店”找一下……

4.0 這時候(或者某個時候……),Android studio會自動提示(右下角彈出一個小提示框),你似乎可以繫結下Git?!

連結:AndroidStudio怎樣和Git關聯
事實上一般Android studio會很智慧的讓你把提示點開,然後填入Git安裝目錄地址,找到Git.exe,確認,就搞定了。然後就會出現方便的Git控制:

16102290-18fa579e7bccb702.png
2019-02-21_103504.png

5.0 好吧,原始出奇跡,你可以在cmd中輸入git --version
16102290-fed633ee4592c260.png
2019-02-21_103710.png

可以看到,確確實實是裝好了。

然後桌面也會出現Git Bash圖示(快捷方式),點開它:

16102290-126c6f12035a17e8.png
2019-02-21_103821.png

16102290-46b0ee79f2cdc3a8.png
2019-02-21_103857.png

6.0 新手學習階段,先學會一個語句:

find . -name ".git" | xargs rm -Rf

16102290-2e081d69d0f4332d.png
2019-02-21_105252.png

這樣當你玩脫了的時候,這個命令可以幫助你刪掉某個專案中Git的一切(相當於解除安裝該專案的Git),你可以重新給專案安裝Git,再來一次……

7.0 Git使用前,需要做一件事。
  • 給自己弄個身份,這樣在提交程式碼的時候Git可以知道是誰在提交程式碼。命令如下:
git config --global user.name "Tony"
git config  --global user.email "Tony@email.com"

(當然你可以叫別的,這只是一個示範案例而已。)

8.0 先把ProviderTest專案的程式碼貼上來:
  • 專案檔案目錄


    16102290-32fcfdbf129741c4.png
    2019-02-20_210200.png
  • activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/add_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新增資料到book"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.20"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.06" />

    <Button
        android:id="@+id/query_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="從book中查詢資料"
        app:layout_constraintBottom_toBottomOf="@+id/add_data"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/add_data"
        app:layout_constraintTop_toTopOf="@+id/add_data" />

    <Button
        android:id="@+id/update_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="更新資料到book"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/add_data"
        app:layout_constraintStart_toStartOf="@+id/add_data"
        app:layout_constraintTop_toBottomOf="@+id/add_data"
        app:layout_constraintVertical_bias="0.06" />

    <Button
        android:id="@+id/delete_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="從book中刪除資料"
        app:layout_constraintBottom_toBottomOf="@+id/update_data"
        app:layout_constraintEnd_toEndOf="@+id/query_data"
        app:layout_constraintStart_toStartOf="@+id/query_data"
        app:layout_constraintTop_toTopOf="@+id/update_data" />

</android.support.constraint.ConstraintLayout>
  • MainActivity.java
package com.example.providertest;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private String newId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //新增資料
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
                ContentValues values = new ContentValues();
                values.put("name", "王之國度");
                values.put("author", "張三");
                values.put("pages", 1040);
                values.put("price", 55.55);
                Uri newUri = getContentResolver().insert(uri, values);
                newId = newUri.getPathSegments().get(1);

            }
        });

        Button queryData = (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        Toast.makeText(MainActivity.this,
                                "name is" + name + ",\n author is" + author +
                                        ",\n pages is" + pages + ",\n price is" + price,
                                Toast.LENGTH_SHORT).show();
                    }
                    cursor.close();
                }
            }
        });

        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //更新資料
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
                ContentValues values = new ContentValues();
                values.put("name","創世之神");
                values.put("pages", 8250);
                values.put("price", 198.72);
                getContentResolver().update(uri, values, null, null);
            }
        });

        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
                //刪除資料
                getContentResolver().delete(uri, null, null);
            }
        });
    }
}
  • AndroidManifest.xml沒有修改,就不貼程式碼了。
9.0 具體操作如下(可能知識點講解會相當繁瑣,但我以谷歌的人品發誓,知識點絕對是不重複的):
  • 1.準備工作:
    開啟Git Bash,,進入專案的根目錄下,然後執行git init
    16102290-34731c83620bc466.png
    2019-02-21_091907.png

    這樣準備工作就已經完成了,我們可以繼續Git之旅。
  • 2.提交ProviderTest專案程式碼。
    • 在提交之前我們還有一個問題:是不是所有檔案都會加入版本控制當中?
      比如說,我們知道Android專案結構目錄下,build目錄下的檔案是編譯專案時自動生成的,所以這部分檔案新增到版本控制之中,沒有任何意義,而且還會增加你的資料閱讀量。

      這裡, Git 使用的是排除法,它有一套可配性很強的機制,檢查程式碼倉庫目錄下是否存在一個名為.gitignore的檔案(記事本就可以開啟),它會一行一行去讀取裡面的內容,把每一行指定的檔案目錄排除在版本控制之外(注意:.gitignore指定的檔案目錄可以使用*萬用字元)

      16102290-09426a3778cddeb7.png
      2019-02-21_111720.png

      16102290-75230f08d414f39a.png
      2019-02-21_111834.png

      可以看到,Git 是不管裡面這些檔案的版本控制的。

在app模組下還有一個.gitignore檔案,這個就簡單多了:

16102290-c613612259a66033.png
2019-02-21_111950.png

16102290-6a8f6c20bf724cb0.png
2019-02-21_092146.png

由於app模組下基本都是我們自己編寫的程式碼,所以預設只會有其中的build目錄不會被新增到版本控制之中。

但我們可以任意新增,比如說app模組下所有的測試檔案我都只提供給自己用,並不想上傳到Git版本控制中,那麼我們可以這樣修改app/.gitignore檔案中的內容:

16102290-a1368384e28545cf.png
2019-02-21_092122.png

好,理論講解完畢,提交程式碼只有兩句命令:
先使用add命令將所有檔案新增,命令如下:

git add .

然後執行commit命令完成提交,命令如下:

git commit -m "First commit"

執行結果如下:


16102290-ccc776e72242d8ce.png
2019-02-21_092254.png

我們可以檢視一下提交記錄,命令如下:

git log

執行結果如下:


16102290-1414094b5bf3e5fa.png
2019-02-21_113324.png

可以看到,確確實實是提交成功了。

  • 3.檢視修改內容
    命令如下:
git status

執行結果如下:

16102290-c4e8d45e51c6e2f8.png
2019-02-21_092350.png

可以看到,Git提示沒有任何可提交的檔案。

現在我們修改下ProviderTest專案中的程式碼,修改MainActivity.java中的程式碼:

16102290-9b0b8658ab819433.png
2019-02-21_113726.png

重新輸入git status命令,結果如下:

16102290-86db7cde752ccbcd.png
2019-02-21_092521.png

可以看到,Git提示我們MainActivity.java檔案已經發生了改變。
檢視更改內容命令:

git diff

命令執行結果如下:

16102290-016ef36465f2c61e.png
檢視修改的具體內容

減號代表刪除部分,
加號代表新增部分。

如果只想檢視MainActivity.java檔案修改的部分:

git dif fapp/src/main/java/com/example/providertest/MainActivity.java

命令執行結果如下:
16102290-6386c4aef327e044.png
2019-02-21_092747.png
  • 4.撤銷未提交的修改
    這可以解決我們有時候程式碼寫的過於草率,以至於原本正常的功能,結果反而被我們改出了問題。

遇到這種問題,我們只要程式碼未提交,修改的內容可以通過Git命令撤銷。
比如撤銷上面價格的修改:

git checkout app/src/main/java/com/example/providertest/MainActivity.java

命令執行結果如下:


16102290-46808cfbf265d432.png
2019-02-21_092912.png

我們點開Android Studio,檢視MainActivity.java檔案:


16102290-f25a3c77e363d202.png
16102290-729be1adb785b8dc.png

會發現程式碼已被自動還原成價格45.96

再執行git status命令檢查一下,結果如下:

16102290-37def014852e971a.png
2019-02-21_093010.png

可見,撤銷不僅真的撤銷成功了,而且Git也認為它已經撤銷成功了。

但是如果某個檔案已經新增了,那麼就無法撤銷其修改的內容,比如我們重新把價格改為55.55,然後執行如下命令:

gti add .

再執行git status命令檢查一下,結果如下:

16102290-d01e698e8728fb70.png
2019-02-21_100411.png

如果我們再執行一遍checkout命令,會發現Android Studio裡面ProviderTest專案中MainActivity.java檔案的內容無法被撤銷掉:
16102290-560919af1a37bc04.png
2019-02-21_1552.png

16102290-85a40d83d692caed.png
2019-02-21_120236.png

我們可以取消新增,然後撤銷,取消新增命令如下:

git reset HEAD  app/src/main/java/com/example/providertest/MainActivity.java

執行結果如下:

16102290-27c9dbb767612208.png
2019-02-210552.png

檢視Android Studio裡面ProviderTest專案中MainActivity.java檔案,又回滾到價格45.96

  • 5.檢視提交記錄。
    上面已經介紹了,我們繼續把Android Studio裡面ProviderTest專案中MainActivity.java檔案中的價格修改為55.55,然後再執行一次提交操作:
git add .
git commit -m "Change price"

重新執行git log,執行結果如下:

16102290-be753b980a557803.png
2019-02-21_100552.png

16102290-9bc1d27cede6a737.png
2019-02-21_100601.png

當提交記錄較多時,如果只想檢視其中一條記錄,我們可以指定該記錄的id,並加上-1參數列示我們只想看到一行記錄,命令如下:

git log  c8405ae68eed5e6d7b20fa9a4c84caf09619fd3c -1

執行結果如下:


16102290-ced09e07ba3dd2b0.png
2019-02-21_100700.png

如果想看這條記錄修改了什麼內容,可以在命令中加入-p引數,命令如下:

git log  c8405ae68eed5e6d7b20fa9a4c84caf09619fd3c -1 -p

執行結果如下:


16102290-195a7982664b2a3d.png
2019-02-21_100757.png

就說到這裡。

END

相關文章