application 元件設計

血色王冠發表於2019-05-10

沒校對,有錯別字大家見諒吧~

application 元件設計

為什麼我要封裝 application

application 在以前是非常重要的一個地方,剛開始開發時我們會在 application 中儲存資料,提供全域性公共方法,application 雖然很方便,但是漸漸的我們還是放棄了在 application 裡面做其他的工作,現在 application 主要的應用場景是:

但是我在使用 application 時還是遇到了一些問題不好處理:

  • 平臺化時,公司一個團隊要同時開發多個 app,不同的 app 有不同的 application 實現類,這樣我們在業務module 裡怎麼統一方便的拿到 application
  • application 沒有提供 啟動,退出,切到後臺,前臺的相應方法
  • 沒有優雅的退出 app 的方法
  • 沒有能拿到 app 當前狀態的地方,ActivityManage 又存在適配問題,有的裝置 TM 的就是出么蛾子

我想大家都曾為了上面的問題煩惱過吧,也許你已經解決了,也許你只是臨時解決了,也許你還沒解決。同樣這也困擾過我,以前我只是臨時解決,程式碼耦合難看,還沒發適應越來越高的複用要求,一處該,處處動,這樣的程式碼不是我想要的,早就該掃到垃圾箱裡去了,於是誕生了今天的文章

我對 application 是這樣安排的:

話說官方的 Lifecycle 剛出來時我是非常興奮的,我想這下 app 的生命週期該好用了吧,興奮的我一看官方壓根就沒動 application,只是把 Activity 的宣告周期函式響應式化了,我是很失望的,也許 google 考慮相容性吧


回顧下 ActivityLifecycleCallbacks

application 的核心就是這個了,一切的基礎都是他在身上做的

public class Application extends ContextWrapper implements ComponentCallbacks2 {

    private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<ActivityLifecycleCallbacks>();

    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }
}
複製程式碼

我們平時使用 ActivityLifecycleCallbacks 基本都是這個樣子的

        this.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {

            override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
                Log.d("AA", "onActivityCreated")
            }

            override fun onActivityResumed(activity: Activity?) {
                Log.d("AA", "onActivityResumed")
            }

            override fun onActivityStarted(activity: Activity?) {
                Log.d("AA", "onActivityStarted")
            }

            override fun onActivityPaused(activity: Activity?) {
                Log.d("AA", "AA")
            }

            override fun onActivityDestroyed(activity: Activity?) {
                Log.d("AA", "onActivityDestroyed")
            }

            override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
                Log.d("AA", "onActivitySaveInstanceState")
            }

            override fun onActivityStopped(activity: Activity?) {
                Log.d("AA", "onActivityStopped")
            }
        })
複製程式碼

跟進原始碼看看

    public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
        synchronized (mActivityLifecycleCallbacks) {
            mActivityLifecycleCallbacks.add(callback);
        }
    }
複製程式碼

注意看是 add 方法,這說明啥,這說明 ActivityLifecycleCallbacks 我們可以新增多個,Activity 會在相應的生命週期函式中發射相關訊息

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        getApplication().dispatchActivityCreated(this, savedInstanceState);
}

    void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
        Object[] callbacks = collectActivityLifecycleCallbacks();
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
                        savedInstanceState);
            }
        }
    }
複製程式碼

我們新增 2個 ActivityLifecycleCallbacks 進去

application 元件設計

事實證明,的確可以新增多個回撥,並且沒有問題,這也是我們自己封裝 application 元件的基石


類結構

我就不畫 UML 類圖,因為很簡單

application 元件設計

考慮到我要在 application 元件裡新增很多功能進來,那麼良好合理的分層就必不可少了,即便是該功能非常簡單,直接在 ApplicationManage 裡實現更方便,但是基於單一職責原則必須分工明確,現在費點勁,以後省大事

我設計了以下幾個角色:

Lifecycle 和 StateManage 都是私有的,不是應該外部可見的。外部只需要註冊生命週期的 observer,不需要知道我怎麼實現的。同樣 外部不需要知道我們怎麼管理的 app 當前狀態,只需要知道現在 app 是個什麼樣子。這部分我通過 ApplicationManage 對外提供相應方法

另外我在寫訊息型別和 app 狀態型別時,我考慮了下相應的 type 放在哪裡合適,是相應 manage 的內部類,還是專門一個類。內部類方便外界使用,專門的類方便檢視程式碼結構,這就得看實際場景了,Lifecycle 這塊我是用的內部類做的,這樣邏輯順延好些程式碼,exit 這塊基本都是對內的,不暴露出來,所以專門維護了一個類


使用效果

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ScreenAutoManager.instance.init(this, 1080.0f, ScreenAutoManager.BASE_LINE_WIDTH)

        ApplicationManage.init(this)
        ApplicationManage.instance.addObserver { lifecycleMessage ->
            when (lifecycleMessage.type) {
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_CREATE -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityCreated(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_CREATE")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_START -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityStarted(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_START")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_RESUME -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityResumed(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_RESUME")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_PAUSE -> Log.d("AA", "MESSAGE_ACTIVITY_PAUSE")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_STOP -> Log.d("AA", "MESSAGE_ACTIVITY_STOP")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_SAVEINSTANCESTATE -> Log.d("AA", "MESSAGE_ACTIVITY_SAVEINSTANCESTATE")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_DESTROYED -> Log.d("AA", "MESSAGE_ACTIVITY_DESTROYED")

                ApplicationManage.MessageType.MESSAGE_APP_START -> Log.d("AA", "MESSAGE_APP_START")
                ApplicationManage.MessageType.MESSAGE_APP_EXIT -> Log.d("AA", "MESSAGE_APP_EXIT")
                ApplicationManage.MessageType.MESSAGE_APP_FORNT -> Log.d("AA", "MESSAGE_APP_FORNT")
                ApplicationManage.MessageType.MESSAGE_APP_BACKGROUD -> Log.d("AA", "MESSAGE_APP_BACKGROUD")
            }
        }
    }
複製程式碼

改造 application 生命週期管理

我個人是很喜歡 Lifecycle 的,官方人家可是用的 apt 做的,我註解這塊寫不好,藉助的是 Livedata,在 registerActivityLifecycleCallbacks 時發射相應的訊息出來

class LifecycleManage {
    var lifecycleLivaData: MyLiveData<LifecycleMessage> = MyLiveData()

    /**
     * 初始化方法
     */
    fun init(application: Application) {
        registerActivityLifecycleCallbacks(application)
    }

    /**
     * 註冊 application 生命週期回撥函式,在對應的函式回撥中發射對應的訊息
     */
    private fun registerActivityLifecycleCallbacks(application: Application) {
        if (application == null) return

        application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {

            override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_CREATE, activity = activity, savedInstanceState = savedInstanceState))
            }

            override fun onActivityStarted(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_START, activity = activity))
            }

            override fun onActivityResumed(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_RESUME, activity = activity))
            }

            override fun onActivityPaused(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_PAUSE, activity = activity))
            }

            override fun onActivityStopped(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_STOP, activity = activity))
            }

            override fun onActivityDestroyed(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_DESTROYED, activity = activity))
            }

            override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_SAVEINSTANCESTATE, activity = activity, savedInstanceState = outState))
            }
        })
    }
}
複製程式碼

然後大家通過 ApplicationManage 實現註冊 observer

    fun addObserver(tag: String? = null, lifecycle: Lifecycle? = null, observer: (lifecycleMessage: LifecycleMessage) -> Unit) {
        lifecycleManage.lifecycleLivaData.addObserver(tag, lifecycle, observer)
    }
複製程式碼

然後是使用

        ApplicationManage.instance.addObserver { lifecycleMessage ->
            when (lifecycleMessage.type) {
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_CREATE -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityCreated(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_CREATE")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_START -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityStarted(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_START")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_RESUME -> {
                    if (lifecycleMessage.activity != null) ScreenAutoManager.instance.onActivityResumed(lifecycleMessage.activity)
                    Log.d("AA", "MESSAGE_ACTIVITY_RESUME")
                }
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_PAUSE -> Log.d("AA", "MESSAGE_ACTIVITY_PAUSE")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_STOP -> Log.d("AA", "MESSAGE_ACTIVITY_STOP")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_SAVEINSTANCESTATE -> Log.d("AA", "MESSAGE_ACTIVITY_SAVEINSTANCESTATE")
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_DESTROYED -> Log.d("AA", "MESSAGE_ACTIVITY_DESTROYED")

                ApplicationManage.MessageType.MESSAGE_APP_START -> Log.d("AA", "MESSAGE_APP_START")
                ApplicationManage.MessageType.MESSAGE_APP_EXIT -> Log.d("AA", "MESSAGE_APP_EXIT")
                ApplicationManage.MessageType.MESSAGE_APP_FORNT -> Log.d("AA", "MESSAGE_APP_FORNT")
                ApplicationManage.MessageType.MESSAGE_APP_BACKGROUD -> Log.d("AA", "MESSAGE_APP_BACKGROUD")
            }
        }
複製程式碼

可以看到這裡 app 的啟動,退出,前後臺切換我也都傳送相關的訊息了

實現不難,思路就使用 livedata 在合適的位置轉發一下資料,官方的 Lifecycle 也是這個思路做的


判斷 app 啟動,退出,前後臺切換

我想大家都關心這個,相信大家也都有自己的實現,基本思路都是在 registerActivityLifecycleCallbacks 裡更新計數器判斷 app 狀態,這裡我也是一樣的,只不過多了一步罷了

我標識了 app 的3種狀態: app state 預設是 no - app沒啟動

val STATE_APP_NO: Int = 31
val STATE_APP_FORNT: Int = 32
val STATE_APP_BACKGROUD: Int = 33
複製程式碼

判斷邏輯如下:

  • app 啟動 - 觸發 create 函式,state = STATE_APP_NO,說明 app 之前沒啟動,那麼此時必然就是啟動了
  • app 退出 - 觸發 destroy 函式,若活躍 activity 計數 =0 了,那說明 app 就是關閉了
  • app 切入後臺 - 觸發 stop 函式,活躍 activity 計數先--,若 =0 了並且 state = STATE_APP_FORNT,那就是說明前臺沒有活躍顯示的 activity 了,進入後臺了
  • app 切回前臺 - 觸發 start 函式,先判斷 活躍 activity 計數,若 =0 了並且 state = STATE_APP_BACKGROUD,那說明又切回前臺來了,計數器再++

注意:onActivityStarted 這個函式即表示 onStart,也表示 onRestart ,所以在計數時要更外小心,因為 start 的原因 oncreate 不適合計數器++了,要不會和 start 重複

這樣我們也可以返回 app 當前的狀態了,不用再用 AM 來判斷了,AM 很多人反應部分手機無效,其實返回 app 狀態的這個小功能非常實用的,在推送時我們要判斷 app 是不是啟來了,因為由不同的操作


優雅的退出 app

我這裡思路很簡單,就是主介面下面墊一個透明無介面的 Activity,我們想退出 app 時啟動這個 Activity,在 onNewIntent 裡面 finish 頁面就行了,不過這個功能有侵入行:

  • 一是需要遮蔽主介面的 onBackPressed 函式,不控制返回鍵的話就回到這個透明的頁面了
  • 二是閃屏頁啟動主介面時需要使用該功能的啟動頁面方法
// 退出 app
ApplicationManage.instance.exitmanage.exitApp()

// 代理方法啟動主介面
ApplicationManage.instance.exitmanage.startActivityProxy(this, Intent(this@SplaseActivity, MainActivity::class.java))

// 遮蔽主介面返回按鍵預設操作
override fun onBackPressed() {
//  super.onBackPressed()
}
複製程式碼

具體程式碼

我知道大家都懶得看 demo,這程式碼長也得貼出來

/**
 * 作者 : BloodCrown
 * 時間 : 2019-05-08 21:33
 * 描述 :
 *  application 封裝類,在方便提供 application 上下文物件的同時,
 *  也提供了一些功能
 *
 * 功能 :
 *  1. Application 上下文代理,任何模組都不必關心 application 具體的實現型別
 *  有 ApplicationManage 在時刻都能獲取全域性上下文物件
 *
 *  2. 提供優雅退出 app 的功能,通過在主頁面下面新增一個透明的 activity + singleTask 實現優雅退出
 *
 *  3. Application 的生命週期實現響應式,像 EventBus,RxBus 那樣響應訊息就行,另外我還新增了
 *  app 啟動,退出,切入後臺,切回前臺的相應進來
 *
 *  4. 在實現功能3時,實現了 app 當前狀態的儲存,極大的方便了我們在注入推送時判斷 app 是否啟動等操作
 *
 *  最後說一點,我沒有使用 ActivityManage 來判斷 app 狀態,因為 ActivityManage 存在適配問題,
 *  總有那麼一小撮手機就是不配合,臣妾也是沒辦法呀~
 *
 */
class ApplicationManage {

    companion object Help {

        // 餓漢式單例,加上同步限制,這樣可以避免 application 操作類單例為null 的情況
        val instance: ApplicationManage by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            return@lazy ApplicationManage()
        }

        // 標準初始化方法,
        fun init(application: Application) {
            instance.init(application)
        }
    }

    // 全域性上下文物件
    var application: Application? = null
    // 退出 app 工具類
    var exitmanage: ExitManage = ExitManage()
    // app 全域性生命週期管理類,使用 livedata 實現,考慮其若是外部可見,就能使用他亂髮射資料,資料私有
    private var lifecycleManage: LifecycleManage = LifecycleManage()
    // app 狀態管理類,也是私有,這個實現絕對是不對外的,大家關心結果就好了,由 ApplicationManage 銜接
    private var stateManage: StateManage = StateManage()

    /**
     * 初始化方法私有,由靜態方法銜接
     */
    private fun init(application: Application) {
        this.application = application
        lifecycleManage.init(application)
        stateManage.initStateManage(lifecycleManage)
    }

    /**
     * 新增監聽
     */
    fun addObserver(tag: String? = null, lifecycle: Lifecycle? = null, observer: (lifecycleMessage: LifecycleMessage) -> Unit) {
        lifecycleManage.lifecycleLivaData.addObserver(tag, lifecycle, observer)
    }

    /**
     * 解綁
     */
    fun removeobserver(tag: String) {
        lifecycleManage.lifecycleLivaData.removeOberver(tag)
    }

    /**
     * 獲取當前 app 狀態
     */
    fun getCurrentState(): Int {
        return stateManage.STAET_CURRENT
    }

    /**
     * 訊息型別
     */
    class MessageType {

        companion object {
            // 對應 activity 的生命週期
            @JvmField
            val MESSAGE_ACTIVITY_CREATE: Int = 11
            @JvmField
            val MESSAGE_ACTIVITY_RESUME: Int = 12
            @JvmField
            val MESSAGE_ACTIVITY_START: Int = 13
            @JvmField
            val MESSAGE_ACTIVITY_PAUSE: Int = 14
            @JvmField
            val MESSAGE_ACTIVITY_STOP: Int = 15
            @JvmField
            val MESSAGE_ACTIVITY_DESTROYED: Int = 16
            @JvmField
            val MESSAGE_ACTIVITY_SAVEINSTANCESTATE: Int = 17

            // app 啟動,退出,切換到前臺,切換到後臺
            @JvmField
            val MESSAGE_APP_START: Int = 21
            @JvmField
            val MESSAGE_APP_EXIT: Int = 25
            @JvmField
            val MESSAGE_APP_FORNT: Int = 22
            @JvmField
            val MESSAGE_APP_BACKGROUD: Int = 23
        }
    }
}
複製程式碼
/**
 * 作者 : BloodCrown
 * 時間 : 2019-05-08 21:38
 * 描述 :
 */
class LifecycleManage {
    var lifecycleLivaData: MyLiveData<LifecycleMessage> = MyLiveData()

    /**
     * 初始化方法
     */
    fun init(application: Application) {
        registerActivityLifecycleCallbacks(application)
    }

    /**
     * 註冊 application 生命週期回撥函式,在對應的函式回撥中發射對應的訊息
     */
    private fun registerActivityLifecycleCallbacks(application: Application) {
        if (application == null) return

        application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {

            override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_CREATE, activity = activity, savedInstanceState = savedInstanceState))
            }

            override fun onActivityStarted(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_START, activity = activity))
            }

            override fun onActivityResumed(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_RESUME, activity = activity))
            }

            override fun onActivityPaused(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_PAUSE, activity = activity))
            }

            override fun onActivityStopped(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_STOP, activity = activity))
            }

            override fun onActivityDestroyed(activity: Activity?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_DESTROYED, activity = activity))
            }

            override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
                lifecycleLivaData.sendValue(LifecycleMessage(type = ApplicationManage.MessageType.MESSAGE_ACTIVITY_SAVEINSTANCESTATE, activity = activity, savedInstanceState = outState))
            }
        })
    }

}
複製程式碼
class LifecycleMessage(var type: Int, var activity: Activity? = null, var savedInstanceState: Bundle? = null) {
}
複製程式碼
/**
 * 作者 : BloodCrown
 * 時間 : 2019-05-09 21:32
 * 描述 :
 */
class StateManage {

    companion object stateType {

        // 沒啟動,前臺,後臺
        @JvmField
        val STATE_APP_NO: Int = 31
        @JvmField
        val STATE_APP_FORNT: Int = 32
        @JvmField
        val STATE_APP_BACKGROUD: Int = 33
    }

    var STAET_CURRENT: Int = STATE_APP_NO
    var aliveActivitys: Int = 0

    fun initStateManage(lifecycleManage: LifecycleManage) {
        if (lifecycleManage == null) return

        addObserver(lifecycleManage)
    }

    /**
     * 新增管理器
     */
    private fun addObserver(lifecycleManage: LifecycleManage) {
        if (lifecycleManage == null) return
        lifecycleManage.lifecycleLivaData.addObserver {
            when (it.type) {
                ApplicationManage.MessageType.MESSAGE_ACTIVITY_CREATE -> {
                    // 標記是沒啟動,那麼觸發 create 一定是app 啟動
                    if (STAET_CURRENT == STATE_APP_NO) {
                        STAET_CURRENT = STATE_APP_FORNT
                        lifecycleManage.lifecycleLivaData.sendValue(LifecycleMessage(ApplicationManage.MessageType.MESSAGE_APP_START))
                    }
                }

                ApplicationManage.MessageType.MESSAGE_ACTIVITY_START -> {
                    // 活動 ac 數量為0,並且當前標記是 app 在後臺,那麼此時觸發 start,那麼就是切會到前臺來了
                    if (aliveActivitys == 0 && STAET_CURRENT == STATE_APP_BACKGROUD) {
                        STAET_CURRENT = STATE_APP_FORNT
                        lifecycleManage.lifecycleLivaData.sendValue(LifecycleMessage(ApplicationManage.MessageType.MESSAGE_APP_FORNT))
                    }
                    aliveActivitys++
                }

                ApplicationManage.MessageType.MESSAGE_ACTIVITY_STOP -> {
                    aliveActivitys--
                    if (aliveActivitys == 0 && STAET_CURRENT == STATE_APP_FORNT) {
                        STAET_CURRENT = STATE_APP_BACKGROUD
                        lifecycleManage.lifecycleLivaData.sendValue(LifecycleMessage(ApplicationManage.MessageType.MESSAGE_APP_BACKGROUD))
                    }
                }

                ApplicationManage.MessageType.MESSAGE_ACTIVITY_DESTROYED -> {
                    if (aliveActivitys == 0) {
                        STAET_CURRENT = STATE_APP_NO
                        lifecycleManage.lifecycleLivaData.sendValue(LifecycleMessage(ApplicationManage.MessageType.MESSAGE_APP_EXIT))
                    }
                }
            }
        }
    }

}
複製程式碼
class ExitActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_exit)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        if (intent == null) return

        val action: Int = intent.getIntExtra(ExitMessage.MESSAGE_ACTION, ExitMessage.ACTION_EXIT)
        when (action) {
            ExitMessage.ACTION_EXIT -> this@ExitActivity.finish()
            else -> this@ExitActivity.finish()
        }
    }

}
複製程式碼
class ExitManage {

    fun exitApp(): Boolean {
        if (ApplicationManage.instance.application == null) return false

        var intent = Intent(ApplicationManage.instance.application, ExitActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        ApplicationManage.instance.application?.startActivity(intent)
        return true
    }

    fun exitAppBySystem() {
        System.exit(0)
    }

    fun startActivityProxy(activity: Activity, intentYou: Intent) {
        if (activity == null) return

        var intentExit = Intent(activity, ExitActivity::class.java)
        intentExit.putExtra(ExitMessage.MESSAGE_ACTION, ExitMessage.ACTION_EXIT)

        activity.startActivity(intentExit)
        activity.startActivity(intentYou)
    }

}
複製程式碼
object ExitMessage {
    val MESSAGE_ACTION: String = "message_action"
    val ACTION_EXIT: Int = 101
}
複製程式碼

能看到這裡的都是相當給面子的了~


最後吐槽下吧

鎖屏,解鎖時我即便按照下面的設定設了

android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|keyboardHidden"
複製程式碼

但是蛋疼的有的手機就是不給面子,還是會走1-2遍 activity 銷燬,重建的過程,太蛋疼了,手頭的 meizu 16h就這樣,好在這樣的手機只是少部分,但是帶給我們的影響就是前後臺切換的訊息會走好幾次,這我也沒辦法,昨天下午一下午的時間就是在找資料搞訂這個,一下午的時間過去了也不行,算了就這樣吧,大家記得android 這啃爹玩意完事不是 100% 有些偏差就得了,我監聽鎖屏,解鎖廣播,發現最後才收到廣播,宣告周期函式早就執行完了,廣播才來還有個P用啊

唉,一下午的時間身心俱疲啊~

我知道高玩們是看不上我這篇文章的,不噴我就是好的了,全當是自娛自樂吧

相關文章