Android: 如何检查活动是否正在运行?

有没有什么简单的方法可以确定某个活动是否处于活动状态? 我想做某些事情取决于哪个活动是活跃的。 例如:

if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
319292 次浏览

这是用于检查特定服务是否正在运行的代码。我相当肯定,只要用 getRunningAppProcessions ()或 getRunningTasks ()更改 getRunningServices,它也可以为某个活动工作。看看这里 http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()

相应地更改 Constants.PackAGE 和 Constants.Background _ SERVICE _ Class

    public static boolean isServiceRunning(Context context) {


Log.i(TAG, "Checking if service is running");


ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);


List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);


boolean isServiceFound = false;


for (int i = 0; i < services.size(); i++) {


if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){


if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){
isServiceFound = true;
}
}
}


Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running");


return isServiceFound;


}

您可以在活动中使用 static变量。

class MyActivity extends Activity {
static boolean active = false;


@Override
public void onStart() {
super.onStart();
active = true;
}


@Override
public void onStop() {
super.onStop();
active = false;
}
}

唯一的问题是,如果在两个相互链接的活动中使用它,那么第一个活动中的 onStop有时会在第二个活动中的 onStart之后调用。因此,这两种情况可能短暂地都是正确的。

取决于您试图做什么(从服务更新当前活动?).您只需在活动 onStart方法中在服务中注册一个静态侦听器,那么当您的服务想要更新 UI 时,正确的侦听器将可用。

谢谢 kkudi!我把你的答案改编成了一个活动... 这是我的应用程序的工作原理。.

public boolean isServiceRunning() {


ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) {
isServiceFound = true;
}
}
return isServiceFound;
}

如果 topActivity 匹配用户正在做的事情,这个示例将给出 true 或 false。因此,如果您检查的活动没有显示出来(例如,onPuse) ,那么您将不会得到匹配。此外,要做到这一点,您需要将权限添加到您的清单。.

<uses-permission  android:name="android.permission.GET_TASKS"/>

我希望这对你有帮助!

我想更清楚的是:

  public boolean isRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);


for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
return true;
}


return false;
}

有一种比上述所有方法都要简单得多的方法,这种方法不需要在清单中使用 android.permission.GET_TASKS,也不需要在已接受的答案中指出竞态条件或内存泄漏的问题。

  1. 在主活动中创建一个 STATIC 变量。静态允许其他活动从另一个活动接收数据。onPause()设置这个变量 假的onResumeonCreate()设置这个变量 没错

    private static boolean mainActivityIsOpen;
    
  2. Assign getters and setters of this variable.

    public static boolean mainActivityIsOpen() {
    return mainActivityIsOpen;
    }
    
    
    public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
    DayView.mainActivityIsOpen = mainActivityIsOpen;
    }
    
  3. And then from another activity or Service

    if (MainActivity.mainActivityIsOpen() == false)
    {
    //do something
    }
    else if(MainActivity.mainActivityIsOpen() == true)
    {//or just else. . . ( or else if, does't matter)
    //do something
    }
    

我使用 MyActivity.class 和 getCanonicalName 方法得到了答案。

protected Boolean isActivityRunning(Class activityClass)
{
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);


for (ActivityManager.RunningTaskInfo task : tasks) {
if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
return true;
}


return false;
}

不知道这是不是一种“正确”的“做事”的方式。
如果没有 API 来解决这个(或 a)问题,那么你可能做错了一些事情,而是阅读了更多的文档等等。
(据我所知,在 android 中静态变量是一种常见的错误方式。当然,它可以工作,但肯定会有情况下,当它不工作(例如,在生产,在百万设备))。
正是在你的情况下,我建议认为 为什么你需要知道,如果另一个活动是活的吗?..您可以启动另一个结果活动以获得其功能。或者,您可以派生该类以获得其功能,依此类推。
最好的问候。

如果你对这个活动的特定实例的生命周期状态感兴趣,那么 Silicon oneagle 的解决方案看起来是正确的,除了新的“活动”变量应该是一个实例变量,而不是静态的。

这比使用静态变量和遵循 OOP 要好得多

Shared Preferences可以用来与其他 activities共享变量和来自一个 application的服务

    public class example extends Activity {


@Override
protected void onStart() {
super.onStart();


// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", true);
ed.commit();
}


@Override
protected void onStop() {
super.onStop();


// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", false);
ed.commit();


}
}

使用共享首选项。它拥有最可靠的状态信息,更少的应用程序切换/破坏问题,节省了我们请求另一个权限的时间,并且它给了我们更多的控制权来决定何时我们的活动实际上是最重要的。见 详情请浏览此网页这里也有

使用有序广播。请参阅 http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html

在活动中,在 onStart 中注册一个接收器,在 onStop 中取消注册。现在,例如,当服务需要处理活动可能能够做得更好的事情时,从服务发送一个有序的广播(在服务本身中使用默认处理程序)。您现在可以在活动运行时在活动中响应。服务可以检查结果数据,以查看是否处理了广播,以及是否采取了适当的操作。

不使用辅助变量的选项是:

activity.getWindow().getDecorView().getRootView().isShown()

其中活动是 FE: this 或 getActivity ()。

该表达式返回的值在 onStart ()/onStop ()中更改,这些事件开始/停止显示手机上活动的布局。

除了 公认的答案之外,如果您有该活动的多个实例,则可以使用计数器来处理多个实例:

class MyActivity extends Activity {


static int activeInstances = 0;


static boolean isActive() {
return (activeInstances > 0);
}


@Override
public void onStart() {
super.onStart();
activeInstances++;
}


@Override
public void onStop() {
super.onStop();
activeInstances--;
}
}

我使用了检查 if (!a.isFinishing())和它似乎做我需要的。a是活动实例。是不是这样?为什么没人这么做?

使用下面的代码找到了一个简单的解决方案

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
// Activity is being brought to front and not being  created again,
// Thus finishing this activity will bring the last viewed activity to foreground
finish();
}
}

我认为接受的答案是一种糟糕的处理方式。

我不知道这个用例是什么,但是请考虑基类中的一个受保护的方法

@protected
void doSomething() {
}

并在派生类中重写它。

当事件发生时,只需在基类中调用此方法。然后,正确的“活动”类将处理它。然后该类本身可以检查它是否不是 Paused()

更好的方法是使用像 绿色机器人正方形这样的事件总线,但是这种总线不被推荐,建议使用 RxJava

ActivityLificycleCallback 是跟踪应用程序中所有活动的一个很好的方法:

public class BaseActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {


private ActivityState homeState, contentState;


@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.CREATED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.CREATED;
}
}


@Override
public void onActivityStarted(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STARTED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STARTED;
}
}


@Override
public void onActivityResumed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.RESUMED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.RESUMED;
}
}


@Override
public void onActivityPaused(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.PAUSED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.PAUSED;
}
}


@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STOPPED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STOPPED;
}
}


@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}


@Override
public void onActivityDestroyed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.DESTROYED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.DESTROYED;
}
}


public ActivityState getHomeState() {
return homeState;
}


public ActivityState getContentState() {
return contentState;
}
}

活动状态:

public enum ActivityState {
CREATED, STARTED, RESUMED, PAUSED, STOPPED, DESTROYED;
}

扩展 Application 类并在 Android Manifest 文件中提供其引用:

import android.app.Application;


public final class BaseApplication extends Application {
private BaseActivityLifecycleCallbacks baseALC;


@Override
public void onCreate() {
super.onCreate();
baseALC = new BaseActivityLifecycleCallbacks();
this.registerActivityLifecycleCallbacks(baseALC);


}


public BaseActivityLifecycleCallbacks getBaseALC() {
return baseALC;
}
}

从活动中检查任何地方其他活动的状态:

private void checkAndLaunchHomeScreen() {
Application application = getApplication();
if (application instanceof BaseApplication) {
BaseApplication baseApplication = (BaseApplication) application;
if (baseApplication.getBaseALC().getHomeState() == null || baseApplication.getBaseALC().getHomeState() == ActivityState.DESTROYED) {
//Do anything you want
}
}
}

Https://developer.android.com/reference/android/app/application

activity.isFinishing()

如果在前景中没有相同的活动,那么可以这样做。 如果你从通知打开不工作,我做了一些调整,随之而来的是:

public static boolean ativo = false;
public static int counter = 0;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
counter++;
}


@Override
protected void onStart() {
super.onStart();
ativo = true;
}


@Override
protected void onStop() {
super.onStop();
if (counter==1) ativo = false;
}


@Override
protected void onDestroy() {
counter--;
super.onDestroy();
}

对我来说,同时打开几个活动就可以了。

if(!activity.isFinishing() && !activity.isDestroyed())

官方文件显示:

活动 # 正在完成()

检查这个活动是否正在完成过程中,要么是因为您在它上面调用了 Finish () ,要么是因为其他人请求它已经完成。这通常在 onPuse ()中使用,以确定活动是简单暂停还是完全结束。

活动 # 被摧毁()

如果已经对 Activity 进行了最后的 onDestroy ()调用,则返回 true,因此此实例现在已死亡。

使用 isActivity 变量检查 activity 是否活动。

private boolean activityState = true;


@Override
protected void onDestroy() {
super.onDestroy();
activityState = false;
}

那就检查一下

if(activityState){
//add your code
}

你有没有试过。

    if (getActivity() instanceof NameOfYourActivity){
//Do something
}

我知道这个问题已经很老了,但我认为还是值得分享我的解决方案,因为它可能对其他人有用。

在 Android 架构组件发布之前,这个解决方案是不可用的。

活动至少部分可见

getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)

前景是活跃的

getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)

如果您想检查该活动是否在后面的堆栈中,只需按照下面的步骤操作。 在 Application 类中声明一个 ArrayList [ Application 类在 Application 标记中的 mainfest 文件中定义]

private ArrayList<Class> runningActivities = new ArrayList<>();
  1. 并添加以下公共方法以访问和修改此列表。

    public void addActivityToRunningActivityies (Class cls) {
    if (!runningActivities.contains(cls)) runningActivities.add(cls);
    }
    
    
    public void removeActivityFromRunningActivities (Class cls) {
    if (runningActivities.contains(cls)) runningActivities.remove(cls);
    }
    
    
    public boolean isActivityInBackStack (Class cls) {
    return runningActivities.contains(cls);
    }
    
  2. In your BaseActivity, where all activities extend it, override onCreate and onDestroy methods so you can add and remove activities from back stack as the following.

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    
    ((MyApplicationClass)getApplication()).addActivityToRunningActivityies
    (this.getClass());
    }
    
    
    @Override
    protected void onDestroy() {
    super.onDestroy();
    
    
    ((MyApplicationClass)getApplication()).removeActivityFromRunningActivities
    (this.getClass());
    }
    
  3. Finally if you want to check whether the activity is in the back stack or not just call this function isActivityInBackStack.

Ex: I want to check if the HomeActivityis in the back stack or not:

if (((MyApplicationClass)
getApplication()).isActivityInBackStack(HomeActivity.class)) {
// Activity is in the back stack
} else {
// Activity is not in the back stack
}
public static boolean isActivityActive(Activity activity) {
if (null != activity)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
return !activity.isFinishing() && !activity.isDestroyed();
else return !activity.isFinishing();
return false;
}

我使用的是 task.topActivity 而不是 task.baseActivity,它很适合我。

   protected Boolean isNotificationActivityRunning() {
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);


for (ActivityManager.RunningTaskInfo task : tasks) {
if (task.topActivity.getClassName().equals(NotificationsActivity.class.getCanonicalName()))
return true;
}


return false;
}

我知道这个问题很老了,有很多不同的答案,有各种各样的优点和缺点。我的看法是,为什么不推出自己的 IPC 实现呢。

class IPC {


companion object {
private val appContext : Context by lazy { /*genericApplicationContext*/ }


fun initIPC(process: String){
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
var output : OutputStream? = null
try {
output = FileOutputStream(file!!)
output.write(0)
} finally {
output?.close()
}
}


fun destroyIPC(process: String){
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
file.delete()
}


fun checkForIPC(process: String) : Boolean {
var file : File? = null
file = File(appContext.cacheDir.absolutePath + "/$process")
if(file.exists()) return true
return false
}
}


}

这允许您在启动活动之前创建文件,然后在关闭启动的活动时关闭“ process/file”。如果您的“进程活动”在后台,这允许您检查后台线程或当前活动,以查看文件是否仍然打开,表明该活动是活动。在我的例子中,我连续调用一个外部 API,但是需要对调用进行评分,所以使用这个来确保每次只有一个活动活跃地调用这些 API。

这就是我想出来的用来帮助跟踪不同活动的方法,这些活动的类都是从基本的“ helper”类派生出来的。

protected static Dictionary<string, bool> _activityInstances = new Dictionary<string, bool>();
protected static Dictionary<string, bool> _activitiesVisible = new Dictionary<string, bool>();
        

protected override void OnStart()
{
base.OnStart();
_activityInstances[this.GetType().Name] = true;
}


protected override void OnDestroy()
{
_activityInstances[this.GetType().Name] = false;
base.OnDestroy();
}


protected override void OnResume()
{
base.OnResume();
_activitiesVisible[this.GetType().Name] = true;
}


protected override void OnPause()
{
_activitiesVisible[this.GetType().Name] = false;
base.OnPause();
}


public static bool activityIsInstanced(string type)
{
return _activityInstances.ContainsKey(type) ? _activityInstances[type] : false;
}


public static bool activityIsVisible(string type)
{
return _activitiesVisible.ContainsKey(type) ? _activityInstances[type] : false;
}

它是可以继承的,但是为了运行一个测试(例如,在启动一个特定活动的新副本之前) ,你需要使用类的名称调用静态方法,例如。

    if (!SettingsEdit.activityIsInstanced("SettingsEdit"))
{
Intent intent = new Intent(this, typeof(SettingsEdit));
Bundle bundle = new Bundle();
bundle.PutString(MY_SETTING, this.someSetting);
intent.PutExtras(bundle);
this.StartActivityForResult(intent, 0);
}

如果这对谁有帮助的话,我想我应该在这里分享。