application 在之前是很是重要的一個地方,剛開始開發時咱們會在 application 中存儲數據,提供全局公共方法,application 雖然很方便,可是漸漸的咱們仍是放棄了在 application 裏面作其餘的工做,如今 application 主要的應用場景是:java
可是我在使用 application 時仍是遇到了一些問題很差處理:android
我想你們都曾爲了上面的問題煩惱過吧,也許你已經解決了,也許你只是臨時解決了,也許你還沒解決。一樣這也困擾過我,之前我只是臨時解決,代碼耦合難看,還沒發適應愈來愈高的複用要求,一處該,到處動,這樣的代碼不是我想要的,早就該掃到垃圾箱裏去了,因而誕生了今天的文章git
我對 application 是這樣安排的:github
話說官方的 Lifecycle 剛出來時我是很是興奮的,我想這下 app 的生命週期該好用了吧,興奮的我一看官方壓根就沒動 application,只是把 Activity 的聲明周期函數響應式化了,我是很失望的,也許 google 考慮兼容性吧面試
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") } })
跟進源碼看看app
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { synchronized (mActivityLifecycleCallbacks) { mActivityLifecycleCallbacks.add(callback); } }
注意看是 add 方法,這說明啥,這說明 ActivityLifecycleCallbacks 咱們能夠添加多個,Activity 會在相應的生命週期函數中發射相關消息ide
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 組件的基石
我就不畫 UML 類圖,由於很簡單
考慮到我要在 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") } } }
我我的是很喜歡 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 也是這個思路作的
我想你們都關心這個,相信你們也都有本身的實現,基本思路都是在 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
判斷邏輯以下:
注意:onActivityStarted 這個函數即表示 onStart,也表示 onRestart ,因此在計數時要更外當心,由於 start 的緣由 oncreate 不適合計數器++了,要不會和 start 重複
這樣咱們也能夠返回 app 當前的狀態了,不用再用 AM 來判斷了,AM 不少人反應部分手機無效,其實返回 app 狀態的這個小功能很是實用的,在推送時咱們要判斷 app 是否是啓來了,由於由不一樣的操做
我這裏思路很簡單,就是主界面下面墊一個透明無界面的 Activity,咱們想退出 app 時啓動這個 Activity,在 onNewIntent 裏面 finish 頁面就好了,不過這個功能有侵入行:
// 退出 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用啊
唉,一下午的時間身心俱疲啊~
以爲有幫助的話你們點點喜歡支持一下