Android - 动态获取当前前台活动的方法

11

情况如下:

  1. 在一个线程中触发了一个事件。
  2. 需要检索当前的活动(activity)。
  3. 然后在该活动上创建并显示对话框。

问题: 根据我所查找到的,目前没有办法获取前台活动。

额外信息: 这需要能够在多个活动中处理。因此,它可以在Activity-A、B或C中弹出。


可能是重复的问题:如何获取顶层活动的任何标识符? - sschuberth
http://stackoverflow.com/a/28423385/185022 - AZ_
可能是如何在Android中获取当前前台活动上下文?的重复问题。 - Alessandro Muzzi
6个回答

16

我不确定这是否是你在寻找的内容,但它看起来相当简单明了。 http://iamvijayakumar.blogspot.com/2011/09/get-current-activity-and-package-name.html

  ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
  List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
  ComponentName componentInfo = taskInfo.get(0).topActivity;
  Log.d(WebServiceHelper.TAG, "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName()+"   Package Name :  "+componentInfo.getPackageName());

希望这有所帮助。


14
需要注意的是,为了使此功能正常工作,您需要请求android.permission.GET_TASKS权限。 - acrespo
想知道访问那个会不会导致应用被拒绝? - rishabh
10
注意,这个功能自API 21棒棒糖版本以来已被弃用。 - lage
6
这不仅在Android 5中被弃用,而且[http://developer.android.com/reference/android/app/ActivityManager.html#getRunningTasks(int)](文档)暗示它甚至不会起作用。 - Sam
有没有其他方法可以在Android 5以上的版本中实现? - RATHI

6
计划A: 按照您的请求字面意思进行处理
步骤1:让线程由服务来管理
步骤2:当“事件被触发”时,让服务发送一条消息--使用LocalBroadcastManager、Square的Otto、greenrobot的EventBus等。
步骤3:使每个活动在前台时都设置为监听该消息
步骤4:收到消息后,让活动显示对话框
计划B: 同样的视觉效果
步骤1:让线程由服务来管理
步骤2:让服务在对话框主题的活动上调用startActivity() 步骤3:没有第三步

太好了,两个计划中的第二步都完成了!但是为什么第一步(使用服务)很重要,而不是例如使用AsyncTask? - LarsH
1
@LarsH:如果后台工作持续时间足够长,以至于您不知道前台UI是什么(甚至不知道它是否在您自己的应用程序中),那么您可能需要一个服务,只是为了向Android发出信号,告诉它您正在进行后台工作,以便您的进程可以存活更长时间。 - CommonsWare
1
@RaghubanshMani:在您的情况下,您可以使用计划A。在“onStart()”中注册活动以接收事件,并在“onStop()”中注销。当前可见的任何活动都将处理该事件。 - CommonsWare
@RaghubanshMani:在事件总线上注册相当便宜,如果您已经有一个BaseActivity,在那里注册似乎是一个好计划。我不知道我是否会仅仅为了两行代码而引入一个公共超类,但如果您已经有这样的超类,请使用它。 - CommonsWare
我确实有一个BaseActivity超类。但是我不确定是否应该将这样的代码放在那里。我创建这样的基类的目的是为了提供所有子类都会使用的通用帮助方法,例如片段事务、资源访问等。我不喜欢在那里放置行为逻辑,因为我很少打开这样的文件。它很容易成为新子类中不需要的功能。这只是我的个人偏好——将行为代码放在眼前。 - Raghubansh Mani
显示剩余2条评论

0
您可以使用自定义广播接收器来实现此功能。您可以在线程中定义广播接收器,并在不同的活动中编写接收器。从您的线程中,您可以决定发送广播到哪个活动。
在接收器中,您可以显示对话框。

0

哈哈,这种方法完全等同于将当前Activity存储在静态变量中。 - zapl
不,得分最高的答案没有使用静态变量。 - frogmanx
不过它使用应用程序来引用活动。应用程序永远不会被垃圾回收,因此当从应用程序引用时,活动也永远不会被垃圾回收。这相当于使用静态变量,因为它们是从其“类”对象引用的,该对象也永远不会被垃圾回收。 - zapl
是的,我不会完全按照相同的方式进行操作,因为有一种更清洁和内存高效的方法来完成相同的任务。但是变量在onPause时被置空,所以它应该仍然被垃圾回收。 - frogmanx
如果你在onPause中将它们置空,那么你也可以使用静态变量 :) 如果你不能保证这种情况发生,那么无论如何都会出现泄漏。唯一能做的事情(也许应该做的事情)是保持对它们的WeakReference。它们保证在Activity调用onDestroy之后才被GC回收。 - zapl

0

使用Facebook的stetho包对我来说是最安全和最简单的方式(而且没有其他团队成员抱怨“这很hacky,我们不会批准!”之类的事情...)

就像这样简单:

ActivityTracker.get().tryGetTopActivity();


0

就像@Xian Zhang所说的那样,使用Facebook stetho库对我很有效。

ActivityTracker.get().tryGetTopActivity()?.localClassName

如果你的活动在 ui 包内,输出将会像这样
    ui.YourActivityName

您的应用程序包名称将不会被包含在内


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接