項(xiàng)目中 云信IM同一帳號(hào)仓蛆,在多處登錄時(shí),要實(shí)現(xiàn)互踢功能募胃。
需求
在收到被踢通知時(shí),彈窗提示用戶被踢畦浓,點(diǎn)擊繼續(xù)跳轉(zhuǎn)到登錄界面痹束,取消則關(guān)閉App
分析
由于不知道用戶會(huì)在哪個(gè)界面操作時(shí)被踢,接受通知的那個(gè)Activity有可能已經(jīng)失去上下文讶请,導(dǎo)致空指針異常祷嘶!從而無法 Toast 或 彈窗屎媳。
能實(shí)現(xiàn) 全局Dialog 就好了!
實(shí)現(xiàn)的簡單方式
由于退出App的時(shí)候论巍,要清除之前所有的Activity烛谊,其實(shí)就是退出登錄功能。
我采用 集合法 來實(shí)現(xiàn)的退出登錄嘉汰,在BaseActivity中記錄所有打開過的Activity丹禀,然后遍歷清除。
/**
* <pre>
* author : jake
* time : 2018/03/23
* function : App
* version: 1.0
* </pre>
*/
class RiseApp : MultiDexApplication() {
lateinit var activities: ArrayList<Activity>
companion object {
var mContext: RiseApp? = null
fun getInstance(): RiseApp {
return mContext!!
}
}
fun addActivity(activity: Activity) {
activities.add(activity)
}
fun clearActivity() {
activities.forEach {
it.finish()
}
activities.clear()
}
}
然后在 BaseActivity 中調(diào)用 addActivity() 鞋怀,不在贅述双泪!
如果能獲取到用戶當(dāng)前觀看的界面,然后將上下文傳過去密似,就可以實(shí)現(xiàn)全局Dialog
當(dāng)前頁面也就是棧頂Activity焙矛,也就是最后添加的那個(gè)Activity。如下:
// 當(dāng)前Activity也就是棧頂Activity辛友,獲取到后以實(shí)現(xiàn) 全局dialog
fun currentActivity(): AppCompatActivity {
return activities[activities.lastIndex] as AppCompatActivity
}
然后在使用的地方獲取
NIMClient.getService(AuthServiceObserver::class.java).observeOnlineStatus(object : Observer<StatusCode> {
override fun onEvent(status: StatusCode?) {
status?.let {
if (it.shouldReLogin()){
initIMLogin()
}else if (status.wontAutoLogin()){
exitDialog.show(RiseApp.getInstance().currentActivity().supportFragmentManager) {
loginOut()
}
}
}
}
}, true)
即:
exitDialog.show(RiseApp.getInstance().currentActivity().supportFragmentManager) {
loginOut()
}
注意:之所以返回AppCompatActivity薄扁,而不是Activity,
是因?yàn)閺棾鯠ialog 需要 supportFragmentManager 废累,Activity 獲取不到
以上就可以實(shí)現(xiàn)全局Dialog了邓梅。
另外,上述Dialog是用DialogFragment寫的邑滨,感興趣可閱《DialogFragment 去除內(nèi)容區(qū)棱角背景(不規(guī)則圓角)》日缨,附有工具類及用法。