判断context是否存活

今天给大家带来这篇文章,应该说是一个工具类。写这个方法的目的也顺便说明一下。这个是一个困扰了我很久,而且到目前也没有完全解决的问题。

# main(1)

android.view.WindowManager$BadTokenException

Unable to add window -- token android.os.BinderProxy@39ef5143 is not valid; is your activity running? This Crash Caused By ANR , PLS To Fix ANR , This Trace May Be Not Useful![Bugly]

BadTokenException这个Bug,Bugly上没有明确的显示具体是哪个控件在什么情况下调用的时候,抛出了这个Bug。最开始频繁抛出这个bug。由于App中实在是有太多太多的

dialog, windowManager, dialogFragment的调用。唯一能做的就是给所有弹框在调用的时候,增加一个保护,判断context是否存活,如果存活则继续调用。否则不弹出。

下面是判断一个context是否存活。我们一般在调用的时候有三种情况,

1.上下文是一个Activity,我一开始是用context == null 来判断。我觉得context == null 就能很好的判断出来。后来我边上的大神和我说,Java的垃圾回收机制无法保证即使的回收,也有可能会有时间差。可能一个Activity已经被destroy了,但是没有被JC及时回收,所以判断为非空。一般判断的时候Activity用context.isFinishing()会比较好。所以我又改成了现在的代码。

2.上下文是一个Service,这个就没有像Activity一样有直接的方法判断。后来经过我的研究(其实就是谷歌,百度一通搜索。。- -!) 下面 isServiceExisted 这个方法,通过判断现在运行的服务是否存活。来判断。

3.还有一种上下文Application,这个是我当时写的Bug。哈哈。一开始没考虑到Application。也是一脸懵逼。这个竟然会没考虑到。罪过罪过。然后导致项目中,就是无法弹出很多提示。然后一次次的检查代码。这个过程真的很痛苦哦。所以小伙伴们在写代码的时候,一定要考虑周到。等代码写完了,再回头看代码。MB这是谁写的代码啊,这代码什么时候写的啊,就会有各种问题。具体就不多说了。反正就是一个教训。


public static boolean isServiceExisted(Context context, String className) {
    ActivityManager activityManager = (ActivityManager) context
            .getSystemService(Context.ACTIVITY_SERVICE);
    List serviceList = activityManager
            .getRunningServices(Integer.MAX_VALUE);

    if (!(serviceList.size() > 0)) {
        return false;
    }

    for (int i = 0; i < serviceList.size(); i++) {
        ActivityManager.RunningServiceInfo serviceInfo = serviceList.get(i);
        ComponentName serviceName = serviceInfo.service;

        if (serviceName.getClassName().equals(className)) {
            return true;
        }
    }
    return false;
}
public static boolean isContextExisted(Context context) {
    if (context != null) {
        if (context instanceof Activity) {
            if (!((Activity)context).isFinishing()) {
                return true;
            }
        } else if (context instanceof Service) {
            if (isServiceExisted(context, context.getClass().getName())) {
                return true;
            }
        } else if (context instanceof Application) {
            return true;
        }
    }
    return false;
}

好了。通过调用方法,直接判断Context是否存活。也大大的降低了bugly上 这个 badToken的bug。然而没有完全解决。因为代码中的弹框提示什么太多太多了。说不定哪里漏了,就可能存在隐患。反正就是写代码之前如果全部做好各种判断,就不会有后期这种纠结的找bug,加保护的操作了。

你可能感兴趣的:(判断context是否存活)