Android开发中关于获取当前Activity的一些思考
在android开发过程中,我们有时候需要获取当前的activity实例,比如弹出dialog操作,必须要用到这个。关于如何实现由很多种思路,这其中有的简单,有的复杂,这里简单总结一下个人的一些经验吧。
反射
反射是我们经常会想到的方法,思路大概为
- 获取activitythread中所有的activityrecord
- 从activityrecord中获取状态不是pause的activity并返回
一个使用反射来实现的代码大致如下
public static activity getactivity() { class activitythreadclass = null; try { activitythreadclass = class.forname("android.app.activitythread"); object activitythread = activitythreadclass.getmethod("currentactivitythread").invoke(null); field activitiesfield = activitythreadclass.getdeclaredfield("mactivities"); activitiesfield.setaccessible(true); map activities = (map) activitiesfield.get(activitythread); for (object activityrecord : activities.values()) { class activityrecordclass = activityrecord.getclass(); field pausedfield = activityrecordclass.getdeclaredfield("paused"); pausedfield.setaccessible(true); if (!pausedfield.getboolean(activityrecord)) { field activityfield = activityrecordclass.getdeclaredfield("activity"); activityfield.setaccessible(true); activity activity = (activity) activityfield.get(activityrecord); return activity; } } } catch (classnotfoundexception e) { e.printstacktrace(); } catch (nosuchmethodexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } catch (invocationtargetexception e) { e.printstacktrace(); } catch (nosuchfieldexception e) { e.printstacktrace(); } return null; }
然而这种方法并不是很推荐,主要是有以下的不足:
- 反射通常会比较慢
- 不稳定性,这个才是不推荐的原因,android框架代码存在修改的可能性,谁要无法100%保证mactivities,paused固定不变。所以可靠性不是完全可靠。
activity基类
既然反射不是很可靠,那么有一种比较可靠的方式,就是使用activity基类。
在activity的onresume方法中,将当前的activity实例保存到一个变量中。
public class baseactivity extends activity{ @override protected void onresume() { super.onresume(); myactivitymanager.getinstance().setcurrentactivity(this); } }
然而,这一种方法也不仅完美,因为这种方法是基于约定的,所以必须每个activity都继承baseactivity,如果一旦出现没有继承baseactivity的就可能有问题。
回调方法
介绍了上面两种不是尽善尽美的方法,这里实际上还是有一种更便捷的方法,那就是通过framework提供的回调来实现。
android自 api 14开始引入了一个方法,即application的registeractivitylifecyclecallbacks方法,用来监听所有activity的生命周期回调,比如onactivitycreated,onactivityresumed等。
so,一个简单的实现如下
public class myapplication extends application { @override public void oncreate() { super.oncreate(); registeractivitylifecyclecallbacks(new activitylifecyclecallbacks() { @override public void onactivitycreated(activity activity, bundle savedinstancestate) { } @override public void onactivitystarted(activity activity) { } @override public void onactivityresumed(activity activity) { myactivitymanager.getinstance().setcurrentactivity(activity); } @override public void onactivitypaused(activity activity) { } @override public void onactivitystopped(activity activity) { } @override public void onactivitysaveinstancestate(activity activity, bundle outstate) { } @override public void onactivitydestroyed(activity activity) { } }); } }
然而,金无足赤人无完人,这种方法唯一的遗憾就是只支持api 14即其以上。不过还在现在大多数设备都满足了这个要求。
为什么是弱引用
可能有人会带着疑问看到这里,myactivitymanager是个什么鬼,好,我们现在看一下这个类的实现
public class myactivitymanager { private static myactivitymanager sinstance = new myactivitymanager(); private weakreference<activity> scurrentactivityweakref; private myactivitymanager() { } public static myactivitymanager getinstance() { return sinstance; } public activity getcurrentactivity() { activity currentactivity = null; if (scurrentactivityweakref != null) { currentactivity = scurrentactivityweakref.get(); } return currentactivity; } public void setcurrentactivity(activity activity) { scurrentactivityweakref = new weakreference<activity>(activity); } }
这个类,实现了当前activity的设置和获取。
那么为什么要使用弱引用持有activity实例呢?
其实最主要的目的就是避免内存泄露,因为使用默认的强引用会导致activity实例无法释放,导致内存泄露的出现。
以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。
上一篇: java字符串反转示例分享