欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2016年02月22日 09:13:44   投稿:lijiao  
這篇文章主要為大家詳細(xì)介紹了Android開發(fā)過程中,關(guān)于獲取當(dāng)前Activity的一些思考,感興趣的小伙伴們可以參考一下

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

反射

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

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

一個(gè)使用反射來實(shí)現(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;
}

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

  • 反射通常會(huì)比較慢
  • 不穩(wěn)定性,這個(gè)才是不推薦的原因,Android框架代碼存在修改的可能性,誰要無法100%保證mActivities,paused固定不變。所以可靠性不是完全可靠。

Activity基類

既然反射不是很可靠,那么有一種比較可靠的方式,就是使用Activity基類。

在Activity的onResume方法中,將當(dāng)前的Activity實(shí)例保存到一個(gè)變量中。

public class BaseActivity extends Activity{

  @Override
  protected void onResume() {
    super.onResume();
    MyActivityManager.getInstance().setCurrentActivity(this);
  }
}

然而,這一種方法也不僅完美,因?yàn)檫@種方法是基于約定的,所以必須每個(gè)Activity都繼承BaseActivity,如果一旦出現(xiàn)沒有繼承BaseActivity的就可能有問題。

回調(diào)方法

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

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

So,一個(gè)簡(jiǎn)單的實(shí)現(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ù)設(shè)備都滿足了這個(gè)要求。

為什么是弱引用

可能有人會(huì)帶著疑問看到這里,MyActivityManager是個(gè)什么鬼,好,我們現(xiàn)在看一下這個(gè)類的實(shí)現(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);
  }


}

這個(gè)類,實(shí)現(xiàn)了當(dāng)前Activity的設(shè)置和獲取。

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

其實(shí)最主要的目的就是避免內(nèi)存泄露,因?yàn)槭褂媚J(rèn)的強(qiáng)引用會(huì)導(dǎo)致Activity實(shí)例無法釋放,導(dǎo)致內(nèi)存泄露的出現(xiàn)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Android軟件編程有所幫助。

相關(guān)文章

最新評(píng)論