发现 Android 活动是不是正在运行
Posted
技术标签:
【中文标题】发现 Android 活动是不是正在运行【英文标题】:Discovering if Android activity is running发现 Android 活动是否正在运行 【发布时间】:2012-05-27 05:33:06 【问题描述】:我正在使用 C2DM,我的 BroadcastReceivers 将 C2DM 事件传播到本地服务。该服务通过将 id 发送到我的网络服务器 pus 来完成注册,它负责让设备知道新消息,但是如果应用程序(其中一个活动)启动,我们希望使用新数据向该活动发送一个意图,所以它可以被更新,如果不是 NotificationManager 用于通知用户。
问题是,如何知道活动正在运行?应用程序对象不是一个选项,因为服务是应用程序的一部分,它显然会出现。在每个应用程序的 onDesroy 中取消注册也不是一个选项,因为它可能发生在方向更改中......
有什么标准的方法来完成它吗?
【问题讨论】:
【参考方案1】:解决方案 1: 您可以使用 ActivityManager 检查 Activity 是否正在运行:
public boolean isActivityRunning()
ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
isActivityFound = false;
for (int i = 0; i < activitys.size(); i++)
if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfocom.example.testapp/com.example.testapp.Your_Activity_Name"))
isActivityFound = true;
return isActivityFound;
需要将权限添加到您的清单..
<uses-permission android:name="android.permission.GET_TASKS"/>
解决方案 2: 您可以在要检查它是否正在运行的活动中使用静态变量,并将其存储在某个位置以便从您的服务或广播接收器访问:
static boolean CurrentlyRunning= false;
public void onStart()
CurrentlyRunning= true; //Store status of Activity somewhere like in shared //preference
public void onStop()
CurrentlyRunning= false;//Store status of Activity somewhere like in shared //preference
我希望这会有所帮助!
【讨论】:
第一种方法看起来很有趣,但我想知道是否有任何活动正在运行,或者更像是我的应用程序是否正在运行(不包括服务)静态方法操作系统不好,因为活动可能有多个实例也许应用程序互斥锁可以解决问题...... 我可能错了,但我认为这只会检查任务中当前的***活动。如果是这样,同一任务中的其他活动(暂停或停止)呢? 不要使用第一种方法。来自 ActivityManager 文档:“注意:此方法仅用于调试和呈现任务管理用户界面。绝不应将其用于应用程序中的核心逻辑,例如根据此处找到的信息决定不同的行为。” 另外,它现在已被弃用和损坏:@deprecated As of LOLLIPOP, this method * is no longer available to third party * applications: the introduction of document-centric recents means * it can leak person information to the caller. For backwards compatibility, * it will still return a small subset of its data: at least the caller's * own tasks, and possibly some other tasks * such as home that are known to not be sensitive
当您运行 BroadcastReceiver / Service 时,解决方案 1 不起作用。该应用程序似乎始终在运行。但是,在尝试了无数其他方法之后,解决方案 2 对我们非常有效。【参考方案2】:
如果您想通过您的活动(如果有任何正在运行)来处理传入的 Google Cloud 消息 (C2DM),或者如果没有活动正在运行,则发出通知,则下一种方法会很有效。
在清单文件中注册一个 BroadcastReceiver。每当应用程序未运行时,此接收器将处理 C2D 消息。在您的活动中以编程方式注册另一个 BroadcastReceiver。该接收器将在活动运行时处理 C2D 消息。
AndoroidManifest.xml
<receiver
android:name=".StaticReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.mypackage" />
</intent-filter>
</receiver>
MyReceiver.java
public class StaticReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
// TODO Trigger a Notification
MyActivity.java
public class MyActivity extends ActionBarActivity
@Override
protected void onResume()
super.onResume();
final IntentFilter filter = new
IntentFilter("com.google.android.c2dm.intent.RECEIVE");
filter.addCategory("com.mypackage");
filter.setPriority(1);
registerReceiver(dynamicReceiver, filter,
"com.google.android.c2dm.permission.SEND", null);
@Override
protected void onPause()
super.onPause();
unregisterReceiver(dynamicReceiver);
private final BroadcastReceiver dynamicReceiver
= new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
// TODO Handle C2DM
// blocks passing broadcast to StaticReceiver instance
abortBroadcast();
;
注意!要先捕获广播,dynamicReceiver IntentFilter 的优先级必须高于 StaticReceiver 实例 IntentFilter 的优先级(默认优先级为 '0')。
PS。看起来 Google Cloud Messaging Service 发出的广播是有序广播。原创创意作者:CommonsWare
【讨论】:
【参考方案3】:复制自here。
您可以在活动中使用静态变量。
class MyActivity extends Activity
static boolean active = false;
public void onStart()
active = true;
public void onStop()
active = false;
【讨论】:
如果您在另一个问题及其答案中找到了完美匹配,您不应该在这里回答,而是将此问题标记为重复...【参考方案4】:检查 Activity 是否正在运行的最简单方法是:
Context context = MyActivity.this;
if (! ((Activity) context).isFinishing())
// Activity is running
else
// Activity has been finished
注意:如果活动未运行,则不应执行任何与 UI 相关的操作。
【讨论】:
当从后台服务发出时,Context context = MyActivity.this;
将导致错误提示 MyActivity“不是封闭类”
好吧,如果您已经持有MyActivity.this
,那么无论如何都有更好/更简单的方法来检查活动状态:D以上是关于发现 Android 活动是不是正在运行的主要内容,如果未能解决你的问题,请参考以下文章