现在的位置: 首页 > 编程技术 > Java > 编程技术 > 安卓开发 > 正文

一个单例菊花引起的八阿哥

2015年09月09日 Java, 安卓开发 ⁄ 共 1404字 ⁄ 字号 一个单例菊花引起的八阿哥已关闭评论 ⁄ 阅读 378 次

之前公司的项目,想让所有的网络请求在请求过程中时自动加上菊花dialog(看看手机qq里面的那些菊花loading就知道了),于是乎写了一个单例

	public static synchronized CPDSingleton getInstance(Context context) {
		if (mInstance == null) {
			mInstance = new CPDSingleton(context);
		} else if (!context.getClass().equals(mCtx.getClass())) {
			if (cpd.isShowing()) {
				cpd.dismiss();
				atomicInteger.getAndSet(0);
			}
			mInstance = new CPDSingleton(context);
		}
//		else if (context != mCtx) {
//			if (cpd.isShowing()) {
//				cpd.dismiss();
//				atomicInteger.getAndSet(0);
//			}
//			mInstance = new CPDSingleton(context);
//		}
		return mInstance;
	}

在这个单例模式中需要判断是不是当前的activity发起的,不是当前的activity发起的就要新建一个菊花,所以这里用了

!context.getClass().equals(mCtx.getClass())

来判断,结果这个bug隐藏非常深。在显示菊花的时候有时候会爆出Unable to add window -- token android.os.BinderProxy@53850f4c is not valid; is your activity running?于是乎在stackoverflow上找了找,做了一个running判断,暂时不会崩溃了。

if(!((Activity) context).isFinishing())
{
    //show dialog
}

但是在原来崩溃的activity的菊花不会再出现了。这个bug当时初步解决了,一概而过以为是fragment的生命周期引起的,直到现在在总结fragment的特点时,为了模拟这个bug才发现根本不是之前那样想的。

上面的判断是否是同一个activity的方法,只能判断出是否是一个类,不能说明是同一个activity,所以当一个activity被back返回到一个没有菊花的页面再进去之时,就会出现是同一个类,但是不是同一个activity的情况(之前的activity已经被finish),但是拿着以前已经结束的activity构造的菊花来显示,显然会爆出is your activity running?这句话,并且还会引起内存泄漏。

解决的办法如果你看得仔细的话,应该也看出来了,就是最初的那段代码中注释的

		else if (context != mCtx) {
			if (cpd.isShowing()) {
				cpd.dismiss();
				atomicInteger.getAndSet(0);
			}
			mInstance = new CPDSingleton(context);
		}

用==和!=来验证内存地址是否一样。最后,重要的事情说一遍就是"=="判断的是不是同一个(内存地址是否一样)而"equals"判断是的object的内容是否一样,比如两个小米4手机可以用equals而不能用==,同一个小米4手机才可以用==。

抱歉!评论已关闭.