一. 什么是Activity?
Activity,翻譯為“活動”。在Android中,它是四大應用組件之一(其它三個分別為:Service、BroadcastReceiver和ContentProvider)。
二. Activity有什么用?
在我們的應用程序中,Activity一般情況下起到和用戶交互的作用,絕大部分Activity是用于和用戶交互的:Activity會創(chuàng)建一個交互窗口,可以通過調(diào)用setContentView(View)來放置一個布局在activity的窗口中,從而起到和用戶交互的作用。
三. Activity如何使用?
首先,創(chuàng)建Activity,在manifests文件中進行聲明。重寫其生命周期,在不同的方法中就可以為所欲為。關于生命周期以及Activity啟動流程,請看下圖:

流程介紹:
1.Activity啟動 --> onCreate() -->onStart() -->onResume(),接著Activity進入運行狀態(tài)Activity running。
2.當其他Activity覆蓋當前的Activity ,或者鎖屏時,調(diào)用onPause,進入暫停狀態(tài)。
此時被覆蓋的Activity去哪兒了呢?在堆棧(“返回棧”)中保存。當新的Activity銷毀,原來被覆蓋的Activity再回到棧頂,獲取焦點。
3.當被覆蓋的Activity回到前臺,或者屏幕解鎖 -->onResume(),直接進入可交互狀態(tài)。
4.新的Activity來到前臺(foreground),或者返回到主屏。當前Activity調(diào)用onPause()-->onStop(),退居后臺,進入不可見狀態(tài)。
onPause狀態(tài)和onStop狀態(tài)最大的區(qū)別是前者還可能是可見狀態(tài),后者完全不可見。一般情況下,剛開始被覆蓋,先onPause()等著,因為我不知道新的Activity要干嘛...等到新的Activity進入onResume(),被覆蓋的Activity知道暫時沒我啥事了,就onStop()了。
5.用戶再次導航(navigates),也就是再次需要使用onStop狀態(tài)的Activity時,就不需要再次創(chuàng)建了,直接onRestart()-->onStart()-->onResume()再次進入運行(running)狀態(tài)。
6.Activity進入onPause()和onStop()狀態(tài),也就是后臺暫停和不可見狀態(tài)時,當系統(tǒng)內(nèi)存不足時,會殺死當前Activity來騰出內(nèi)存。當用戶再次跳轉到這個Activity時,重新調(diào)用onCreate()-->onStart()-->onResume()再次進入運行狀態(tài)。
重寫onSaveInstanceState方法,可以在被kill掉之前存儲相關信息。
7.用戶退出Activity,調(diào)用onPause()-->onStop()-->onDestroy()。至此,這個Activity就被銷毀掉了。
8.其它:onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState
//當Activity窗口獲得或失去焦點時被調(diào)用,在onResume之后獲得焦點,onPause之后 失去焦點
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i(TAG, "onWindowFocusChanged called.");
}
/**
* Activity被系統(tǒng)殺死時被調(diào)用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當前Activity處于后臺,系統(tǒng)資源緊張將其殺死.
* 另外,當跳轉到其他Activity或者按Home鍵回到主屏時該方法也會被調(diào)用,
* 系統(tǒng)是為了保存當前View組件的狀態(tài).
* 在onPause之前被調(diào)用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(TAG, "onSaveInstanceState called. put param: " + param);
super.onSaveInstanceState(outState);
}
/**
* Activity被系統(tǒng)殺死后再重建時被調(diào)用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;
* 當前Activity處于后臺,系統(tǒng)資源緊張將其殺死,用戶又啟動該Activity.
* 這兩種情況下onRestoreInstanceState都會被調(diào)用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(TAG, "onRestoreInstanceState called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}
四. Activity使用擴展?
4.1.activity啟動方式:
| 啟動方式 | 是否能存在多個實例 | 說明 |
|---|---|---|
| standard | 允許 | 默認啟動方式,總是創(chuàng)建新的實例,因此任務棧會存在多個相同實例 。 |
| singleTop | 看條件 | 如果棧頂存在該Activity的實例,則不會創(chuàng)建新的實例,而是直接跳轉。若不存在,則創(chuàng)建 。 |
| singleTask | 不允許 | 需要跳轉到該Activity時,如果任務棧中存在該Activity的實例,則不會創(chuàng)建新的,而是將intent發(fā)送給已存在的實例,并且移除它前面的所有Activity來將之移到棧頂。 |
| singleInstance | 不允許 | 另起一個任務棧,將以這種方式啟動的Activity放入其中。例:A --> B(singleInstance),B-->C.C點擊返回,直接回到A。因為B在另一個任務棧中。 |
使用方式:
(1) 清單文件中聲明:
<activity android:name=".ui.WebActivity"
android:launchMode="singleTask" />
(2) 代碼設置
Intent intent = new Intent();
// 等同于singleTask
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 等同于singleTop
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 類似singleInstance但每一次都會創(chuàng)建新的實例
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 當離開該activity時,它就會被移除。
intent.setFlags(Intent.FLAG_ACITVITY_NO_HISTORY);
4.2.Activity的intent filter
Intent Filter 描述了一個組件愿意接收什么樣的 Intent 對象,在 Android 的 AndroidManifest.xml 里面可以定義某Activity的<intent-filter >,用于描述該Activity相應Intent的類型。
(1) action 匹配
action 是用戶定義的字符串,用于描述一個 Android 應用程序組件。一個intent filter可以包括多個 action 標簽,用于該Activity所能接收的 “action”。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
SDK中定義了一些標準的動作:
| onstant | Target component | Action |
|---|---|---|
| ACTION_CALL | activity | Initiate a phone call. |
| ACTION_EDIT | activity | Display data for the user to edit. |
| ACTION_MAIN | activity | Start up as the initial activity of a task, with no data input and no returned output. |
| ACTION_SYNC | activity | Synchronize data on a server with data on the mobile device. |
| ACTION_BATTERY_LOW | broadcast receiver | A warning that the battery is low. |
| ACTION_HEADSET_PLUG | broadcast receiver | A headset has been plugged into the device, or unplugged from it. |
| ACTION_SCREEN_ON | broadcast receiver | The screen has been turned on. |
| ACTION_TIMEZONE_CHANGED | broadcast receiver | The setting for the time zone has changed. |
此外,也可以自定義動作,需要加上包名作為前綴。
(2) Data 數(shù)據(jù)匹配
Android指向數(shù)據(jù)一般用Url來表示,例如指向聯(lián)系人:content://contacts/1。ACTION_EDIT指定Data為文件URI,打電話為tel:URI,訪問網(wǎng)絡為http:URI,而由content provider提供的數(shù)據(jù)則為content: URIs。
(3) Category 類別匹配
被執(zhí)行動作的附加信息。它要求Intent中個如果含有category,那么所有的category都必須和過濾規(guī)則中的其中一個category相同。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
4.3.Activity啟動動畫:
這里暫時先寫一種最簡單的方式來實現(xiàn)Activity各種啟動方式和動畫。使用overridePendingTransition方法。例子:
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
從SecondActivity返回的動畫,可以重寫finish()方法來寫上這個方法來定義啟動和退出的動畫。
@Override
public void finish() {
super.finish();
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
}
4.4 Activity的統(tǒng)一管理
(1) 獲取當前Activity名稱,創(chuàng)建BaseActivity。項目中相應的Activity繼承它,重寫onCreate() 來打印它的名字。
public abstract class BaseActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("BaseActivity",getClass().getSimpleName());
}
}
(2) 退出所有Activity。
public static List<Activity> activityList = new ArrayList<>();
// 添加Activity到activityList
public static void addActivity(Activity activity){
activityList.add(activity);
}
// 移除Activity
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
// 移除所有Activity
public static void finishAll(){
for (Activity activity : activityList){
if(!activity.isFinishing()){
activity.finish();
}
}
}
(3) 使用Intent跳轉Activity。
首先在需要跳轉到的Activity定義一個static的方法,用來傳遞context和數(shù)據(jù)。
public static void startNewActivity(Context context,String data1,String data2){
Intent intent = new Intent(context,SecondActivity.class);
intent.putExtra("data1",data1);
intent.putExtra("data2",data2);
context.startActivity(intent);
}
在進行跳轉的Activity里面使用上面定義的方法來進行跳轉,需要傳遞的數(shù)據(jù)一目了然,此外,別的需要跳轉的操作也可以直接使用SecondActivity定義的方法。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SecondActivity.startNewActivity(FirstActivity.this,"data1","data2");
}
});
參考資料:
1.Activity生命周期
2.Activity簡介
3.Intent Filter 匹配規(guī)則
4.實現(xiàn)Activity跳轉動畫的五種方式
5.《第一行代碼(第二版》