Android必知必會的四大元件 -- Activity篇

ClericYi發表於2020-02-25

Android必知必會的四大元件 -- Activity篇

前言

先出一個題吧,Activity A 跳轉Activity B,再從Activity B按back鍵回退,兩個過程各自的生命週期?

這是一個比較簡單的生命週期問題,但是很多人會答錯。那我們就對整個生命週期進行一個分析,再給出答案好了。並且文章內有一些內容我已經寫過了,都是通過給出連結方式跳轉檢視了,請見諒。

思維導圖

Android必知必會的四大元件 -- Activity篇

生命週期

Android必知必會的四大元件 -- Activity篇

這兒重點要知道的是下面這兩對各自之間的區別的區別。

(1)onPause()onStop()

(2)onStart()onResume()

onPause()說明當前的Activity已經暫停,但你並不是說暫停的意思只是沒有了動作,而呼叫了onStop()才讓Acivity不可見。onStart()也是一樣,只是說Activity已經可以啟動了,但這個時候頁面還是不可見的,只有呼叫了onResume()頁面才能夠可見,頁面跳轉也是如此。

現在在回答一下之前的問題,Activity A 跳轉Activity B,再從Activity B按back鍵回退,兩個過程各自的生命週期?

  1. Activity A 跳轉Activity B: Apause -> Bcreate -> Bstart -> Bresume -> Astop
  2. Activity B再按back鍵回退: Bpause -> Arestart -> Astart -> Aresume -> Bstop -> Bdestroy

啟動模式

詳見於幾張圖讓你明白Android四大啟動模式

事件分發機制

詳見於Android事件分發機制,你瞭解過嗎?

這裡說一下為什麼我要把這個模組放在Activity,明明這個機制涉及的有三方ActivityViewGroupView

其實我的思考主要是因為Activity是接受到這些動作的第一人,而不管是ViewGroup還是View,都是後來經過一個事件的分發後,才有的他們的處理,所以我將事件分發機制歸結於此。

Activity之間的資料傳輸

Activity的跳轉之間,其實存在很多需要帶上資料的情況。舉個例子來說,就像是從Activity A一個新聞列表中選取了一條新聞,那這個時候就需要跳轉進入Activity B,而查詢新聞的方式我們就假設是他的id那這個時候,就需要將這個idActivity A送到Activity B中。

其實這種方式有很多,但是最普遍進行使用的莫過於putExtra(key, value)了。

使用方法

// 1. 定義跳轉頁面
Intent intent = new Intent(this, SecActivity.class);
// 2. 將資料放到Intent中
intent.putExtra("parameter key", "parameter value");
// 3. 啟動頁面
//      |-- 不帶回傳方法
startActivity(intent);
//      |-- 帶回傳方法
startActivityForResult(intent, REQUEST_CODE);
複製程式碼

這裡要注意的一個問題就是,如果想要接受到返回的資料,那我們就存在必須重寫的方法,通過下方模版即可完成。

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if(requestCode == REQUEST_CODE){
            // 進行相應的處理
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
複製程式碼

完成了頁面跳轉和引數傳遞,那我們接下來要幹啥?當然是拿到這些引數了!!!

getIntent().getStringExtra(key);
getIntent().getBooleanExtra(key);
// 。。。。。。
複製程式碼

實在太多了,我就不一一列舉了。那我們就出現問題了getIntent()哪兒來的,傳遞靠的是什麼機制??,因為我們的接收還沒講完,所以我們這個問題先保留。

因為我們說過一個事情存在回撥,我們應該要怎麼做的問題。

// 通過setRsult()方法,來進行一個資料的回傳
setResult(resultCode);
setResult(resultCode, intent);

// 模版,setResult()方法二選一
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
        // 說明是一個返回事件
        if (keyCode == KeyEvent.ACTION_DOWN && event.getAction() == KeyEvent.ACTION_DOWN) {
            Intent intent = new Intent();
            intent.putExtra("parameter key", "parameter value");
            // setResult(resultCode);
            setResult(resultCode, intent);
        }

        return super.onKeyDown(keyCode, event);
    }
複製程式碼

Activity之間跳轉,Intent的設定

你可能想說博主怎麼這麼多問題???哈哈哈哈哈!一起來探討一下唄,反正我也剛想知道。

public Intent getIntent() {
        return mIntent;
    }
複製程式碼

我們去ActivitystartActivity(intent)跳轉過程中去查詢,當然程式碼太多了,我就直接總結好了。

startActivity() --> startActivityForResult() --
--> Instrumentation.execStartActivity() --> IActivityTaskManager.startActivity() --
--> 進入了一個.aidl檔案然後我也不知道了,但是肯定是在這裡辦正事兒的
複製程式碼

探索發現:

(1)我們的資料,也就是Intent中使用putExtra(key, value)放置的資料最後都被封裝進了Bundle,所以說Bundle其實就是我們Activity之間資料傳遞的媒介。

(2)而Activity的跳轉也是基於一個Binder的機制來完成的,當然問我為啥呢。我也只能說因為包裡找不到,基本上只會是.aidl檔案,然後結合以前看的網上的解析都是說基於Binder的機制。

當然我的問題並沒有解決,等我以後知識儲備夠了再來分析一下底層。

總結

其實上面都講的差不多了,這裡說一個實際會碰到的問題把。

就是staticHandlerServiceConnection這一類可能會引發的記憶體洩漏問題。他們存在解決方法,其實多種多樣,但更多一般也都是基於生命週期來完成的。一般解法都是在onDestroy()進行置空操作、或是解綁這一類方法把。

以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。


相關文章推薦:

Android必知必會的四大元件 -- Broadcast Receiver篇

Android必知必會的四大元件 -- Service篇

Glide都在用的LruCache,你會幾分?

相關文章