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


152

有没有简单的方法来确定某个活动是否活跃?我想根据正在进行的活动来做某些事情。例如:

if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else

要检查某个活动是否正在运行,您可以通过以下答案进行检查:stackoverflow.com/a/39079627/4531507
Rahul Sharma

Answers:


227

您可以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时正确的侦听器将可用。


5
有人向我指出:由于内存泄漏问题,.sharedpreference应该比静态变量更可取。
Ayush Goyal

13
如果同一班上有不同的活动在运行,该怎么办?如果您MyActivityMyChildactivity孩子接触并想检查孩子是否活跃,该怎么办?
史密斯先生

2
根据您对“运行”的定义,您可能需要更改onResume和onPause中变量的状态...
G. Blake Meike 2014年

5
这个解决方案根本不是一个好的解决方案。假设您的Activity调用了Fragment,例如,该片段将位于Activity之上,但Activity不会调用onPause,并且如果您关闭该片段,则onStop,onStart或任何其他生命周期方法也不会被调用。最好的解决办法是在你的应用程序类检查可见如下所述:stackoverflow.com/questions/18038399/...
portfoliobuilder

6
如果您推荐静力学,您会从我这里得到-1
Matei Suica

51

我意识到这个问题已经很久了,但是我认为仍然值得分享我的解决方案,因为它可能对其他人有用。

在发布Android体系结构组件之前,该解决方案不可用。

活动至少部分可见

getLifecycle().getCurrentState().isAtLeast(STARTED)

活动处于前台

getLifecycle().getCurrentState().isAtLeast(RESUMED)

3
getLifecycle()。getCurrentState()。isAtLeast(Lifecycle.State.RESUMED)
Radhey

43

我认为这样更清楚:

  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;
    }

2
我尽量避免在for循环之前创建临时变量;对于(RunningTaskInfo任务:ActivityManager.getRunningTasks(Integer.MAX_VALUE)){...
mikebabcock 2012年

如何调用此功能?
Behzad 2012年

1
像往常一样,您是否可以在类中作为“函数”调用方法,是否需要示例?
Xenione 2012年

10
来自developer.android.com/reference/android/app/… “这绝对不能用于应用程序的核心逻辑,例如,根据此处找到的信息来决定不同的行为。不支持这种用法,并且这种用法可能会中断在将来。”
joe_deniable 2014年

15
从API级别21(Android 5.0 Lollipop)开始,此方法已被弃用。
AxeEffect 2014年

29

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

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

活动是fe的地方:this或getActivity()。

此表达式返回的值在onStart()/ onStop()中发生更改,这些事件是开始/停止显示电话上的活动布局的事件。


16
为什么不使用jsut Activity#getWindow().getDecorView().isShown()
Gianluca P.

24

我使用了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;
}

1
正如前面提到的,它可能是不是一个好主意,使用getRunningTasks(),因为它已被否决:androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/...
维塔利·德米特里耶夫

21

比使用静态变量并遵循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();

    }
}

使用共享的首选项。它具有最可靠的状态信息,减少了应用程序切换/销毁问题,使我们不必再寻求其他权限,并且它使我们可以更好地控制何时确定活动实际上是最高的。看细节了这里 ABD 这里还


谢谢。但是onResume还需要兄弟吗?

1
这取决于您对活动的了解。根据我的代码,活动处于堆栈中,然后处于活动状态。如果您想处理可见或不可见,则可以使用onResume
Zar E Ahmer

19
当活动被取消而没有致电时,此中断onStop()
Marcel Bro

3
如果应用崩溃,会发生什么?
ucMedia '18

1
这是一个非常危险的“解决方案”。
菲岑

9

这是用于检查特定服务是否正在运行的代码。我相当确定,只要您使用getRunningAppProcesses()或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;

}

1
但是请记住,您提供的链接指出“此方法仅用于调试或构建面向用户的流程管理UI”。
joe_deniable 2014年

现在不推荐使用getRunningTasks。
阿迪

5

有一种比上面所有方法都简单得多的方法,该方法不需要android.permission.GET_TASKS在清单中使用,或者在公认的答案中指出了竞争条件或内存泄漏的问题。

  1. 在主活动中创建一个STATIC变量。静态允许其他活动从另一个活动接收数据。onPause()将此变量设置为falseonResume并将onCreate()此变量设置为true

    private static boolean mainActivityIsOpen;
  2. 分配此变量的获取器和设置器。

    public static boolean mainActivityIsOpen() {
        return mainActivityIsOpen;
    }
    
    public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
        DayView.mainActivityIsOpen = mainActivityIsOpen;
    }
  3. 然后从另一个活动或服务

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

3
您是说使用访问器方法比使用原始公共静态变量更好吗?
IgorGanapolsky

1
在Java中,最好使用setter和getter来保持变量私有。但是,我相信在Android中直接访问公共变量是很普遍的……
Stephen

11
拥有公共设置器是没有意义的,因为活动状态应仅由活动本身处理。您应该遵循Java命名约定:isActivityOpen将是正确的getter方法。还使用if boolean == true是多余的。除此之外,将状态管理委派给活动是最好的方法。
利桑德罗(Lisandro)

8
这就是为什么您应该更努力地参加@coolcool;)
Jerec TheSith 2013年

1
如果您有多个活动实例在运行,该怎么办?
nickmartens1980 2014年

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

从官方文档:

活动#isFinishing()

检查此活动是否正在完成中,这是因为您在该活动上调用了finish()还是其他人已要求完成该活动。通常在onPause()中使用它来确定活动是只是暂停还是完全结束。

活动#isDestroyed()

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


4

谢谢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。因此,如果未显示您所检查的活动(即onPause),那么您将不会获得匹配。另外,要执行此操作,您需要将权限添加到清单中。

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

我希望这可以帮到你!


1
这将使用许可权被弃用API级别21 developer.android.com/reference/android/...
盖伊西

2
降低答案的比例,因为访问最低活动(服务[i] .topActivity),我们达到了API级别Q。
Debasish Ghosh

4

我认为公认的答案是处理此问题的一种糟糕方法。

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

@protected
void doSomething() {
}

并在派生类中重写它。

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

更重要的是,使用一个事件像公交车GreenRobot的方形的,而是一个已被弃用,并使用建议RxJava


2

我用了一张支票if (!a.isFinishing()),它似乎可以满足我的需求。a是活动实例。这不正确吗?为什么没有人尝试呢?


2

关于什么 activity.isFinishing()


这不是一个很好的解决方案,原因是isfinishing指示是否有活动在杀死进程中。
VelocityPulse

2

ActivityLifecycleCallbacks是跟踪App中所有活动的好方法:

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.ActivityLifecycleCallbacks.html


1

不确定这是“做事”的“正确”方法。
如果没有一种API方法可以解决您的问题,那么您可能做错了,请阅读更多文档等等。
(据我所知,静态变量在android中通常是错误的方法。它可能会起作用,但肯定会在某些情况下无法起作用(例如,在生产中,在数百万个设备上))。
正是在您的情况下,我建议考虑一下为什么您需要知道另一个活动是否还存在吗?..您可以启动另一个活动以获得结果以获取其功能。或者,您可以派生该类以获得其功能,等等。
最好的祝福。


1

如果您对活动的特定实例的生命周期状态感兴趣,那么siliconeagle的解决方案看起来是正确的,只是新的“活动”变量应该是实例变量而不是静态变量。


1

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

在您的活动中,在onStart中注册一个接收者,在onStop中注销。现在,例如,当服务需要处理活动可能能够做得更好的事情时,请从服务发送有序广播(服务本身具有默认处理程序)。现在,您可以在活动运行时对其进行响应。该服务可以检查结果数据,以查看是否处理了广播,如果没有,请采取适当的措施。


1

除了可接受的答案外,如果您有活动的多个实例,则可以使用计数器来代替:

class MyActivity extends Activity {

     static int activeInstances = 0;

     static boolean isActive() {
        return (activeInstance > 0)
     }

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

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

在返回行中缺少“ s”和“ ;;(半冒号)”。
Ali_dev

1

你有没有尝试过..

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

0

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

@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(); 
            } 
    }

0

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

private boolean activityState = true;

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

然后检查

if(activityState){
//add your code
}

0

如果要检查活动是否在堆栈中,请执行以下步骤。1.在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. 在所有活动将其扩展的BaseActivity中,重写onCreate和onDestroy方法,以便您可以按如下所示从后堆栈中添加和删除活动。

    @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. 最后,如果要检查活动是否在后堆栈中,则只需调用此函数isActivityInBackStack。

例如:我想检查HomeActivity是否在后堆栈中:

if (((MyApplicationClass) 
getApplication()).isActivityInBackStack(HomeActivity.class)) {
       // Activity is in the back stack
    } else {
       // Activity is not in the back stack
    }


-1

如果您在前台没有相同的活动,则可以进行此工作。如果您从通知中打开不起作用,我会进行一些调整并附带以下内容:

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();
}

这对我有效,同时有几个活动。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.