一. 什么是Activity先紫?
Activity巡语,翻譯為“活動”。在Android中沐旨,它是四大應(yīng)用組件之一(其它三個分別為:Service衅金、BroadcastReceiver和ContentProvider)噪伊。
二. Activity有什么用簿煌?
在我們的應(yīng)用程序中,Activity一般情況下起到和用戶交互的作用鉴吹,絕大部分Activity是用于和用戶交互的:Activity會創(chuàng)建一個交互窗口姨伟,可以通過調(diào)用setContentView(View)來放置一個布局在activity的窗口中,從而起到和用戶交互的作用豆励。
三. Activity如何使用夺荒?
首先,創(chuàng)建Activity良蒸,在manifests文件中進(jìn)行聲明技扼。重寫其生命周期,在不同的方法中就可以為所欲為嫩痰。關(guān)于生命周期以及Activity啟動流程剿吻,請看下圖:
流程介紹:
1.Activity啟動 --> onCreate() -->onStart() -->onResume(),接著Activity進(jìn)入運(yùn)行狀態(tài)Activity running串纺。
2.當(dāng)其他Activity覆蓋當(dāng)前的Activity 丽旅,或者鎖屏?xí)r,調(diào)用onPause纺棺,進(jìn)入暫停狀態(tài)榄笙。
此時被覆蓋的Activity去哪兒了呢?在堆棧(“返回椀或颍”)中保存茅撞。當(dāng)新的Activity銷毀,原來被覆蓋的Activity再回到棧頂杆逗,獲取焦點(diǎn)乡翅。
3.當(dāng)被覆蓋的Activity回到前臺,或者屏幕解鎖 -->onResume()罪郊,直接進(jìn)入可交互狀態(tài)。
4.新的Activity來到前臺(foreground)尚洽,或者返回到主屏悔橄。當(dāng)前Activity調(diào)用onPause()-->onStop(),退居后臺腺毫,進(jìn)入不可見狀態(tài)癣疟。
onPause狀態(tài)和onStop狀態(tài)最大的區(qū)別是前者還可能是可見狀態(tài),后者完全不可見潮酒。一般情況下睛挚,剛開始被覆蓋,先onPause()等著急黎,因?yàn)槲也恢佬碌腁ctivity要干嘛...等到新的Activity進(jìn)入onResume()扎狱,被覆蓋的Activity知道暫時沒我啥事了侧到,就onStop()了。
5.用戶再次導(dǎo)航(navigates)淤击,也就是再次需要使用onStop狀態(tài)的Activity時匠抗,就不需要再次創(chuàng)建了,直接onRestart()-->onStart()-->onResume()再次進(jìn)入運(yùn)行(running)狀態(tài)污抬。
6.Activity進(jìn)入onPause()和onStop()狀態(tài)汞贸,也就是后臺暫停和不可見狀態(tài)時,當(dāng)系統(tǒng)內(nèi)存不足時印机,會殺死當(dāng)前Activity來騰出內(nèi)存矢腻。當(dāng)用戶再次跳轉(zhuǎn)到這個Activity時,重新調(diào)用onCreate()-->onStart()-->onResume()再次進(jìn)入運(yùn)行狀態(tài)射赛。
重寫onSaveInstanceState方法多柑,可以在被kill掉之前存儲相關(guān)信息。
7.用戶退出Activity咒劲,調(diào)用onPause()-->onStop()-->onDestroy()顷蟆。至此,這個Activity就被銷毀掉了腐魂。
8.其它:onWindowFocusChanged帐偎、onSaveInstanceState、onRestoreInstanceState
//當(dāng)Activity窗口獲得或失去焦點(diǎn)時被調(diào)用,在onResume之后獲得焦點(diǎn)蛔屹,onPause之后 失去焦點(diǎn)
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i(TAG, "onWindowFocusChanged called.");
}
/**
* Activity被系統(tǒng)殺死時被調(diào)用.
* 例如:屏幕方向改變時,Activity被銷毀再重建;當(dāng)前Activity處于后臺,系統(tǒng)資源緊張將其殺死.
* 另外,當(dāng)跳轉(zhuǎn)到其他Activity或者按Home鍵回到主屏?xí)r該方法也會被調(diào)用,
* 系統(tǒng)是為了保存當(dā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被銷毀再重建;
* 當(dāng)前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使用擴(kuò)展削樊?
4.1.activity啟動方式:
啟動方式 | 是否能存在多個實(shí)例 | 說明 |
---|---|---|
standard | 允許 | 默認(rèn)啟動方式,總是創(chuàng)建新的實(shí)例兔毒,因此任務(wù)棧會存在多個相同實(shí)例 漫贞。 |
singleTop | 看條件 | 如果棧頂存在該Activity的實(shí)例,則不會創(chuàng)建新的實(shí)例育叁,而是直接跳轉(zhuǎn)迅脐。若不存在,則創(chuàng)建 豪嗽。 |
singleTask | 不允許 | 需要跳轉(zhuǎn)到該Activity時谴蔑,如果任務(wù)棧中存在該Activity的實(shí)例,則不會創(chuàng)建新的龟梦,而是將intent發(fā)送給已存在的實(shí)例隐锭,并且移除它前面的所有Activity來將之移到棧頂。 |
singleInstance | 不允許 | 另起一個任務(wù)棧计贰,將以這種方式啟動的Activity放入其中钦睡。例:A --> B(singleInstance),B-->C.C點(diǎn)擊返回,直接回到A躁倒。因?yàn)锽在另一個任務(wù)棧中荞怒。 |
使用方式:
(1) 清單文件中聲明:
<activity android:name=".ui.WebActivity"
android:launchMode="singleTask" />
(2) 代碼設(shè)置
Intent intent = new Intent();
// 等同于singleTask
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 等同于singleTop
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 類似singleInstance但每一次都會創(chuàng)建新的實(shí)例
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 當(dāng)離開該activity時洒琢,它就會被移除。
intent.setFlags(Intent.FLAG_ACITVITY_NO_HISTORY);
4.2.Activity的intent filter
Intent Filter 描述了一個組件愿意接收什么樣的 Intent 對象挣输,在 Android 的 AndroidManifest.xml 里面可以定義某Activity的<intent-filter >纬凤,用于描述該Activity相應(yīng)Intent的類型。
(1) action 匹配
action 是用戶定義的字符串撩嚼,用于描述一個 Android 應(yīng)用程序組件停士。一個intent filter可以包括多個 action 標(biāo)簽,用于該Activity所能接收的 “action”完丽。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
SDK中定義了一些標(biāo)準(zhǔn)的動作:
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)絡(luò)為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啟動動畫:
這里暫時先寫一種最簡單的方式來實(shí)現(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) 獲取當(dāng)前Activity名稱,創(chuàng)建BaseActivity磅氨。項(xiàng)目中相應(yīng)的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跳轉(zhuǎn)Activity决瞳。
首先在需要跳轉(zhuǎn)到的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);
}
在進(jìn)行跳轉(zhuǎn)的Activity里面使用上面定義的方法來進(jìn)行跳轉(zhuǎn),需要傳遞的數(shù)據(jù)一目了然痴颊,此外赏迟,別的需要跳轉(zhuǎn)的操作也可以直接使用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.實(shí)現(xiàn)Activity跳轉(zhuǎn)動畫的五種方式
5.《第一行代碼(第二版》