android打開activity-九游会j9娱乐平台
㈠ android —— activity的四種啟動模式
除了activity的生命周期外,activity的啟動模式也是一個難點,有時候為了滿足項目的特殊需求,就必須使用activity的啟動模式。
在默認情況下,當我們多次啟動同一個activity的時候,系統會創建多個實例並把它們放入任務棧中,但是有些場景重復創建多個實例,是沒有必要且浪費資源的,這就需要啟動模式來修改系統的默認行為。
下面,我將以理論 實踐的形式為大家介紹activity的啟動模式。
這是系統的默認啟動模式,採用這種模式的activity無論是否已經存在實例,都會重新創建一個實例,在這種模式下誰啟動了這個activity,那麼這個activity就運行在啟動它的那個activity所在的棧中。
實踐:mainactivity 採用 standard 模式
在這種模式下,如果新的activity已經位於任務棧的棧頂,那麼此activity不會被重新創建,同時它的 newintent 方法將會被回調。如果新activity的實例已存在但不是位於棧頂,那麼新activity依然會被創建。
實踐:mainactivity 採用 singletop 模式
mainactivity 採用 singletop 模式,secondactivity採用 standard 模式
這是一種單實例模式,在這種模式下,只要activity在一個棧中存在,那麼多次啟動此activity都不會重新創建實例,而是回調 onnewintent() 。
實踐:mainactivity 採用 singletask 模式
mainactivity 採用 singletask 模式,secondactivity採用 standard 模式
這是一種加強的 singletask 模式,它除了具有 singletask 模式的所有特性外,還加強了一點,那就是具有此模式的activity只能單獨的位於一個任務棧中。
實踐:mainactivity 採用 singleinstance 模式
mainactivity 採用 singleinstance 模式,secondactivity採用 standard 模式
以上就是activity啟動模式的介紹。
歡迎留言指出錯誤。
㈡ android. 當啟動一個activity並且完後需要返回到啟動他的activity來執行的回調函數是
1、首先在打開的xml界面中,定義一個按鈕,如下圖所示。
㈢ android 怎麼設置activity的啟動模式
在android中每個界面都是一個activity,切換界面操作其實是多個不同activity之間的實例化操作。在android中activity的啟動模式決定了activity的啟動運行方式。
android總activity的啟動模式分為四種:
activity啟動模式設置:
activity的四種啟動模式:
1. standard
模式啟動模式,每次激活activity時都會創建activity,並放入任務棧中。
2. singletop
如果在任務的棧頂正好存在該activity的實例, 就重用該實例,否者就會創建新的實例並放入棧頂(即使棧中已經存在該activity實例,只要不在棧頂,都會創建實例)。
3. singletask
如果在棧中已經有該activity的實例,就重用該實例(會調用實例的onnewintent())。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
4. singleinstance
在一個新棧中創建該activity實例,並讓多個應用共享改棧中的該activity實例。一旦改模式的activity的實例存在於某個棧中,任何應用再激活改activity時都會重用該棧中的實例,其效果相當於多個應用程序共享一個應用,不管誰激活該activity都會進入同一個應用中。
其中standard是系統默認的啟動模式。
下面通過實例來演示standard的運行機制:
1 private textview text_show;
2 private button btn_mode;
3
4 @override
5 public void oncreate(bundle savedinstancestate) {
6 super.oncreate(savedinstancestate);
7 setcontentview(r.layout.activity_main);
8
9 text_show = (textview) this.findviewbyid(r.id.text_show);
10
11 text_show.settext(this.tostring());
12
13 btn_mode = (button) this.findviewbyid(r.id.btn_mode);
14
15 }
16
//按鈕單擊事件
17 public void launchstandard(view v){
18 startactivity(new intent(this,mainactivity.class));
19
20 text_show.settext(this.tostring());
21 }
㈣ android 不用startactivity 怎麼開啟activity的方法
啟動其他apk的activity方法
有兩個app,分別叫做app1和app2。
app1包含兩個activity,分別叫做app1_a和app1_b.其中app1_a是入口activity.
也就是app1_a設置intent-filter,action為
app2隻有一個activity,叫做app2_a。
現在在app2_a中通過startactivity啟動app1_a是沒問題的.但是啟動app1_b的時候報了fc錯誤。
logcat如下:
08-03 02:23:44.119: warn/activitymanager(64): permission denied: checkcomponentpermission() requid=10030
08-03 02:23:44.119: warn/activitymanager(64): permission denial: starting intent { act=android.intent.action.view cmp=com.hello/.activity2 } from processrecord{407c8bc8 665:com.fileexplorer/10032} (pid=665, uid=10032) requires null
用法如下:
intent intent = new intent();
componentname componentname = new componentname("com.hello","com.hello.app1_a");//這個沒問題
//componentname componentname = new componentname("com.hello","com.hello.app1_b");//這個報錯
intent.setcomponent(componentname);
startactivity(intent);
解決方法:
(1)
通過隱式intent調用方法實現,需要在被調用的activity的manifest文件中添加
在startactivity(it)之前,設定該intent對應的action(com.example.project.show_activity)
intent intent = new intent();
intent.setaction(action);
intent.addflags(intent.flag_activity_new_task);
context.startactivity(intent);推薦使用
利用setaction方法啟動activity還有一個好處就是不需要知道包名和activity類名,只需要知道action就可以隱式的啟動activity
(2)
即使直接指定了目標activity的componentname,跨應用的activity調用也要至少給目標activity指定一個帶action的filter。如:
action name為空即可。
(3)給被調用的activity增加一個帶action的filter,如下:
然後可以通過隱式intent來調用,而不用使用intent.setcomponent方法,如下就ok了(但是經過驗證,這種方法只是對apk的入口activity有用,對普通的沒用,和上面的問題一樣無法解決:啟動其他apk的非入口activity)
intent i = new intent("com.sdmc.ottplayer.uercenter");
i.setflags(intent.flag_activity_new_task);
this.startactivity(intent);
異常處理:
caused by: android.util.androidruntimeexception: calling startactivity() from outside of an activity context requires the flag_activity_new_task flag. is this really what you want?
context中有一個startactivity方法,activity繼承自context,重載了startactivity方法。
如果使用 activity的startactivity方法,不會有任何限制,
而如果使用context的startactivity方法的話,就需要開啟一個新 的task,遇到上面那個異常的,都是因為使用了context的startactivity方法。
解決辦法是,加一個flag。intent.addflags(intent.flag_activity_new_task)
intent intent = new intent();
intent.setclass(mcontext, videoplayer.class);
intent.addflags(intent.flag_activity_new_task);
mcontext.startactivity(intent);
㈤ 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 必須加上以下這句,代表能夠接收隱式調用
只要匹配一個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啟動流程分析