《第一行代碼》——Intent,數據傳遞,活動的生命週期

整理自《第一行代碼》一二兩章

安卓基礎知識

啓動程序

<activity android:name=".MainActivity">
      <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>

.MainActivity 爲開始執行的類文件。這段代碼對 MainActivity 活動進行註冊,表示其爲主活動,在手機上點擊應用圖標,首先啓動的就是此活動。

apply plugin: 'com.android.application'
//插件,application表示是應用模塊,library表示是庫
android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.example.finaltop"	//指定項目的包名
        minSdkVersion 14					  //項目兼容的最低版本
        targetSdkVersion 29					  //已檢測過可運行的版本
        versionCode 1
        versionName "1.0"						//項目版本號和項目版本名
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {			//debug指定生成測試版安裝文件的配置 release指定生成正式版安裝文件的配置
        release {
            minifyEnabled false			//是否對項目的代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'			//混淆時使用的規則文件
        }
    }
}

Intent(意圖)

顯示創建Intent

Intent intent = new Intent(MainActivity.this,SecondActivity.class); 
startActivity(intent);

隱式創建Intent

當前活動可以相應 com.example.activitytest.ACTION_START這個action,<category>標籤包含了附加信息,更精確地指明瞭當前的活動能夠響應的Intent中還可能帶有的category。只有兩個標籤中的內容能夠同時匹配上Intent中指定的action和category,該活動才能響應該intent。

<activity android:name=".SecondActivity">
      <intent-filter>
            <action android:name="com.example.activitytest.ACTION_START" />
            <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
</activity>
Intent intent = new Intent("com.example.activitytest.ACTION_START");
//想要啓動一種能響應ACTION_START的活動,DEFAULT爲默認的category
startActivity(intent);
intent.addCategory("com.example.activitytest.MY_CATEGORY");
//可以通過此函數增加category但是運行會報錯,intent可以指定多個category

首先指定了intent的action是ACTION_VIEW,這是安卓系統內置的動作,常量值爲 android.intent.action.VIEW 。然後通過 Uri.parse("http://www.baidu.com") 方法將網址字符串解析成Uri對象,再調用 setData() 方法將此對象傳遞過去。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);

可以配置Data標籤,精確指定當前活動能夠響應的數據類型。只有標籤內指定內容完全一致纔可以響應該intent。

android:scheme					//指定數據協議部分
android:host					//指定主機部分
android:port					//指定端口部分
android:path					//指定主機名和端口之後的部分
android:mimeType				//指定可以處理的數據類型,允許使用通配符的方式進行指定
//如下例所示只響應協議爲http的活動
<data android:scheme="http" />		

傳遞數據(前——>後 / 後——>前)

String data = "hello world!";
Intent intent = new Intent(MainActivity.this,ScondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);
//將數據傳遞給下一個intent

Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
//下一個intent進行接收

/*******************************************************************/
Intent intent = new Intent(MainActivity.this,ScondActivity.class);
startActivityForResult(intent,1);//請求碼傳入唯一值即可
protected void onActivityResult(int requestCode,int resultCode,Intent data){
    switch(requestCode){//啓動活動時傳入的請求碼
        case 1:
            if(resultCode == RESULT_OK){
                String returnedData = data.getStringExtra("data_return");//接收數據
                Log.d("FirstActivity",returnedData);
            }break;
            default;
    }
}


//重寫onBackPressed() 用戶按下back鍵也可返回信息
public void onBackPressed(){
    Intent intent = new Intent();
    intent.putExtra("data_return","Hello FirstActivity");
    setResult(RESULT_OK,intent);
	finish();
}

Intent intent = new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK,intent);
finish();
//將帶有返回數據的意圖傳遞回去
/*************************使用bundle***********************************/
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    String tempData = "something";
    outState.putString("data_key",tempData);
}

protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.id.activity_main);
    if(savedInstanceState!=null){
        String tempData = savedInstanceState.getString("data_key");
        Log.d(TAG,tempData);
    }
}

活動的生命週期

活動狀態:運行狀態、暫停狀態、停止狀態、銷燬狀態

活動的生存期

完整生存期:活動在onCreate()和onDestroy()之間經歷的就是完整生存期。

可見生存期:活動在onStart()和onStop()之間經歷的是可見生存期。在這一階段,活動對於用戶總是可見,即使可能無法與用戶進行交互。因此我們應合理管理對用戶可見的資源。如選擇合適的時機對資源進行加載和釋放。

前臺生存期:活動在onResume()和onPause()之間經歷的就是前臺生存期。活動總是處於運行狀態。

方法名 意義
onCreate() 活動第一次創建的時候調用,完成初始化操作,加載佈局、綁定事件
onStart() 由不可見變爲可見時調用
onResume() 與用戶進行交互時調用,此時其一定處於棧頂並處於運行狀態
onPause() 系統準備去啓動或恢復另一個進程時調用,釋放CPU資源保存關鍵數據
onStop() 活動完全不可見時調用
onDestroy() 活動被銷燬之前調用,之後的狀態變爲銷燬狀態
onRestart() 活動重新啓動

不難看出, 以上方法除了Restart外都是兩兩相對的。其中Stop和Pause方法的區別是如果新活動是對話框式的則pause會執行而stop不會。

活動的啓動模式

standard 默認的啓動模式。每啓動一個新的活動,就會在返回棧中入棧,並處於棧頂的位置。對於使用standard模式的活動,系統不會在乎活動是否已經在返回棧中存在,每次啓動都會創建該活動的一個新的實例。

singletop 在啓動活動時如果發現返回棧頂的棧頂已經是該活動,則認爲可以直接使用它,不會再創建新的活動實例。

singleTask 每次啓動該活動時系統首先會在返回棧中檢測是否存在該活動的實例,如果發現已經存在則直接使用該實例,並把在這個活動之上的所有活動統統出戰,如果沒有發現就會創建一個新的活動實例。

singleinstance 啓用一個新的返回棧來管理這個活動。有一個單獨的返回棧來管理這個活動,不管是哪個應用程序來訪問這個活動,都共用的同一個返回棧,也就解決了共享活動實例的問題。

android:launchMode="singleinstantce"

退出程序

public class ActivityCollector{
    public static List<Activity> activities = new ArrayList<>();
    public static void addActivity(Activity activity){
        activities.add(activity);
    }
    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }
    public static void finishAll(){
        for(Activity activity:activities){
            if(!activity.isFinishing()){
                activity.finish();
            }
        }
    }
}

public class BaseActivity extends AppCompatActivity{
    protected void onCreate(Bundle savedInstanceState){
        /****/
        ActivityCollector.add(this);
    }
    protected void onDestroy(){
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

//android.os.Process.killProcess(android.os.Process.myPid());
//殺掉一個進程,接收進程ID參數。但此方法只能用於殺掉當前程序的進程,不能殺掉其他程序。

其他方法

getMenuInflater().infalte(R.menu.main,menu);	//創建互動菜單,(資源文件,傳遞目標對象)
finish();									//銷燬活動
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章