1匙赞、什么是Activity?
四大組件之一,一般的,一個(gè)用戶交互界面對應(yīng)一個(gè) activity
?setContentView() ,// 要顯示的布局
?button.setOnclickLinstener{}, activity 是 Context 的子類,同時(shí)實(shí)現(xiàn)了 ?window.callback 和keyevent.callback, 可以處理與窗體用戶交互的事件.
?我開發(fā)常用的的有
FragmentActivitiyListActivity ,PreferenceActivity ,TabAcitivty 等…
2佛掖、請描述一下 Activity 生命周期
?Activity 從創(chuàng)建到銷毀有多種狀態(tài),從一種狀態(tài)到另一種狀態(tài)時(shí)會(huì)激發(fā)相應(yīng)的回調(diào)方法涌庭,這些回調(diào)方法包括:onCreate onStart onResume onPause onStop onDestroy
?其實(shí)這些方法都是兩兩對應(yīng)的芥被,onCreate 創(chuàng)建與 onDestroy 銷毀;
onStart 可見與 onStop 不可見坐榆;onResume 可編輯(即焦點(diǎn))與 onPause拴魄;
如果界面有共同的特點(diǎn)或者功能的時(shí)候,還會(huì)自己定義一個(gè) BaseActivity.
進(jìn)度對話框的顯示與銷毀
onCreate:與onDestroy配對,表示Activity正在被創(chuàng)建席镀,這是生命周期的第一個(gè)方法匹中。在這個(gè)方法中可以做一些初始化的工作(加載布局資源、初始化Activity所需要的數(shù)據(jù)等)豪诲,耗時(shí)的工作在異步線程上完成顶捷。
onRestart:表示Activity正在重新啟動(dòng)。一般情況下屎篱,在當(dāng)前Activity從不可見重新變?yōu)榭梢姷臓顟B(tài)時(shí)onRestart就會(huì)被調(diào)用服赎。這種情形一般是由于用戶的行為所導(dǎo)致的,比如用戶按下Home鍵切換到桌面或者打開了一個(gè)新的Activity(這時(shí)當(dāng)前Activity會(huì)暫停交播,也就是onPause和onStop被執(zhí)行)重虑,接著用戶有回到了這個(gè)Activity,就會(huì)出現(xiàn)這種情況堪侯。
onStart:與onStop配對嚎尤,表示Activity正在被啟動(dòng),并且即將開始伍宦。但是這個(gè)時(shí)候要注意它與onResume的區(qū)別芽死。兩者都表示Activity可見乏梁,但是onStart時(shí)Activity還正在加載其他內(nèi)容碘菜,正在向我們展示灌灾,用戶還無法看到,即無法交互羡藐。
onResume:與onPause配對揖曾,表示Activity已經(jīng)創(chuàng)建完成落萎,并且可以開始活動(dòng)了,這個(gè)時(shí)候用戶已經(jīng)可以看到界面了炭剪,并且即將與用戶交互(完成該周期之后便可以響應(yīng)用戶的交互事件了)练链。
onPause:與onResume配對,表示Activity正在暫停奴拦,正常情況下媒鼓,onStop接著就會(huì)被調(diào)用。在特殊情況下错妖,如果這個(gè)時(shí)候用戶快速地再回到當(dāng)前的Activity,那么onResume會(huì)被調(diào)用(極端情況)绿鸣。一般來說,在這個(gè)生命周期狀態(tài)下暂氯,可以做一些存儲數(shù)據(jù)潮模、停止動(dòng)畫的工作,但是不能太耗時(shí)痴施,如果是由于啟動(dòng)新的Activity而喚醒的該狀態(tài)擎厢,那會(huì)影響到新Activity的顯示,原因是onPause必須執(zhí)行完晾剖,新的Activity的onResume才會(huì)執(zhí)行锉矢。
onStop:與onStart配對,表示Activity即將停止齿尽,可以做一些稍微重量級的回收工作沽损,同樣也不能太耗時(shí)(可以比onPause稍微好一點(diǎn))。
onDestroy:與onCreate配對循头,表示Activity即將被銷毀绵估,這是Activity生命周期的最后一個(gè)回調(diào),我們可以做一些回收工作和最終的資源釋放(如Service卡骂、BroadReceiver国裳、Map等)。
3 全跨、 常 見 的 Activity 類 型 有 FragmentActivitiy 缝左,ListActivity,TabAcitivty 等。請描述一下 Activity 生命周期
Activity 從創(chuàng)建到銷毀有多種狀態(tài)渺杉,從一種狀態(tài)到另一種狀態(tài)時(shí)會(huì)激發(fā)相應(yīng)的回
調(diào)方法蛇数,這些回調(diào)方法包括:onCreate onStart onResume onPause onStop
onDestroy
其實(shí)這些方法都是兩兩對應(yīng)的,onCreate 創(chuàng)建與 onDestroy 銷毀是越;
onStart 可見與 onStop 不可見耳舅;onResume 可編輯(即焦點(diǎn))與 onPause。
4倚评、如何保存 Activity 的狀態(tài)或者(Activiy 重啟怎么保存數(shù)據(jù)浦徊?)
Activity 的狀態(tài)通常情況下系統(tǒng)會(huì)自動(dòng)保存的,只有當(dāng)我們需要保存額外的
數(shù)據(jù)時(shí)才需要使用到這樣的功能天梧。
一般來說, 調(diào)用onPause()和onStop()方法后的activity 實(shí)例仍然存在于內(nèi)
存中, activity 的所有信息和狀態(tài)數(shù)據(jù)不會(huì)消失, 當(dāng) activity 重新回到前臺之后,
所有的改變都會(huì)得到保留盔性。
但是當(dāng)系統(tǒng)內(nèi)存不足時(shí), 調(diào)用onPause()和onStop()方法后的activity 可能
會(huì)被系統(tǒng)摧毀, 此時(shí)內(nèi)存中就不會(huì)存有該activity 的實(shí)例對象了。如果之后這個(gè)
activity 重新回到前臺, 之前所作的改變就會(huì)消失腿倚。為了避免此種情況的發(fā)生, 我
們可以覆寫 onSaveInstanceState()方法纯出。onSaveInstanceState()方法接受一
個(gè) Bundle 類型的參數(shù), 開發(fā)者可以將狀態(tài)數(shù)據(jù)存儲到這個(gè) Bundle 對象中, 這
樣即使 activity 被系統(tǒng)摧毀, 當(dāng)用戶重新啟動(dòng)這個(gè) activity 而調(diào)用它的
onCreate()方法時(shí), 上述的Bundle 對象會(huì)作為實(shí)參傳遞給 onCreate()方法, 開
發(fā)者可以從 Bundle 對象中取出保存的數(shù)據(jù), 然后利用這些數(shù)據(jù)將 activity 恢復(fù)
到被摧毀之前的狀態(tài)蚯妇。
需要注意的是, onSaveInstanceState()方法并不是一定會(huì)被調(diào)用的, 因?yàn)橛?br> 些場景是不需要保存狀態(tài)數(shù)據(jù)的. 比如用戶按下 BACK 鍵退出 activity 時(shí), 用戶
顯然想要關(guān)閉這個(gè) activity, 此時(shí)是沒有必要保存數(shù)據(jù)以供下次恢復(fù)的, 也就是
onSaveInstanceState()方法不會(huì)被調(diào)用. 如果調(diào)用 onSaveInstanceState()方
法, 調(diào)用將發(fā)生在 onPause()或 onStop()方法之前敷燎。
5、 兩個(gè) Activity 之間跳轉(zhuǎn)時(shí)必然會(huì)執(zhí)行的是哪幾個(gè)方法箩言?
一般情況下比如說有兩個(gè)activity,分別叫A,B,當(dāng)在A 里面激活B 組件的時(shí)候,
A 會(huì)調(diào)用 onPause()方法,然后 B 調(diào)用 onCreate() ,onStart(), onResume()硬贯。這
個(gè)時(shí)候 B 覆蓋了窗體, A 會(huì)調(diào)用 onStop()方法. 如果 B 是個(gè)透明的,或者
是對話框的樣式, 就不會(huì)調(diào)用 A 的 onStop()方法。
6陨收、 橫豎屏切換時(shí) Activity 的生命周期(★★★★)
此時(shí)的生命周期跟清單文件里的配置有關(guān)系饭豹。
1.不設(shè)置 Activity 的 android:configChanges 時(shí),切屏?xí)匦抡{(diào)用各個(gè)生
命周期默認(rèn)首先銷毀當(dāng)前 activity,然后重新加載务漩。
2.設(shè)置 Activity
android:configChanges="orientation|keyboardHidden|screenSize"時(shí)拄衰,切
屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行 onConfigurationChanged 方法饵骨。
通常在游戲開發(fā), 屏幕的朝向都是寫死的翘悉。
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
7、 如何將一個(gè) Activity 設(shè)置成窗口的樣式
只需要給我們的 Activity 配置如下屬性即可居触。
android:theme="@android:style/Theme.Dialog"
8妖混、 如何退出 Activity?如何安全退出已調(diào)用多個(gè)Activity 的 Application轮洋?(★★★★)
1制市、通常情況用戶退出一個(gè) Activity 只需按返回鍵,我們寫代碼想退出 activity
直接調(diào)用 finish()方法就行弊予。
2祥楣、記錄打開的 Activity:
每打開一個(gè) Activity,就記錄下來。在需要退出時(shí)误褪,關(guān)閉每一個(gè) Activity 即可床未。
3、發(fā)送特定廣播:
在需要結(jié)束應(yīng)用時(shí)振坚,發(fā)送一個(gè)特定的廣播薇搁,每個(gè) Activity 收到廣播后,關(guān)閉
即可渡八。
//給某個(gè) activity 注冊接受接受廣播的意圖
//偽代碼
List<Activity> lists ;// 在 application 全局的變量里面
lists = new ArrayList<Activity>();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
lists.remove(this);
registerReceiver(receiver, filter)
//如果過接受到的是 關(guān)閉 activity 的廣播 就調(diào)用 finish()方法 把當(dāng)前的
activity finish()掉
4啃洋、遞歸退出
在打開新的 Activity 時(shí)使用 startActivityForResult,然后自己加標(biāo)志屎鳍,在
onActivityResult 中處理宏娄,遞歸關(guān)閉。
5逮壁、其實(shí) 也可以通過 intent 的 flag 來實(shí)現(xiàn)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一個(gè)新的 activity孵坚。
此時(shí)如果該任務(wù)棧中已經(jīng)有該 Activity,那么系統(tǒng)會(huì)把這個(gè) Activity 上面的所有
Activity 干掉窥淆。其實(shí)相當(dāng)于給 Activity 配置的啟動(dòng)模式為 SingleTop卖宠。
9、 Activity 的 四 種 啟 動(dòng) 模 式 忧饭, singletop 和singletask 區(qū)別是什么扛伍?一般書簽的使用模式是singletop,那為什么不使用 singletask?
singleTop 跟 standard 模式比較類似词裤。唯一的區(qū)別就是刺洒,當(dāng)跳轉(zhuǎn)的對象是
位于棧頂?shù)?activity(應(yīng)該可以理解為用戶眼前所 看到的 activity)時(shí),程序?qū)?br> 不會(huì)生成一個(gè)新的activity 實(shí)例吼砂,而是直接跳到現(xiàn)存于棧頂?shù)哪莻€(gè) activity 實(shí)例逆航。
拿上面的例子來說,當(dāng) Act1 為 singleTop 模式時(shí)渔肩,執(zhí)行跳轉(zhuǎn)后棧里面依舊只有
一個(gè)實(shí)例因俐,如果現(xiàn)在按返回鍵程序?qū)⒅苯油顺觥?br> singleTask 模式和 singleInstance 模式都是只創(chuàng)建一個(gè)實(shí)例的。在這種模
式下赖瞒,無論跳轉(zhuǎn)的對象是不是位于棧頂?shù)?activity女揭,程序都不會(huì)生成一個(gè)新的實(shí)
例(當(dāng)然前提是棧里面已經(jīng)有這個(gè)實(shí)例)。這種模式相當(dāng)有用栏饮,在以后的多activity
開發(fā)中吧兔,常會(huì)因?yàn)樘D(zhuǎn)的關(guān)系導(dǎo)致同個(gè)頁面生成多個(gè)實(shí)例,這個(gè)在用戶體驗(yàn)上始
終有點(diǎn)不好袍嬉,而如果你將對應(yīng)的 activity 聲明為 singleTask 模式境蔼,這種問題將
不復(fù)存在灶平。在主頁的 Activity 很常用
10、Android 中的 Context, Activity箍土,Appliction 有什么區(qū)別逢享?(★★)
相同:Activity 和 Application 都是 Context 的子類。
Context 從字面上理解就是上下文的意思吴藻,在實(shí)際應(yīng)用中它也確實(shí)是起到了管理
上下文環(huán)境中各個(gè)參數(shù)和變量的總用瞒爬,方便我們可以簡單的訪問到各種資源。不同:
維護(hù)的生命周期不同沟堡。 Context 維護(hù)的是當(dāng)前的 Activity 的生命周期侧但,
Application 維護(hù)的是整個(gè)項(xiàng)目的生命周期。
使用 context 的時(shí)候航罗,小心內(nèi)存泄露禀横,防止內(nèi)存泄露,注意一下幾個(gè)方面:
- 不要讓生命周期長的對象引用 activity context粥血,即保證引用 activity 的對象
要與 activity 本身生命周期是一樣的柏锄。
- 對于生命周期長的對象,可以使用 application复亏,context趾娃。
- 避免非靜態(tài)的內(nèi)部類,盡量使用靜態(tài)類蜓耻,避免生命周期問題茫舶,注意內(nèi)部類對
外部對象引用導(dǎo)致的生命周期變化。
11刹淌、兩個(gè)Activity 之間傳遞數(shù)據(jù),除了 intent讥耗,廣播接收者有勾,content provider 還有啥?
1)利用 static 靜態(tài)數(shù)據(jù)古程,public static 成員變量
2)利用外部存儲的傳輸蔼卡,
例如 File 文件存儲
SharedPreferences 首選項(xiàng)
Sqlite 數(shù)據(jù)庫
12、Context 是 什 么 挣磨? 雇逞, 一 個(gè) 應(yīng) 用 有 多 少 個(gè)Context(2020.5.15)(★★)
1、它描述的是一個(gè)應(yīng)用程序環(huán)境的信息茁裙,即上下文塘砸。
2、該類是一個(gè)抽象(abstract class)類晤锥,Android 提供了該抽象類的具體實(shí)
現(xiàn)類(ContextIml)掉蔬。
3廊宪、通過它我們可以獲取應(yīng)用程序的資源和類,也包括一些應(yīng)用級別操作女轿,
例如:啟動(dòng)一個(gè) Activity箭启,發(fā)送廣播,接受 Intent蛉迹,信息傅寡,等。
4北救、一個(gè)應(yīng)用 Context 數(shù)量=Activity 個(gè)數(shù)+service 個(gè)數(shù)+1 個(gè)
13.activity 之間還有 activity 和 service 之間如何傳值赏僧,可以傳圖片嗎? (2020.5.15)(上海)
Activity 之間的傳值:startActivity扭倾,通過 Intent 對象的各種 putExtra 方法來
進(jìn)行傳遞淀零。在第二個(gè) Activity 對象中,可以通過 getIntent() 方法來得到跳轉(zhuǎn)
到這個(gè) Activity 的 Intent 對象膛壹,然后通過 Intent 對象的各種 getXXExtra 方
法來得到我們的傳過來的值驾中。
Activity 和 service 之間傳值:
1、在 activity 中通過 startService(intent)即可模聋,同樣 intent.putStringExtra()肩民,
然 后 再 service 中 的 onStart 函 數(shù) 中 獲 取 該
值,this.getIntent(),intent.getString()
在這里我們需要在 Mainfeist 文件中注冊這個(gè) service
<service Android:enabled="true" android:name=".Service">
</service>
2、service 可以從 public int onStartCommand(Intent intent, int flags, int
startId)中取出從 activity 中傳過來的值链方。intent.getExtra()獲得 bundle 對象持痰,
可從中取值。
3祟蚀、activity 也可以用 bindService(intent, conn,BIND_AUTO_CREATE);傳
值工窍,把要傳的值綁定在 intent 里,在 service 的 public IBinder onBind(Intent
intent) 方法里取得 intent前酿。
4患雏、同時(shí)也可以在 reseiver 里面注冊一個(gè)廣播,在 activity 里sendbroadcast
(intent)傳值罢维。
可以傳遞圖片淹仑,用 Intent 把圖片的地址或者把圖片對象用 Intent 傳過去,用
bitmap 對象肺孵。
14.Activity的啟動(dòng)過程
Activity的啟動(dòng)過程匀借,我們可以從Context的startActivity說起,其實(shí)現(xiàn)是ContextImpl的startActivity平窘,然后內(nèi)部會(huì)通過Instrumentation來嘗試啟動(dòng)Activity吓肋,這是一個(gè)跨進(jìn)程過程,它會(huì)調(diào)用ams的startActivity方法初婆,當(dāng)ams校驗(yàn)完activity的合法性后蓬坡,會(huì)通過ApplicationThread回調(diào)到我們的進(jìn)程猿棉,這也是一次跨進(jìn)程過程,而applicationThread就是一個(gè)binder屑咳,回調(diào)邏輯是在binder線程池中完成的萨赁,所以需要通過Handler H將其切換到ui線程,第一個(gè)消息是LAUNCH_ACTIVITY兆龙,它對應(yīng)handleLaunchActivity杖爽,在這個(gè)方法里完成了Activity的創(chuàng)建和啟動(dòng),接著紫皇,在activity的onResume中慰安,activity的內(nèi)容將開始渲染到window上,然后開始繪制直到我們看見聪铺。