(廢棄)簡單的 applicappation 通用組件

開場白

今天突然有感,想寫一個通用的 application 組件出來,應該是對 application 的思考和積累有點心得了,要不怎么會突然冒出這個想法呢

在項目中我們都會一個 MainApplication 類承載我們 application 中的邏輯,期中有很大一部分邏輯代碼都是通用的,考慮到平臺化的問題(我司內部就有好幾個 app),怎么復用 application 是個問題。還有一部分功能和業務組件時需要 applicationContent 的,所以怎么跨 app 通用 application 是個問題。


application 組件思路

application 抽象成公共組件是個必然,但是在 app 內我們不能簡單的復用 application 類型,每個 app 中的application 都是不同的,所以難點在于怎么讓 application 可以實現跨 app 。

上面的問題可以使用代理的思路,全局靜態的 applicationProxy 對象持有 app 的 application 對象,這樣統一了 application 類型,我們就能在任何地方使用 application 了。

另外添加了一些 application 常用的功能:

  • app 啟動,home 鍵切入后臺,切回前臺的回調和狀態記錄
  • 手機信息采集
  • 棧管理(類我聲明了,具體邏輯沒寫)
  • app 進程回收優化

application 組件分層

因為要實現的功能不多,我也不打算寫多少,所以 application 組件功能分層很簡單,有下面幾個類:

  • ApplicationComponent
    application 組件外部公共入口
  • AppStateManage
    app 狀態記錄器,有4個標記位:app 啟動,進入后臺,進入前臺,當前狀態
  • ActivityManage
    app activity 棧管理
  • PhoneInfoManage
    手機信息采集器
  • ListenerAdapter
    回調適配器
AppStateManage

AppStateManage 定義的4個 app 狀態值需要搞清楚

    // app 首次啟動
    public static final int STATE_APPSTATE = 0;
    // app 在前臺
    public static final int STATE_FRONT = 1;
    // app 在后臺
    public static final int STATE_BACKGROUD = -1;
    // app 當前狀態
    public int currentState = STATE_APPSTATE;
ApplicationComponent
public class ApplicationComponent {

    ..............

    public void attach(Application application) {

        if (application != null) {
            this.application = application;
            initParameter();
            registerActivityLifecycleCallback();
        }
    }
 }

ApplicationComponent 因為要對外提供統一的公共入口,所以靜態單例是沒跑了

ApplicationComponent 核心就是 attach 方法,attach 方法會關聯 app 的 application 對象并給 application 對象注冊 ActivityLifecycleCallbacks 全局回調監聽函數,Application 組件的核心功能都是在這里實現的

ActivityManage

ActivityManage 應該是實現 activity 棧管理的,我這里沒做。我在 ActivityManage 里面記錄了活動窗口數量,這個參數是判斷 app 在后臺還是前臺的核心。


app 啟動,前臺,后臺的判斷思路

這個需求大家應該都碰到過,但是 android API 對這個需求真是無能為力,需要自己想辦法,我在上一個項目的日志模塊碰到的這個需求,需要準確區分 app 的啟動,切入后臺,切回前臺。

我的思路很簡單,就是利用 application 注冊的 ActivityLifecycleCallbacks 全局監聽函數中的 activityStart 和 activityStop 方法中記錄當前活躍的窗口數。

  • AppStateManage 中的 currentState 默認是 app 啟動
  • activityStart 函數:
    * 先判斷 currentState 是不是 app 啟動標記,是的話,執行 app 啟動的回調函數,然后currentState 置為前臺標記,然后活動窗口數++,return
    * 若 currentState 不是 app 啟動標記,并且活動窗口數為0的話,表示切回前臺,然后活動窗口數++,return
  • activityStop 函數,活動窗口數先 -- ,若活動窗口數為0的話,app 就進入后臺了。

用這個思路,判斷 app 是不是首次啟動,home 切入后臺,切回前臺很準確,并且把這端邏輯放在 applicappation 組件中,適合別的組件調用,尤其是在推送中判斷當前 app 的狀態是個很好的做法。

另外我在 ActivityManage 中只記錄了活動窗口數,大家可以自行擴展線管公共,比如有的組件需要獲取到當前活動的 activity 對象的,放到 ActivityManage 挺合適的。


APP 進程優化

這個是應對一個問題: 系統殺后臺的 app 進程會緩存 activity 棧信息,再次由系統啟動 app 進程的話,界面會直接來到上次的位置。

這就帶來一個問題,我們在 flashActivity 中會寫很多啟動邏輯和初始化操作,要是有 activity 棧緩存的話,就不會執行正常的啟動邏輯了,flashActivity 頁面就沒法執行了,有次會帶來很多問題,尤其是初始化方法沒有執行造成的空指針。我們在寫日志模塊時,因為需要讀寫 SD 卡的權限,所以日志組件的初始化放到 flashActivity 里,結果就因為這個 activity 棧緩存的問題報了很多次空指針,教訓啊!

那么面對這個問題怎么解決呢,就是在 app 處于后臺進程,并且快被回收時,不用等系統回收,咱們自己殺自己,這樣就沒有 activity 棧緩存的問題了,app 啟動邏輯永遠都會按我們設計的走,對我們就沒有干擾了。

關于后臺進程回收優先級的點看我這篇文章:

關于殺進程的問題再補充一下,app 處于后臺時不管我們怎么殺進程都沒事,但是 app 在前臺時我們殺進程,進程的確會被殺死,但是進程在被殺死之后還會重啟,沒有 activity 棧緩存的問題,會按正常邏輯啟動 app

殺進程的方法如下:


最后

項目地址: BW_Application

完事之后,感覺寫的很一般,太菜了,功能是分層了,但是邏輯沒有完全分層,尤其是對 app 啟動,后太,前臺的邏輯判斷上,全都放在作為外部入口的 ApplicationComponent 類里了,這對不熟悉這個組件的朋友和未來的自己修改維護帶來了麻煩和困擾,一是邏輯位置不好找,二是不方便擴展。引以為戒吧,從小處看代碼封裝的水平,代碼封裝的水平基本就代表了手底下的代碼編寫水平,我這也是不合格呀。

大家就胡看吧,小白太菜沒辦法......

參考資料


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。