In the Android development process, we sometimes need to get the current activity instance, such as a pop-up dialog operation, which must be used. about how to achieve by a lot of ideas, which some simple, some complex, here a simple summary of some personal experience.
Reflection
Reflection is a method we often think of, thinking about
- Get all the Activityrecord in the Activitythread
- Getting a status from Activityrecord is not a pause activity and returns
A code that uses reflection to implement is roughly as follows
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 ("Activit
Y ");
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;
}
However, this method is not very recommended, mainly with the following deficiencies:
- Reflection is usually slower
- Instability, this is not recommended for reasons, the Android framework code has the possibility of modification, who can not 100% guarantee mactivities,paused fixed unchanged. So reliability is not completely reliable.
Activity base class
Since reflection is not very reliable, there is a more reliable way to use the activity base class.
In the Onresume method of the activity, the current activity instance is saved to a variable.
public class Baseactivity extends activity{
@Override
protected void Onresume () {
super.onresume ();
Myactivitymanager.getinstance (). setcurrentactivity (this);
}
However, this method is not only perfect, because this method is based on the Convention, so each activity must inherit baseactivity, if there is no inheritance baseactivity may be problematic.
callback method
With the above two methods that are not perfect, there is actually a more convenient way to do it through the callbacks provided by the framework.
Android has introduced a method from API 14, the application Registeractivitylifecyclecallbacks method, that listens to the lifecycle callbacks of all activity, such as onactivitycreated,onactivityresumed and so on.
So, a simple implementation is as follows
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 act ivity) {} @Override public void onactivityresumed (activity activity) {Myactivitymanager.geti
Nstance (). setcurrentactivity (activity); @Override public void onactivitypaused (activity activity) {} @Override public void OnA ctivitystopped {} @Override public void onactivitysaveinstancestate (activity Activ
ity, Bundle outstate) {} @Override public void onactivitydestroyed (activity activity) {}
}); }
}
However, there is no perfect pure, the only regret of this method is that only API 14 is supported. But most of the equipment now meets this requirement.
Why is a weak reference
Maybe someone will come up with a question and see here, Myactivitymanager is a ghost, OK, let's take a look at the implementation of this class now
public class Myactivitymanager {
private static Myactivitymanager sinstance = new Myactivitymanager ();
Private weakreference<activity> scurrentactivityweakref;
Private Myactivitymanager () {
} public
static Myactivitymanager getinstance () {return
sinstance;
}
Getcurrentactivity () {activity
currentactivity = null;
if (scurrentactivityweakref!= null) {
currentactivity = Scurrentactivityweakref.get ();
}
return currentactivity;
}
public void setcurrentactivity {
scurrentactivityweakref = new Weakreference<activity> ( activity);
}
This class, which implements the setup and acquisition of the current activity.
So why use weak references to hold activity instances?
In fact, the main purpose is to avoid memory leaks, because using the default strong reference can cause the activity instance to be unable to release, resulting in memory leaks.
This is the entire content of this article, I hope to learn more about Android software programming help.