iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android开发中关于获取当前Activity的一些思考
  • 632
分享到

Android开发中关于获取当前Activity的一些思考

activityandroid开发Android 2022-06-06 08:06:56 632人浏览 八月长安
摘要

在Android开发过程中,我们有时候需要获取当前的Activity实例,比如弹出Dialog操作,必须要用到这个。关于如何实现由很多种思路,这其中有的简单,有的复杂,这里简单

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:如何编写“万能”的ActivityAndroid中fragment与activity之间的交互(两种实现方式)Android activity堆栈及管理实例详解Android实现Activity水平和垂直滚动条的方法Android开发中Activity创建跳转及传值的方法Android实现在子线程中更新Activity中UI的方法详解Android开发中Activity的四种launchModeAndroid判断Activity是否在最上层的方法Android编程中activity启动时出现白屏、黑屏问题的解决方法Android:“万能”Activity重构篇


--结束END--

本文标题: Android开发中关于获取当前Activity的一些思考

本文链接: https://www.lsjlt.com/news/25601.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • android adb命令获取处于当前屏幕的Activity
    android adb命令获取处于当前屏幕的Activity 使用adb命令: adb shell dumpsys activity activities   输出,例如: ACTIVITY MANAGER ACTIVITIES (du...
    99+
    2023-10-22
    android adb
  • Android开发中怎么获取浏览器当前页面的截图
    这期内容当中小编将会给大家带来有关Android开发中怎么获取浏览器当前页面的截图,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先,新建一个 BrowserScreenShotActivity.java...
    99+
    2023-05-31
    android roi
  • 关于vuex更新视图引发的一些思考详析
    目录场景解决总结扩展vuex可以集中式存储管理应用的所有组件的状态,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高...
    99+
    2024-04-02
  • 小程序开发中如何获取当前的地理位置、速度
    这篇文章主要为大家展示了小程序开发中如何获取当前的地理位置、速度,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“小程序开发中如何获取当前的地理位置、速度”这篇文章吧。获取当前的地理位置、速度。当用户...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作