天天看點

android啟動器開發詳解,Android開發——詳解Activity

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布局,邏輯初始化)

android啟動器開發詳解,Android開發——詳解Activity

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)

}

android啟動器開發詳解,Android開發——詳解Activity

源碼解析.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)