① 請問,如何使安卓軟體中的Activity在後台以及關閉屏幕後能繼續運行
實現activity後台運行有兩種方法:
方法一:
添加下列代碼即可:
java">Intentintent=newIntent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
方法二:
此方法其實不是主要是屏蔽Keycode_Back,讓它不結束(finish())Activity,直接顯示HOME界面。
PackageManagerpm=getPackageManager();
ResolveInfohomeInfo=pm.resolveActivity(newIntent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME),0);
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
if(keyCode==KeyEvent.KEYCODE_BACK){
ActivityInfoai=homeInfo.activityInfo;
IntentstartIntent=newIntent(Intent.ACTION_MAIN);
startIntent.addCategory(Intent.CATEGORY_LAUNCHER);
startIntent.setComponent(newComponentName(ai.packageName,
ai.name));
startActivitySafely(startIntent);
returntrue;
}else
returnsuper.onKeyDown(keyCode,event);
}
voidstartActivitySafely(Intentintent){
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try{
startActivity(intent);
}catch(ActivityNotFoundExceptione){
Toast.makeText(this,R.string.unabletoopensoftware,
Toast.LENGTH_SHORT).show();
}catch(SecurityExceptione){
Toast.makeText(this,R.string.unabletoopensoftware,
Toast.LENGTH_SHORT).show();
Log
.e(
TAG,
""
+intent
+".MakesuretocreateaMAINintent-"
+".",
e);
}
}
② android Activity生命周期解析
Activity 用戶可以做單一的、集中的事情。幾乎所有的Activity都與用戶進行交互,所以Activity類負責創建一個窗口,你可以通過調用setContentView(View)把你的UI布局放置在Activity的窗口中。作為四大組件之一,使用頻率非常高。深入了解Activity,對於我們高質量開發是很有幫助的,下面我們就來看看Activity的生命周期。
Android系統中是通過Activity棧的方式來管理Activity的,而Activity自身則是通過生命周期的方法來管理的自己的創建與銷毀。那麼我們就來看看Activity生命周期是怎樣運作的。
周期即活動從開始到結束所經歷的各種狀態。生命周期即活動從開始到結束所經歷的各個狀態。從一個狀態到另一個狀態的轉變,從無到有再到無,這樣一個過程中所經歷的狀態就叫做生命周期。
Acitivity本質上有四種狀態:
在上面的四中常有的狀態之間,還有著其他的生命周期來作為不同狀態之間的過度,用於在不同的狀態之間進行轉換。
我們先來看看下面這張經典的生命周期流程圖:
1)啟動Activity
onCreate() —> onStart() —> onResume()
2)按Home鍵回到桌面 / 鎖屏
onPause() —> onStop()
3)從桌面回到Activity / 解鎖
onRestart() —> onStart() —> onResume()
4)跳轉新Activity
A: onPause() —> onStop()
B: onCreate() —> onStart() —> onResume()
A —> B: onPause()_A —> onCreate()_B —> onStart()_B —> onResume()_B —> onStop()_A
5)返回上一個Activity
B: onPause() —> onStop() —> onDestroy()
A: onRestart() —> onStart() —> onResume()
B —> A: onPause()_B —> onRestart()_A —> onStart()_A —> onResume()_A —> onStop()_B —> onDestroy()_B
6)退出Activity
onPause() —> onStop() —> onDestroy()
Activity官方文檔,開啟傳送門
至此Activity的整個生命周期都介紹完了,現在我們再看之前的生命周期流程圖,是不是清晰許多。搞清楚Activity活動原理,這樣理解起來就會容易許多,工作中也能如魚得水。
③ 安卓開發activity怎麼在主線程中sleep
在onCreate()或onResume()方法里直接調用Thread.sleep(1000)就可以。這里1000表示1秒。
不過這樣做很容易導致app停止響應,即ANR。
④ android activity的關閉處理的幾種方式
項目中我們往往要用到關閉程序時銷毀所有的activity,而且這也是面試經常遇到的問題,退出程序的方式也有好幾種,一下是一些處理關閉程序的方法:
1.最簡單的方式就是使用系統的方法exit(0),這是最簡單粗暴的方式,強製程序退出,但是這種方法針對部分機型有可能不太好使,退出時有可能出現程序崩潰的彈出框,或者程序會重新啟動,這對用戶體驗來說不是很好。
2.拋出異常強制退出,這種方法的使用對用戶體驗來說簡直就是災難,所以就不要用這種方式了。
3.使用廣播的方式通知activity進行關閉,這種方式也有人在用,大家可以自行網路下,我主要介紹下面這種方式。
4.使用application,在application中創建activity集合,創建添加以及刪除activity的方法,並且在BaseActivity中的生命周期中調用這些方法,在使用的時候調用BaseApplication的方法,這也是目前最常用的方法,但是這種在BaseActivity中添加activity的方法也有一個問題,那就是當你要使用第三方的BaseActivity的時候,一個還好你可以繼承,那如果要使用兩個第三方的BaseActivity呢, Java 本身是單繼承的,所以就會導致activity關閉不全了。那麼這個問題的解決就要依靠一介面: ActivityLifecycleCallbacks ;這是Application中聲明的一個介面,其內容如下:
@Override
public voidonActivityCreated(Activity activity,Bundle bundle) {
Log.e("onActivityCreated---","is running"+"--"+activity.getLocalClassName());
}
@Override
public voidonActivityStarted(Activity activity) {
Log.e("onActivityStarted---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityResumed(Activity activity) { Log.e("onActivityResumed---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityPaused(Activity activity) { Log.e("onActivityPaused---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityStopped(Activity activity) { Log.e("onActivityStopped---","is running"+"--"+activity.getClass().getCanonicalName() );}
@Override
public (Activity activity,Bundle bundle) { Log.e("onActivitySaveInstanceState---","is running"+"--"+activity.getPackageName());}
@Override
public voidonActivityDestroyed(Activity activity) { Log.e("onActivityDestroyed---","is running"+"--"+activity.getPackageName());}
大家可以看到這些方法名採用的都是英語中的過去式命名,其意大家看方法名也應該懂了,就是activity執行過得生命周期都會在這里調用,想要這些方法執行要調用
(this);
這個方法,記得一定要調用啊,還有請記住這些回調是針對所有的Activity哦,所以我們就可以使用這樣的方式去對activity進行關閉或者其他操作了。下面有一種存放activity的方式,喜歡的可以使用:
private staticWeakReferencecurAct;
private staticWeakHashMapacList=newWeakHashMap<>();
/***設置當前activity**
@paramact*/
public static voidsetCurActivity(Activity act) {curAct=newWeakReference<>(act);acList.put(act, null);}
/***獲取想要的activity*@return*/
public staticActivitygetCurActivity() {if(acList==null||acList.isEmpty())return null;WeakReference wr =curAct;if(wr !=null) {returnwr.get();}return null;}
/***清理activity*@paramact*/
public static voidclearCurActivity(Activity act) { Object remove =acList.remove(act);if(remove !=null&& TextUtils .equals(remove.getClass().getSimpleName(),curAct.get().getClass().getSimpleName())) {//TODO You want to do something.}}/***銷毀所有的activity*/public static voiddestroyAllActivity() {if(null!=acList&& !acList.isEmpty()) { Object[] keys =acList.keySet().toArray();for(Object obj : keys) { Activity act = (Activity)obj;if(act !=null) { act.finish();} } }}
/***關閉某個activity*@paramactivity*/
public static voidcloseActivity(String activity) {if(null!=acList&& !acList.isEmpty()) { Object[] keys =acList.keySet().toArray();for(Object obj : keys) {if(obj !=null&& activity !=null&& TextUtils.equals(obj.getClass().getSimpleName(),activity)) { Activity act = (Activity)obj;act.finish();} } }}
下面是CSDN地址: 原文鏈接
⑤ 簡述 activity 和 service 的生命周期有什麼不同
組件的生命周期
應
用程序組件都有一個生命周期,從響應Intent的Android實例開始到這個實例被銷毀。在這期間,他們或許有效或許無效,有效時或許對用戶可見或許
不可見。下面我們就來討論四個基本組件的生命周期,包括在生命周期內的各種狀態,以及狀態之間的轉換。這幾種狀態可能的結果是:進程讓他們停止,
然後實例被銷毀。
一、activity生命周期
一個activity有三個基本的狀態:
@ 當activity在前台運行時(在activity當前任務的堆棧頂),為活動或者運行狀態。這時activity會響應用戶的操作。
@
當activity失去焦點但是對用戶仍然可見時為paused暫停狀態。此時,別的activity在他的上面,透明或者備有被全部覆蓋。所以其中一些
暫停的activity也可以被顯示。一個暫停的activity是處於活動狀態的(他維護著所有的狀態保存著信息,並且依然附著在窗口管理器)。
@ 如果一個activity完全被另一個activity所掩蓋那他會處於stop狀態。但仍然保存著原來的狀態和信息。然而,如果別的地方需要更多的內存而且這個activity仍一直處於隱藏狀態,那麼系統有可能會殺死他的進程。
如果一個activity是暫停或者停止狀態,系統可以清理他們佔用的內存,或者調用finish()方法,或者直接結束他的進程。當他再次顯示給用戶時,會完全的重新運行並且載入以前所存儲的信息。
activity狀態之間的轉換,是通過以前的受保護方法完成的:
void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()
這些都是鉤子函數,你可以重寫他們,當狀態改變時做一些適當的處理。所有的activity在首次運行時必須實現onCreate()方法來初始化安裝。activity可以實現onPause()來提交數據改變,然後准備停止與用戶的交互。
調用超類
每一個實現的activity生命周期方法都會先調用一下父類的方法,例如:
view plain to clipboardprint?
protected void onPause() {
super.onPause();
. . .
}
protected void onPause() {
super.onPause();
. . .
}
通過這兩者比較?,這7個方法定義了一個activity的整個生命周期的方法。你可以實現並且監測這三個嵌套循環:
@ 整個生命周期
調
用onCreate()方法和onDestroy()之間稱為一個activity的完整的生命周期。activity會在onCreate()里執行所
有的初始化安裝,在onDestroy()方法里釋放所有的剩餘資源。例如:一個從網路下載程序的線程,就需要在onCreate()方法里創建,在
onDestroy()方法里銷毀。
@ 可見生命周期
可
見生命周期是從onStart()方法到onStop()方法的時間。這段時間,用戶會在屏幕上看到這個activity。盡管他可能不是在最頂層顯示,
也沒有和用戶進行任何交互。這兩個方法之間,你可以保持需要向用戶顯示的資源。例如:你可以在onStart()方法時注冊一個
BroadcastReceiver檢測某些變化來改變你的界面,當用戶看不到這個activity的界面時可以在onStop()里注銷這個
BroadcastReceiver。這兩個方法可以被調用很多次,在可見和對用戶隱藏時,作為候補的activity待命。
@ 前台顯示周期
一
個activity從onResume()方法指導一個onPause()方法稱為前台顯示周期。此時他在其他的activity之上顯示並且與用戶交
互。一個activity可以頻繁的在這兩個方法之間過度,例如:當設備休眠或者另一個新的activity啟動時,它會進入onPause()狀態,當
一個activity運行結束或者新的接收到Intent請求時,activity的onResume()會被調用。因此,這兩個方法里的代碼量會很
少。
下圖說明了上面說的幾個循環,裡面的箭頭說明了兩個狀態之間是否可以相互轉換。有色的橢圓是activity主要的幾個狀態。正方形和長方形代表activity在狀態之間轉變時我們可以實現的一些回調方法。
注
意killable這列,它指明了進程在調用方法返回後是否可以被系統殺死,而不執行其他的代碼。onPause(), onStop(), and
onDestroy()這三個方法可以,因為onPause方法首先被執行,他是唯一一個一定會被調用的方法當進程被殺死時,但是onStop()和
onDestroy()方法不會。因此,你可以在onPause()方法里保存一些連續的數據,例如編輯。
killable
這列被標記成no的方法,保護activity防止他們被調用時,被進程殺死。例如:一個activity是處於可被殺死的狀態,當activity從
onPause()方法跳轉到onResume()方法時,在OnPause方法回調之前是不會被殺死的。
正如後面的章節:進程和生命周期,一個沒有定義為「killable」的activity仍然可以被系統結束,但這時會發生在特殊情況下,比如沒有其他資源時。
保存activity的狀態
當系統(而不是用戶)關閉一個activity來節省內存時,用戶希望再次啟動activity時會回到當時的狀態。
為
了在activity被殺死之前捕獲他的狀態,你可以實現
onSaveInstanceState()方法,Android會在一個activity將要被關閉時調用這個方法,也就是在onPause()方法之
前。他回傳遞給方法一個Bandle對象,你可以用key-value的方式保存你的數據。當activity再次運行時。這個Bandle對象會傳遞給
onCreate()方法、onStart()方法、onRestoreInstanceState()方法。這幾個方法都能重建當時的activity
狀態。
不
像onPause()和剛才討論的其他幾個方法,onSaveInstanceState()和onRestoreInstanceState()方法不
是生命周期方法。不是不是總被調用。例如:Android在activity將要被系統銷毀之前調用onSaveInstanceState()方法,當
activity實例被用戶的操作銷毀時(例如按下Back鍵),是不會調用這個方法的。這種情況下沒有理由保存他的狀態。
Coordinating activities
當一個activity啟動了另一個activity,他們都經歷了生命周期的轉換。一個暫停了或者結束了,其他的activity啟動。一種情況你可能需要調節這些activity:
生命周期方法的回調順序都是定義好的,尤其當兩個activity在同一進程下:
1.當前運行的activity的onPause()方法被調用。
2.然後將要運行的activity的onCreate()、onStart()、onResume()方法被依次調用。
3.然後,如果將要運行的activity不太可見,那麼onstop()方法會被調用。
二、Service的生命周期:
有了 Service 類我們如何啟動他呢,有兩種方法:
• Context.startService()
• Context.bindService()
1. 在同一個應用任何地方調用 startService() 方法就能啟動 Service 了,然後系統會回調 Service 類的
onCreate() 以及 onStart() 方法。這樣啟動的 Service 會一直運行在後台,直到
Context.stopService() 或者 selfStop() 方法被調用。另外如果一個 Service 已經被啟動,其他代碼再試圖調用
startService() 方法,是不會執行 onCreate() 的,但會重新執行一次 onStart() 。
2. 另外一種 bindService() 方法的意思是,把這個 Service 和調用 Service
的客戶類綁起來,如果調用這個客戶類被銷毀,Service 也會被銷毀。用這個方法的一個好處是,bindService() 方法執行後
Service 會回調上邊提到的 onBind() 方發,你可以從這里返回一個實現了 IBind
介面的類,在客戶端操作這個類就能和這個服務通信了,比如得到 Service 運行的狀態或其他操作。如果 Service
還沒有運行,使用這個方法啟動 Service 就會 onCreate() 方法而不會調用 onStart()。
總結:
1. startService()的目的是回調onStart()方法,onCreate()
方法是在Service不存在的時候調用的,如果Service存在(例如之前調用了bindService,那麼Service的onCreate方法
已經調用了)那麼startService()將跳過onCreate() 方法。
2.
bindService()目的是回調onBind()方法,它的作用是在Service和調用者之間建立一個橋梁,並不負責更多的工作(例如一個
Service需要連接伺服器的操作),一般使用bindService來綁定到一個現有的Service(即通過StartService啟動的服
務)。
由於Service 的onStart()方法只有在startService()啟動Service的情況下才調用,故使用onStart()的時候要注意這點。
與 Service 通信並且讓它持續運行
如果我們想保持和 Service 的通信,又不想讓 Service 隨著 Activity 退出而退出呢?你可以先
startService() 然後再 bindService() 。當你不需要綁定的時候就執行 unbindService()
方法,執行這個方法只會觸發 Service 的 onUnbind() 而不會把這個 Service 銷毀。這樣就可以既保持和 Service
的通信,也不會隨著 Activity 銷毀而銷毀了。
提高 Service 優先順序
Android
系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,系統內部會自動分配,控製程序的內存使用。當系統覺得當前的資源非常有限的時候,為了保
證一些優先順序高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。如果你的
Service 碰上了這種情況,多半會先被殺掉。但如果你增加 Service 的優先順序就能讓他多留一會,我們可以用
setForeground(true) 來設置 Service 的優先順序。
為什麼是 foreground ? 默認啟動的 Service 是被標記為 background,當前運行的 Activity 一般被標記為
foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的 Activity
類似優先順序得到了一定的提高。當讓這並不能保證你得 Service 永遠不被殺掉,只是提高了他的優先順序。
三、android的service的生命周期與activity類似,但是有一些不同:
onCreate和onStart是不同的
通
過從客戶端調用Context.startService(Intent)方法我們可以啟動一個服務。如果這個服務還沒有運行,Android將啟動它並
且在onCreate方法之後調用它的onStart方法。如果這個服務已經在運行,那麼它的onStart方法將被新的Intent再次調用。所以對於
單個運行的Service它的onStart方法被反復調用是完全可能的並且是很正常的。
onResume、onPause以及onStop是不需要的
回調一個服務通常是沒有用戶界面的,所以我們也就不需要onPause、onResume或者onStop方法了。無論何時一個運行中的Service它總是在後台運行。
onBind
如
果一個客戶端需要持久的連接到一個服務,那麼他可以調用Context.bindService方法。如果這個服務沒有運行方法將通過調用
onCreate方法去創建這個服務但並不調用onStart方法來啟動它。相反,onBind方法將被客戶端的Intent調用,並且它返回一個
IBind對象以便客戶端稍後可以調用這個服務。同一服務被客戶端同時啟動和綁定是很正常的。
onDestroy
與
Activity一樣,當一個服務被結束是onDestroy方法將會被調用。當沒有客戶端啟動或綁定到一個服務時Android將終結這個服務。與很多
Activity時的情況一樣,當內存很低的時候Android也可能會終結一個服務。如果這種情況發生,Android也可能在內存夠用的時候嘗試啟動
被終止的服務,所以你的服務必須為重啟持久保存信息,並且最好在onStart方法內來做。
--------------------------------------------------------------------------------------------------
activity的生命周期
oncreate(Bundle
savedInstanceState):在activity第一次被創建的時候調用。這里是你做所有初始化設置的地方──創建視圖、綁定數據至列表等。
如果曾經有狀態記錄,則調用此方法時會傳入一個包含著此activity以前狀態的包對象做為參數
onRestart():在activity停止後,在再次啟動之前被調用。
onStart():當activity正要變得為用戶所見時被調用。
onResume():在activity開始與用戶進行交互之前被調用。此時activity位於堆棧頂部,並接受用戶輸入。
onPause():當系統將要啟動另一個activity時調用。此方法主要用來將未保存的變化進行持久化,停止類似動畫這樣耗費CPU的動作等。這一切動作應該在短時間內完成,因為下一個activity必須等到此方法返回後才會繼續。
onStop():當activity不再為用戶可見時調用此方法。這可能發生在它被銷毀或者另一個activity(可能是現存的或者是新的)回到運行狀態並覆蓋了它。
onDestroy():在activity銷毀前調用。這是activity接收的最後一個調用。這可能發生在activity結束(調用了它的 finish() 方法)或者因為系統需要空間所以臨時的銷毀了此acitivity的實例時。你可以用isFinishing() 方法來區分這兩種情況。
協調activity
當一個activity啟動了另外一個的時候,它們都會經歷生命周期變化。一個會暫停乃至停止,而另一個則啟動。這種情況下,你可能需要協調好這些activity:
生命周期回調順序是已經定義好的,尤其是在兩個activity在同一個進程內的情況下:
1. 調用當前activity的 onPause() 方法。
2. 接著,順序調用新啟動activity的onCreate()、 onStart()和onResume()方法。
3. 然後,如果啟動的activity不再於屏幕上可見,則調用它的onStop()方法。
總之:1、Activity 從創建到進入運行態所觸發的事件 onCreate()-->onStart-->onResume()
2、從運行態到停止態所觸發的事件 onPause()--->onStop()
3、從停止態到運行態所觸發事件 onRestart()-->onStart()--->onResume()
4、從運行態到暫停態所觸發事件 onPause()
5、從暫停態到運行態所觸發事件 onResume()
橫豎屏幕切換生命周期
1.不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次.
2.設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次.
3.設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法.
service的生命周期
啟動Service時可調用startService和bindService()方法來啟動,用這兩種方法啟動的Service的生命周期是不同的。
Service的生命周期只有onCreate,onStart和onDestroy,沒有onResume,onPause和onStop,大多
數時間Service都是運行的,但在嚴重的內存壓力下它也可能被系統kill,如果被kill,系統會在稍後嘗試重新啟動這個Service
Service的調用
途徑一:
調用Context.startService()啟動Service,調用Context.stopService()或Service.stopSelf()或Service.stopSelfResult()關閉Service的調用。
Service生命周期分析:
註:onCreate,onStart(),onDestroy()是Service生命周期相關的方法
當Context.startService()啟動Service時,如果Service本身沒有運行,則調用
onCreate()->onStart()完成Service啟動。如果Service已經運行,則只調用
onStart(),onStart()可以多次被調用。
Service關閉必須調用Context.stopService()或Service.stopSelf()或
Service.stopSelfResult()方法,關閉之前調用onDestroy()方法,否則如果Context直接退出而沒有停止
Service的話,Service會一直在後台運行。該Service的調用者只能再啟動後通過stopService關閉Service。
生命周期順序為:onCreate()->onStart()->onDestroy()
途徑二:
調用Context.bindService()進行初始化綁定,使用Context.unbindService()取消綁定,由於Service和Context是綁定關系,當Context退出或被銷毀時,Service也會相應退出。
Service生命周期分析:
調用Context.bindService()時,Service會經歷onCreate->onBind(),onBind將返回給客戶端一個
IBind實例,IBind允許客戶端回調服務的方法。此時Context和Service是綁定在一起的,Context退出了,Service調用
onUnbind()->onDestroy()相應退出。
生命周期順序為:onCreate->onBind(只一次,不可多次綁定)->onUnbind->onDestroy()
BroadcastReceiver只能通過startService啟動Service,因為廣播本身生命周期很短,bind的話沒有意義
果不是通過bindService創建的服務(但仍然通過bindService得到了服務對象),就可能unbindService後還在運行,否則應該是結束掉了。
⑥ android中怎樣讓main線程和子線程同步一個變數
1、檢查Thread,確定沒有在Background thread中直接調用adapter,如果有,請移除相關代碼到Handler中處理;
2、盡量將數據放在adapter類中管理,不需要的時候清除信息(勤寫clear()),及時用notifyDataSetChanged()刷新;
3、在Activity或者Fragment合適的位置(onPause/onStop)要及時檢查thread,有adapter數據處理相關的應馬上停止;
4、這個錯誤經常出現在Activity休眠起來之後,主要還是使用adapter不太小心造成的。如果實在找不到原因,在onPause()函數中停止所有的background thread,並且在onResume()函數最前面清空adapter中的數據,並且adapter.notifyDataSetChanged()。然後重新更新載入數據,這樣一般可以解決問題。
⑦ Android之Activity全面解析,有些知識點容易忘記
Activity作為安卓四大組件之一,是最重要也是用得最多的組件,涉及的知識點非常多,有些知識點平時開發很少用到,但在某些場景下需要特別注意,本文詳細整理了Activity涉及的知識點,供開發參考。
針對Activity可以提出很多問題,如:
Activity 的生命周期?
Activity 之間的通信方式?
Activity 各種情況下的生命周期?
橫豎屏切換時 Activity 的生命周期?
前台切換到後台,然後再回到前台時 Activity 的生命周期?
彈出 Dialog 的時候按 Home 鍵時 Activity 的生命周期?
兩個Activity之間跳轉時的生命周期?
下拉狀態欄時 Activity 的生命周期?
Activity 與 Fragment 之間生命周期比較?
Activity 的四種 LaunchMode(啟動模式)的區別?
Activity 狀態保存與恢復?
Activity的轉場動畫有哪些實現方式?
Activity的生命周期中怎麼獲取控制項寬高?
onNewIntent的執行時機?
如何連續退出多個Activity?
如何把Acitivty設置成Dialog樣式 ,android:theme="@android:style/Theme.Dialog"
關於橫豎屏切換的生命周期,對應不同的手機,由於廠商定製的原因,會有不同的效果,如設置了configChanges="orientation」在有些手機會執行各個生命周期,但有些手機卻不會執行。
網上常見的結論如下:
但實際的測試如下:
可以看出,不同廠商的手機切屏生命周期會有差異。
從API 13以上,當設備在橫豎切屏時,「屏幕尺寸」也會發生變化,因此為了杜絕切屏導致頁面銷毀重建,需要加上screenSize,使用設置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .
Activity的四種狀態如下:
在activity處於paused或者stoped狀態下,如果系統內存緊張,可能會被銷毀,當重回該activity時會重建,正常返回和被回收後返回的生命周期如下:
如果是回收後返回,onCreate的參數savedInstanceState不為空。
有哪些場景會觸發onNewIntent回調呢?跟啟動模式有關,首先該Activity實例已經存在,再次啟動才可能觸發。一種情況是啟動模式是singleTask或者singleInstance,無論該activity在棧中哪個位置,都會觸發onNewIntent回調,並且把上面其他acitivity移除,另一種情況是啟動模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP啟動,並且該activity實例在棧頂,會觸發onNewIntent,如果不在棧頂是重新創建的,不會觸發。
在實際業務開發中,往往碰到需要連續退出多個activity實例,下面整理了幾種常見方法:
● 發送特定廣播
1、在需要處理連續退出的activity注冊該特定廣播;
2、發起退出的activity發送該特定廣播;
3、接收到該廣播的activity 調用finish結束頁面。
● 遞歸退出
1、用startActivityForResult啟動新的activity;
2、前一個頁面finish時,觸發onActvityResult回調,再根據requestCode和resultCode處理是否finish,達到遞歸退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通過intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)啟動新activity,如果棧中已經有該實例,則會把該activity之上的所有activity關閉,達到singleTop啟動模式的效果。
● 自定義activity棧
1、自定義activity列表,新打開activity則加入棧中,關閉則移除棧;
2、需要退出多個activity時,則循環從棧中移除activity實例,並調用finish。
在討論Activity啟動模式經常提到任務棧,那到底什麼是任務棧?
任務是一個Activity的集合,它使用棧的方式來管理其中的Activity,這個棧又被稱為返回棧(back stack),棧中Activity的順序就是按照它們被打開的順序依次存放的。返回棧是一個典型的後進先出(last in, first out)的數據結構。下圖通過時間線的方式非常清晰地向我們展示了多個Activity在返回棧當中的狀態變化:
taskAffinity 任務相關性,可以用於指定一個Activity更加願意依附於哪一個任務,在默認情況下,同一個應用程序中的所有Activity都具有相同的affinity, 名字為應用的包名。當然了,我們可以為每個 Activity 都單獨指定 taskAffinity 屬性(不與包名相同)。taskAffinity 屬性主要和 singleTask 啟動模式和 allowTaskReparenting 屬性配對使用,在其他情況下沒有意義。
taskAffinity 有下面兩種應用場景:
分為顯示啟動和隱式啟動。
(1)顯示啟動
直接指定待調整的Activity類名。
(2)隱式啟動
Intent 能夠匹配目標組件的 IntentFilter 中所設置的過濾信息,如果不匹配將無法啟動目標 Activity。IntentFilter 的過濾信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一個 Activity 中可以有多個 intent-filter
● 一個 intent-filter 同時可以有多個 action、category、data
● 一個 Intent 只要能匹配任何一組 intent-filter 即可啟動對應 Activity
● 新建的 Activity 必須加上以下這句,代表能夠接收隱式調用
<category android:name="android.intent.category.DEFAULT" />
只要匹配一個action即可跳轉,注意的是action要區分大小寫。
規則:如果intent中有category,則所有的都能匹配到intent-filter中的category,intent中的category數量可用少於intent-filter中的。另外,單獨設置category是無法匹配activity的,因為category屬性是一個執行Action的附加信息。
intent不添加category會匹配默認的,即 「android:intent.category.DEFAULT」
如果上面例子,如果去掉intent.setAction("action_name"),則會拋出異常:
規則:類似action,但data有復雜的結構,只要匹配一個data並且與data中所有屬性都一致就能匹配到Activity,只要有1個屬性不匹配,都無法找到activity。
data的結構:
data 主要是由 URI 和 mimeType 組成的。
URI 可配置很多信息,的結構如下:
與url類似,例如:
mineType:指資源類型包括文本、圖片、音視頻等等,例如:text/plain、 image/jpeg、video/* 等
下面看下data匹配的例子:
只匹配scheme
只匹配scheme也是能匹配到activity的。
匹配scheme、host、port
將上面的data改為
匹配mineType
如果有mineType,則不能僅設置setData或setMineType了,因為setData會把mineType置為null,而setMineType會把data置為null,導致永遠無法匹配到activity,要使用setDataAndType。
使用scheme的默認值contentfile
注意該方法需要在startAtivity方法或者是finish方法調用之後立即執行,不能延遲,但可以在子線程執行。
而在windowAnimationStyle中存在四種動畫:
activityOpenEnterAnimation // 打開新的Activity並進入新的Activity展示的動畫
activityOpenExitAnimation // 打開新的Activity並銷毀之前的Activity展示的動畫
activityCloseEnterAnimation //關閉當前Activity進入上一個Activity展示的動畫
activityCloseExitAnimation // 關閉當前Activity時展示的動畫
overridePendingTransition的方式比較生硬,方法也比較老舊了,不適用於MD風格,google提供了新的轉場動畫ActivityOptions,並提供了兼容包ActivityOptionsCompat。
我們知道在onCreate和onResume裡面直接獲取到控制項寬高為0,那有什麼辦法獲取到控制項的實際寬高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三種方式獲取。
當用戶點擊桌面圖標啟動APP時,背後的流程如下:
我們看到的手機桌面是Launch程序的界面,點擊應用圖標會觸發點擊事件,調用startActivity(intent),然後通過Binder IPC機制,與ActivityManagerService(AMS)通訊,AMS執行一系列操作,最終啟動目前應用,大概流程如下:
通過PackageManager的resolveIntent()收集跳轉intent對象的指向信息,然後通過grantUriPermissionLocked()方法來驗證用戶是否有足夠的許可權去調用該intent對象指向的Activity。如果有許可權,則在新的task中啟動目標activity,如果發現沒有進程,則先創建進程。
如果進程不存在,AMS會調用startProcessLocked創建新的進程,在該方法中,會通過socket的通訊方式通知zygote進程孵化新的進程並返回pid,在新的進程中會初始化ActivityThread,並依次調用Looper.prepareLoop()和Looper.loop()來開啟消息循環。
創建好進程後下一步要將Application和進程綁定起來,AMS會調用上一節創建的ActivityThread對象的bindAppliction方法完成綁定工作,該方法會發送一條BIND_APPLICATION的消息,最終會調用handleBindApplication方法處理消息,並調用makeApplication方法處理消息,載入APP的classes到內存中。
通過前面的步驟,系統已經擁有了該Application的進程,後續的啟動則是從已存在其他進程中啟動Acitivity,即調用realStartAcitvityLocked,該方法會調用Application的主線程對象ActivityThread的sheleLaunchActivity方法,在方法中會發送LAUNCH_ACTIVITY到消息隊列,最終通過handleLaunchActivity處理消息,完成Acitivty的啟動。
Activity
Activity 的 36 大難點,你會幾個?「建議收藏」
[譯]Android Application啟動流程分析
⑧ android中 進入到下一個activity時 不銷毀前一個怎麼做
進入休眠狀態。
Activity 有幾個狀態。。。。跳轉時,設置成休眠即可。
具體你網路下~~
我也忘記了 很長時間沒有高了
⑨ Android基礎之Activity生命周期
Activity是Android最常用的四大組件之一,Activity是Android應用中與用戶交互的界面,通常一個activity就是一個屏幕,Activity一共有四種狀態,Active/Running(當Activity可見且可以與用戶交互);Paused(當Activity可見但是不可交互);Stoped(當Activity被完全覆蓋不可見);Killed(當Activity被系統從內存中刪除).其生命周期如下圖:
相關方法及作用:
1 onCreate:當Activity創建時僅且調用一次,該方法主要適用於初始化頁面。
2 onStart:當Activity調用onCreate方法之後,然後調用此方法開啟Activity,Activty此時可見但不可交互。
3 onResume:此時Activity在前台可見且可與用戶交互。適合做UI更新操作。
4 onPouse:當Activity被另外一個Activity覆蓋時調用該方法。
5 onStop:當Activity在前台不可見或者Activity在銷毀前調用此方法,此方法適合做一些資源的回收操作。
6 onDestroy:當activity被銷毀時調用此方法。
問題:
1)onCreate 和 onStart 方法的區別
a.執行次數不同,onCreate只執行一次,而onStart可以執行多次。
b.在activity的狀態不同,onCreate被調用時Activity的狀態還是未可見,而調用onStart時已可見。
2) onStart 和 onStop的區別
在執行onStart或者onStop時,Activity都是不可交互的,執行onStart時Activity在前台不可見,在後台可見。而執行onStop時Activity前後台都不可見。
3)onResume 和 onPouse的區別
在執行onResume時,Activity在前台是可見的且可以與用戶交互的。而執行onPouse時Activity在前台有可能可見,Activity沒有獲取到焦點,此時不可與用戶交互。
⑩ 如何管理Android中Activity的生命周期
一、基礎
1.1自己創建的activity必須要繼承類Activity(或其子類)。在activity里,為了實現activity各種狀態的切換,你必須實現指定的回調方法。以下是最為重要的兩個回調方法
onCreate():
這是必須實現的回調方法,啟動一個 activity時會首先調用此方法。因此,在onCreate()的方法體里,你應該初始化該activity必要的控制項。值得注意的是,在這里你必須調用setContentView(View view)方法去呈現用戶的界面。
onPause():
在用戶將要離開activity時調用此方法(指的是此時activity處於半透明狀態且沒有獲取用戶的焦點)。通常在這樣的狀態下,你需要處理用戶數據的提交、動畫處理等操作。
1.2銷毀activity
你可以調用finish()方法去銷毀一個activity。同樣得,你可以調用finishActivity()方法去銷毀一個你剛剛啟動的activity。
tips:
在多數情況下,你是不需要顯式地調用finish…()方法去銷毀一個activity。在將要討論到的activity生命周期里,你可以知道,Android系統會為你管理activity的生命周期,所以你並不需要顯式銷毀activity(即調用finish類方法)。顯式地調用finish類方法,會對用戶的體驗產生不利的影響,除非你確實是不希望用戶返回到此activity(界面),才去顯式調用finish類方法。
二、認識activity的生命周期
2、1
Activity的生命周期對它的任務、backstack和與此有關聯的activity有著直接的影響。因此想開發出一個健壯的有彈性的Android程序,你需要學會如何去管理activity的生命周期(即調用各種回調方法)。
activity的生命周期主要包含一些三種狀態:
(1)運行態(Resumedstate)
此時Activity程序顯示在屏幕前台,並且具有焦點,可以與用戶的操作進行交互,如向用戶提供信息、捕獲用戶單擊按鈕的事件並做處理。
(2)暫停態(PausedState)
此時Activity程序失去了焦點,並被其他處於運行態的otherActivity取代在屏幕顯示,但otherActivity程序並沒有覆蓋整個屏幕或者具有半透明的效果—此狀態即為暫停態。處於暫停態的Activity仍然對用戶可見,並且是完全存活的(此時Activity對象存留在內存里,保留著所有狀態與成員信息並保持與窗口管理器的連接)。如果系統處於內存不足的情況下,會殺死這個Activity。
(3)停止態(StoppedState)
當Activity完全被另一個otherActivity覆蓋時(此時otherActivity顯示在屏幕前台),則處於停止態。處於停滯態的Activity依然是存活的(此時Activity對象依然存留在內存里,保留著所有的狀態和與成員信息,但沒有與窗口管理器保持連接),而且它對用戶是不可見的,如果其他地方需要內存,系統會銷毀這個Activity。
處於暫停態(PausedState)或者停止態(Stopped
State)的Activity,系統可以通過調用finish()方法或者直接終止它的進程來銷毀此Activity(從內存中清楚此Activity對象)。被finish()或者銷毀的Activity再重新打開時,是需要再次初始化此Activity的。
2、2
當一個Activity從一種狀態轉到另一種狀態時,會通過調用回調方法來通知這種變化。這些回調方法都是可以重寫的,你可以根據程序的的需要來選擇重寫對應的回調方法。以下列出了Activity生命周期里的基本回調方法:
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now
"resumed").
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is
about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now
"stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
筆記:在方法體里,必須先調用父類對應的實現方法super.Xxx(),再執行其他的操作(如上面代碼所示)。為了習慣,下面也提供一些代碼來測試一些這些方法的使用,在博客的最後面。
總的來說,這些回調方法定義了Activity整個生命周期。在生命周期里通過重寫這些回調方法,,你可以監控以下下三個嵌套的方法循環。
完整存活的時間:
Activity的完整存活的時間是自第一次調用onCreate()開始,直至調用onDestroy()為止。Activity在onCreate()中設置所有「全局」狀態以完成初始化,而在onDestroy()中釋放所有系統資源。例如,如果Activity有一個線程在後台運行從網路下載數據,它會在onCreate()創建線程,而在 onDestroy()銷毀線程。
可見狀態的時間:
Activity的可見狀態是自onStart()調用開始直到相應的onStop()調用結束。在此期間,用戶可以在屏幕上看到Activity,盡管它也許並不是位於前台或者也不與用戶進行交互。在這兩個方法之間,我們可以保留用來向用戶顯示這個Activity所需的資源。例如,當用戶不再看見我們顯示的內容時,我們可以在onStart()中注冊一個BroadcastReceiver來監控會影響UI的變化,而在onStop()中來注消。onStart() 和 onStop() 方法可以隨著應用程序是否為用戶可見而被多次調用。
顯示在前台的時間:
Activity的前台顯示是自onResume()調用起,至相應的onPause()調用為止。在此期間,Activity位於前台最上面並與用戶進行交互。Activity會經常在暫停和恢復之間進行狀態轉換——例如當設備轉入休眠狀態或者有新的Activity啟動時,將調用onPause() 方法。當Activity獲得結果或者接收到新的Intent時會調用onResume() 方法。