项目中 云信IM同一帐号,在多处登录时,要实现互踢功能。
需求
在收到被踢通知时,弹窗提示用户被踢,点击继续跳转到登录界面,取消则关闭App
分析
由于不知道用户会在哪个界面操作时被踢,接受通知的那个Activity有可能已经失去上下文,导致空指针异常!从而无法 Toast 或 弹窗。
能实现 全局Dialog 就好了!
实现的简单方式
由于退出App的时候,要清除之前所有的Activity,其实就是退出登录功能。
我采用 集合法 来实现的退出登录,在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 中调用 addActivity() ,不在赘述!
如果能获取到用户当前观看的界面,然后将上下文传过去,就可以实现全局Dialog
当前页面也就是栈顶Activity,也就是最后添加的那个Activity。如下:
// 当前Activity也就是栈顶Activity,获取到后以实现 全局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,
是因为弹出Dialog 需要 supportFragmentManager ,Activity 获取不到
以上就可以实现全局Dialog了。
另外,上述Dialog是用DialogFragment写的,感兴趣可阅《DialogFragment 去除内容区棱角背景(不规则圆角)》,附有工具类及用法。
うずまき ナルト
网友评论