昨天說明完Activityes 生命週期 今天會說一下 Activity 如何透過程式碼方式來起動Activity與細節
當Actvity 啟動時 會回應一個Screen 給使用者 並處理後續User與APP互動 有什麼方式可以去啟動 Activity 呢? 我會說一下如何透過程式啟動Activity
Intent 是 Messaging 物件 Intent可以請求其他元件操作
例如 在MainActivity.java 這個Activity 啟動 TargetActivity(這個也是Activity) 並傳遞額外資料(Key:Tester)
// In the source Activity (e.g., MainActivity.java)
Intent intent = new Intent(this, TargetActivity.class);
// Optionally, you can add extra data to the Intent
intent.putExtra("key", "Tester");
putExtra 這個屬性傳遞了 parameter = key, value = Tester
我們創好 intent 物件時 就能透過 startActivity() 或是 startActivityForResult() 把intent 傳入
來啟動Activity
其中startActivity() 不期望回傳值 類似 void 這個概念 另外startActivityForResult() 會有啟動後新的Activity 的回傳值
// For launching an Activity without expecting any result back
startActivity(intent);
// For launching an Activity and expecting a result back
int requestCode = 1; // A unique integer request code to identify the result
startActivityForResult(intent, requestCode);
在Android OS 中 會使用stack 方式來管理 Activity 我們稱為back Stack 可以想成單一動作的集合 每個Task就會有個back Stack 管理這些 Activities
舉個例子 如果我們創建了新的Activity 這個Activity 會被Push進去 tack中
在Stack 頂部 就會像這樣
[TargetActivity] <- 頂部,活躍
[MainActivity]
當 TargetActivity 被push進來 MainActivity 就會進入到onStop 狀態 並透過 onSaveInstanceState 保存其狀態
當user滑掉Activity 就會PoP 掉 MainActivity 就會進入 onResume 狀態
[MainActivity] <- 頂部,活躍
當Target Activity 被push 進來時 MainActivity 就會進入onPuse() 狀態
Target Activity 調用 onCreate(), onStart(), onResume() 等等 初始化 或開始執行特定Task
開始跑TargetActivity 並接收 MainActivity 的傳參
public class TargetActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);
// Get data from the Intent
String data = getIntent().getStringExtra("key");
}
// Other lifecycle methods, like onStart(), onResume(), onPause(), onStop(), onDestroy()
}
當使用者 想返回上一個Activity 時 Target Activity 會吃到 finish() 進入 onPause(), onStop(), onDestroy() 狀態 先前Activity 會調用 onRestart(), onStart(), onResume() 等等
以下是 Target Activity 返回並傳值
// Set result and finish the Activity
Intent resultIntent = new Intent();
resultIntent.putExtra("result_key", "result_value");
setResult(RESULT_OK, resultIntent);
finish();
原Activity 如果是使用 startActivityForResult() 就會預期新的Activity 在setResult() 的值
在原Activity 會使用 onActivityResult()來handle 結果
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) { // Match the request code used in startActivityForResult()
if (resultCode == RESULT_OK && data != null) {
String resultData = data.getStringExtra("result_key");
// Process the result data
}
}
}
整體簡單流程
Activity 的啟動 不只只能透過點 APP 圖標與 App 本身程式 還能透過ADB 方式啟動並傳參
後面會在介紹一下ADB這個tools
為了讓Activity 跑起來 我們需要再 manifest 的 Applicaiton 標籤下的 Activity 標籤宣告
其中 android:name 就會包含Activity 類別名
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- Declare your Activity here -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Declare other Activities if needed -->
<!-- <activity android:name=".AnotherActivity" /> -->
</application>
</manifest>
我們可以觀察 Activity 下的Action
android.intent.action.MAIN 這個Action表示 是APP 的程式入口 (第一個啟動的Activity)
android.intent.category.LAUNCHER 告訴Android Systems 這個activity 在啟動器的清單中 也就是用戶點app圖案時就會啟動Activity
由時候我們會看到exprot=true 這表示這個component 可以被其他APP 或 ADB 啟動或傳值進去
<manifest ...>
<application ...>
<activity
android:name=".MyCustomActivity"
android:exported="true">
<!-- Intent filters if needed -->
</activity>
</application>
</manifest>
以上是Activity 解說 之後會繼續說明其他組件