国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android開發(fā)中關(guān)于獲取當前Activity的一些思考

2020-04-11 10:46:42
字體:
供稿:網(wǎng)友

在Android開發(fā)過程中,我們有時候需要獲取當前的Activity實例,比如彈出Dialog操作,必須要用到這個。關(guān)于如何實現(xiàn)由很多種思路,這其中有的簡單,有的復雜,這里簡單總結(jié)一下個人的一些經(jīng)驗吧。

反射

反射是我們經(jīng)常會想到的方法,思路大概為

  • 獲取ActivityThread中所有的ActivityRecord
  • 從ActivityRecord中獲取狀態(tài)不是pause的Activity并返回

一個使用反射來實現(xiàn)的代碼大致如下

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;}

然而這種方法并不是很推薦,主要是有以下的不足:

  • 反射通常會比較慢
  • 不穩(wěn)定性,這個才是不推薦的原因,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,如果一旦出現(xiàn)沒有繼承BaseActivity的就可能有問題。

回調(diào)方法

介紹了上面兩種不是盡善盡美的方法,這里實際上還是有一種更便捷的方法,那就是通過Framework提供的回調(diào)來實現(xiàn)。

Android自 API 14開始引入了一個方法,即Application的registerActivityLifecycleCallbacks方法,用來監(jiān)聽所有Activity的生命周期回調(diào),比如onActivityCreated,onActivityResumed等。

So,一個簡單的實現(xiàn)如下

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即其以上。不過還在現(xiàn)在大多數(shù)設備都滿足了這個要求。

為什么是弱引用

可能有人會帶著疑問看到這里,MyActivityManager是個什么鬼,好,我們現(xiàn)在看一下這個類的實現(xiàn)

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);  }}

這個類,實現(xiàn)了當前Activity的設置和獲取。

那么為什么要使用弱引用持有Activity實例呢?

其實最主要的目的就是避免內(nèi)存泄露,因為使用默認的強引用會導致Activity實例無法釋放,導致內(nèi)存泄露的出現(xiàn)。

以上就是本文的全部內(nèi)容,希望對大家學習Android軟件編程有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 屏山县| 长沙市| 开江县| 安多县| 新野县| 阳山县| 北票市| 中方县| 莫力| 沧州市| 抚州市| 揭西县| 曲阜市| 秭归县| 林周县| 来凤县| 吴桥县| 韩城市| 贵溪市| 桑日县| 乐东| 兴业县| 贵阳市| 佛学| 涟源市| 铜梁县| 高雄县| 图们市| 富民县| 米林县| 神木县| 万年县| 桂东县| 封丘县| 论坛| 东丰县| 仁化县| 志丹县| 田东县| 镇平县| 丰县|