2020.8.1
一.Application的啟動流程
手機開機->應用程式的縮略圖示被點選
①點選圖示->
②啟動ActivityThread->線程的入口點:main函數->建立ActivityThread
③将ActivityThread的對象進行綁定 thread.attach(false, startSeq)
④建立儀表對象,管理程式的生命周期 mInstrumentation = new Instrumentation()->
⑤建立上下文: ContextImpl context = ContextImpl.createAppContext(this,getSystemContext().mPackageInfo);
⑥建立應用程式:
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
app=mActivityThread.mInitialApplication.newApplication(cl,appClass,appContext)
⑦回調application的onCreate方法:instrumentation.callApplicationOnCreate(app)
二.啟動Activity的流程:ActivityThread
①handleLaunchActivity->performLaunchActivity
②建立Activity上下文 createBaseContextForActivity
③建立啟動的頁面
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
④将界面和視窗Window綁定 activity.attach(appContext,getInstrumentation(),window)
⑤調用onCreate方法布局Activity界面
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);->
activity.performCreate(icicle, persistentState);->
onCreate(icicle);
是以在Activity的子類中,通過實作onCreate方法,來對界面進行初始化(UI布局,邏輯初始化)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIkRTN0IWZxYjZlZGNvwFcvwVbvNmL1h2cuFWaq5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
APP啟動流程圖.png
三.上下文——Context
上下文:運作環境,可以了解為就是一個橋梁,Context提供了調用系統資源的方法,裝置Context界面
Activity的context和applicationContext的差別
①大多數情況下,可以互相使用
②如果在涉及界面的跳轉,盡量使用Activity的context,因為它提供了預設的任務棧,applicationContext沒有提供任務棧
一個Activity的繼承于Context,是以通常情況下使用其本身作為Context
四.Activity之間的跳轉
Activity就是一個獨立的頁面
實作頁面之間的跳轉->Intent意圖
顯示跳轉:同一個應用程式,不同界面之間的跳轉,明确指定從哪個頁面切換到哪個頁面
不傳遞資料的跳轉
val intent=Intent(this,目的界面的java位元組碼檔案)
startActivity(intent) 啟動意圖,進行界面跳轉
//明确指定從目前頁面跳轉到app頁面
val intent=Intent(this,app::class.java)
//啟動
startActivity(intent)
finish():結束目前界面,即把目前界面删除,然後從任務棧中調出上一個界面并顯示,其實在manifests配置檔案中給Activity添加父界面,就是等價于添加了finish()方法
傳遞資料的跳轉
intent.putExtra(Key,Value):通過給intent添加鍵值對的方式來傳遞資料
intent.getStringExtra(Key):在目的界面中可以通過intent的鍵擷取對應的值
注:putExtra()->隻能傳遞系統預設的基本類型
intent.putExtra("name","jack")//起始界面傳遞資料
val name:String?=intent.getStringExtra("name")//目的界面中擷取值
val bundle=Bundle()->管理一對鍵值對
bundle.putString(Key,Value)
intent.putExtras(bundle)同樣可以實作傳遞資料
val bundle=Bundle().apply {
putString("name","jack")
putInt("age",20)
}
intent.putExtras(bundle)
val bundle2=intent.extras:在目的界面中擷取Bundle的一個對象
bundle2.getString(Key)擷取對應的值
val bundle2:Bundle?=intent.extras
val name=bundle2?.getString("name")
val age=bundle2?.getInt("age")
需要傳回值的跳轉
startActivityForResult(intent,自定義的請求碼)
同時必須重寫onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)方法
-----------------------------------起始界面--------------------------------------------
startActivityForResult(intent,1)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
//1.判斷是不是我請求的資料
if (requestCode==1){
//2.判斷處理結果 resultCode
if(resultCode==0){
Log.v("cx","處理成功:${data?.getStringExtra("uid")}")
}else{
Log.v("cx","處理失敗")
}
}
}
目的界面中setResult(自定義結果碼)->不帶資料的傳回
setResult(自定義結果碼,Intent的一個對象)->帶資料的傳回
傳回的資料儲存在函數參數data中
-----------------------------------目的界面--------------------------------------------
//1.回調結果 不帶資料
setResult(0)
//2.帶資料
Intent().apply {
putExtra("uid","001")
setResult(0,this)
}
原界面可以通過data擷取傳回的資料
隐式跳轉:不同程式之間,運作界面的跳轉(微信支付、支付寶支付)
打開系統提供的服務(相機、撥号、發消息)
使用方式:由于系統提供的類無法在程式中通過Intent(目前頁面,目的頁面的位元組碼檔案)來通路,隻能通過配置檔案的意圖過濾器來查找我們需要的Activity,即添加一個action,每個界面有很多個意圖過濾器,使用任意一個意圖都可以啟動該服務,并跳轉到服務界面
注:你想要啟動系統某個服務界面,如撥号,那麼得知道撥号對應的action,你可以通過閱讀源代碼來查找撥打電話對應的action,也可以通過Intent的靜态屬性來擷取
//撥打電話
Intent().apply {
//通過配置檔案的意圖過濾器來查找我們需要的Activity
action=Intent.ACTION_DIAL //靜态屬性擷取action
//data傳遞資料
data=Uri.parse("tel:10086") //傳遞所需的電話号碼,必須按照源碼格式
//滿足以上兩種條件,便可進行隐式跳轉
}.also {
startActivity(it)
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIkRTN0IWZxYjZlZGNvwFcvwVbvNmL1h2cuFWaq5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
源碼解析.png
跳轉到其他應用程式
前提:根據啟動系統提供的服務可知,隐式跳轉到其他系統服務/程式,需要目的Activity提供意圖過濾器和傳遞資料的格式
在應用程式的AndroidManifest.xml中配置
--------------------------------------app1----------------------------------------------
在其他應用中進行跳轉
--------------------------------------app2----------------------------------------------
Intent().apply {
action="cx.action.wiwi"
data= Uri.parse("cx:MyAPP")
}.also {
startActivity(it)
}
跳轉到app1中,可通過data擷取傳遞的資料
--------------------------------------app1----------------------------------------------
val content=intent.data?.schemeSpecificPart
Log.v("cx",content)