Android開發(fā)——詳解Activity

2020.8.1

一.Application的啟動流程

  1. 手機(jī)開機(jī)->應(yīng)用程序的縮略圖標(biāo)被點(diǎn)擊
  2. ①點(diǎn)擊圖標(biāo)->
    ②啟動ActivityThread->線程的入口點(diǎn):main函數(shù)->創(chuàng)建ActivityThread
    ③將ActivityThread的對象進(jìn)行綁定 thread.attach(false, startSeq)
    ④創(chuàng)建儀表對象,管理程序的生命周期 mInstrumentation = new Instrumentation()->
    ⑤創(chuàng)建上下文: ContextImpl context = ContextImpl.createAppContext(this,getSystemContext().mPackageInfo);
    ⑥創(chuàng)建應(yīng)用程序:
    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    app=mActivityThread.mInitialApplication.newApplication(cl,appClass,appContext)
    ⑦回調(diào)application的onCreate方法:instrumentation.callApplicationOnCreate(app)

二.啟動Activity的流程:ActivityThread

①handleLaunchActivity->performLaunchActivity
②創(chuàng)建Activity上下文 createBaseContextForActivity
③創(chuàng)建啟動的頁面
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
④將界面和窗口Window綁定 activity.attach(appContext,getInstrumentation(),window)
⑤調(diào)用onCreate方法布局Activity界面
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);->
activity.performCreate(icicle, persistentState);->
onCreate(icicle);

  • 所以在Activity的子類中,通過實(shí)現(xiàn)onCreate方法,來對界面進(jìn)行初始化(UI布局,邏輯初始化)


    APP啟動流程圖.png

三.上下文——Context

上下文:運(yùn)行環(huán)境,可以理解為就是一個(gè)橋梁,Context提供了調(diào)用系統(tǒng)資源的方法,設(shè)備<--->Context<--->界面

  • Activity的context和applicationContext的區(qū)別
    ①大多數(shù)情況下,可以相互使用
    ②如果在涉及界面的跳轉(zhuǎn),盡量使用Activity的context,因?yàn)樗峁┝四J(rèn)的任務(wù)棧,applicationContext沒有提供任務(wù)棧
  • 一個(gè)Activity的繼承于Context,所以通常情況下使用其本身作為Context

四.Activity之間的跳轉(zhuǎn)

  • Activity就是一個(gè)獨(dú)立的頁面
  • 實(shí)現(xiàn)頁面之間的跳轉(zhuǎn)->Intent意圖
  1. 顯示跳轉(zhuǎn):同一個(gè)應(yīng)用程序,不同界面之間的跳轉(zhuǎn),明確指定從哪個(gè)頁面切換到哪個(gè)頁面

??????????????不傳遞數(shù)據(jù)的跳轉(zhuǎn)

  • val intent=Intent(this,目的界面的java字節(jié)碼文件)
  • startActivity(intent) 啟動意圖,進(jìn)行界面跳轉(zhuǎn)
    //明確指定從當(dāng)前頁面跳轉(zhuǎn)到app頁面
    val intent=Intent(this,app::class.java)
    //啟動
    startActivity(intent)
  • finish():結(jié)束當(dāng)前界面,即把當(dāng)前界面刪除,然后從任務(wù)棧中調(diào)出上一個(gè)界面并顯示,其實(shí)在manifests配置文件中給Activity添加父界面,就是等價(jià)于添加了finish()方法
    ?????????????傳遞數(shù)據(jù)的跳轉(zhuǎn)
  • intent.putExtra(Key,Value):通過給intent添加鍵值對的方式來傳遞數(shù)據(jù)
  • intent.getStringExtra(Key):在目的界面中可以通過intent的鍵獲取對應(yīng)的值
  • 注:putExtra()->只能傳遞系統(tǒng)默認(rèn)的基本類型
    intent.putExtra("name","jack")//起始界面?zhèn)鬟f數(shù)據(jù)
    val name:String?=intent.getStringExtra("name")//目的界面中獲取值
  • val bundle=Bundle()->管理一對鍵值對
    bundle.putString(Key,Value)
  • intent.putExtras(bundle)同樣可以實(shí)現(xiàn)傳遞數(shù)據(jù)
       val bundle=Bundle().apply {
            putString("name","jack")
            putInt("age",20)
        }
       intent.putExtras(bundle)
  • val bundle2=intent.extras:在目的界面中獲取Bundle的一個(gè)對象
    bundle2.getString(Key)獲取對應(yīng)的值
        val bundle2:Bundle?=intent.extras
        val name=bundle2?.getString("name")
        val age=bundle2?.getInt("age")

?????????????需要返回值的跳轉(zhuǎn)

  • startActivityForResult(intent,自定義的請求碼)
  • 同時(shí)必須重寫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.判斷是不是我請求的數(shù)據(jù)
        if (requestCode==1){
            //2.判斷處理結(jié)果 resultCode
            if(resultCode==0){
                Log.v("cx","處理成功:${data?.getStringExtra("uid")}")
            }else{
                Log.v("cx","處理失敗")
            }
        }
    }
  • 目的界面中setResult(自定義結(jié)果碼)->不帶數(shù)據(jù)的返回
    setResult(自定義結(jié)果碼,Intent的一個(gè)對象)->帶數(shù)據(jù)的返回
    返回的數(shù)據(jù)保存在函數(shù)參數(shù)data
-----------------------------------目的界面--------------------------------------------
          //1.回調(diào)結(jié)果 不帶數(shù)據(jù)
            setResult(0)
           //2.帶數(shù)據(jù)
            Intent().apply {
                putExtra("uid","001")
                setResult(0,this)
            }
  • 原界面可以通過data獲取返回的數(shù)據(jù)
  1. 隱式跳轉(zhuǎn):不同程序之間,運(yùn)行界面的跳轉(zhuǎn)(微信支付、支付寶支付)
    ????????打開系統(tǒng)提供的服務(wù)(相機(jī)、撥號、發(fā)消息)
    使用方式:由于系統(tǒng)提供的類無法在程序中通過Intent(當(dāng)前頁面,目的頁面的字節(jié)碼文件)來訪問,只能通過配置文件的意圖過濾器來查找我們需要的Activity,即添加一個(gè)action,每個(gè)界面有很多個(gè)意圖過濾器,使用任意一個(gè)意圖都可以啟動該服務(wù),并跳轉(zhuǎn)到服務(wù)界面
    注:你想要啟動系統(tǒng)某個(gè)服務(wù)界面,如撥號,那么得知道撥號對應(yīng)的action,你可以通過閱讀源代碼來查找撥打電話對應(yīng)的action,也可以通過Intent的靜態(tài)屬性來獲取
            //撥打電話
            Intent().apply {
                //通過配置文件的意圖過濾器來查找我們需要的Activity
                action=Intent.ACTION_DIAL  //靜態(tài)屬性獲取action
                //data傳遞數(shù)據(jù)
                data=Uri.parse("tel:10086") //傳遞所需的電話號碼,必須按照源碼格式
                //滿足以上兩種條件,便可進(jìn)行隱式跳轉(zhuǎn)
            }.also {
                startActivity(it)
            }

源碼解析.png

??????????????跳轉(zhuǎn)到其他應(yīng)用程序
前提:根據(jù)啟動系統(tǒng)提供的服務(wù)可知,隱式跳轉(zhuǎn)到其他系統(tǒng)服務(wù)/程序,需要目的Activity提供意圖過濾器和傳遞數(shù)據(jù)的格式
<intent-filter>在應(yīng)用程序的AndroidManifest.xml中配置

--------------------------------------app1----------------------------------------------
            <!-- 添加意圖過濾器 -->
            <intent-filter>
                <!-- 系統(tǒng)定義 -->
                <action android:name="android.intent.action.SEND"/>
                <!-- 自定義 -->
                <action android:name="cx.action.wiwi"/>
                <!-- 如果希望外部程序能夠啟動這個(gè)頁面 必須設(shè)置Category為Default -->
                <category android:name="android.intent.category.DEFAULT"/>
                <!-- 如果希望外部啟動這個(gè)界面的時(shí)候傳遞數(shù)據(jù)過來 必須定義數(shù)據(jù)的格式 -->
                <data android:scheme="cx"/>
            </intent-filter>

在其他應(yīng)用中進(jìn)行跳轉(zhuǎn)

--------------------------------------app2----------------------------------------------
Intent().apply {
                action="cx.action.wiwi"
                data= Uri.parse("cx:MyAPP")
            }.also {
                startActivity(it)
            }

跳轉(zhuǎn)到app1中,可通過data獲取傳遞的數(shù)據(jù)

--------------------------------------app1----------------------------------------------
 val content=intent.data?.schemeSpecificPart
        Log.v("cx",content)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容