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

use*_*571 141 android android-activity

有没有简单的方法来确定某项活动是否有效?我想根据哪些活动是活跃的来做某些事情.例如:

if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
Run Code Online (Sandbox Code Playgroud)

sil*_*gle 213

您可以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;
      }
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是如果你在两个相互链接的活动中使用它,那么onStop在第一个活动中有时会onStart在第二个活动中调用它.所以两者都可能是短暂的.

取决于您要执行的操作(从服务更新当前活动?).您可以在activity onStart方法中在服务中注册一个静态侦听器,然后在您的服务想要更新UI时,可以使用正确的侦听器.

  • 如果同一个班级的不同活动在运行怎么办?如果你用`MyChildactivity`扩展`MyActivity`并想检查孩子是否活跃怎么办? (10认同)
  • 有人向我指出,由于内存泄漏问题,共享偏好优先于静态变量. (3认同)
  • 这个解决方案根本不是一个好的解决方案.让我们说你的Activity调用一个Fragment,例如,片段将在Activity上,但Activity不会调用onPause,如果你关闭片段onStop,onStart或任何其他生命周期方法也不会被调用.最佳解决方案是在Application类中检查可见性,如下所述:http://stackoverflow.com/questions/18038399/how-to-check-if-activity-is-in-foreground-or-in-visible-background (3认同)
  • 如果你推荐静力学,你得到一个-1 (3认同)
  • 根据您对"running"的定义,您可能希望在onResume和onPause中更改变量的状态.... (2认同)
  • 如果活动的多个实例正在运行,这将失败.您可以使用有序广播.在活动本身(在实例级别)内部使用mIsRunning布尔值来获取此状态 (2认同)
  • 使用counterint而不是使用布尔值.在onstart中,增加它,在destroy减去它,创建一个方法来检查counter> 0 (2认同)

Xen*_*one 41

我觉得更清楚:

  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;
    }
Run Code Online (Sandbox Code Playgroud)

  • 此代码将需要android.permission.GET_TASKS (21认同)
  • 从API级别21(Android 5.0 Lollipop)开始,此方法已被弃用. (10认同)
  • 来自http://developer.android.com/reference/android/app/ActivityManager.html#getRunningTasks%28int%29"这绝不应该用于应用程序中的核心逻辑,例如根据找到的信息在不同的行为之间做出决定这些用途不受支持,将来很可能会破裂." (8认同)
  • 我试图避免在'for'循环之前创建临时变量; for(RunningTaskInfo任务:ActivityManager.getRunningTasks(Integer.MAX_VALUE)){... (2认同)

GaR*_*eTa 26

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

activity.getWindow().getDecorView().getRootView().isShown()
Run Code Online (Sandbox Code Playgroud)

活动是fe:this或getActivity().

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

  • 为什么不用jsut使用`Activity#getWindow().getDecorView().isShown()`? (15认同)

小智 23

我使用了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;
}
Run Code Online (Sandbox Code Playgroud)

  • 如前所述,使用 getRunningTasks() 可能不是一个好主意,因为它已被弃用:http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityManager .java#1991 (2认同)

Xar*_*mer 20

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

    }
}
Run Code Online (Sandbox Code Playgroud)

使用共享首选项.它具有最可靠的状态信息,较少的应用程序切换/销毁问题,节省了我们请求另一个权限,它让我们有更多的控制权来决定我们的活动何时实际上是最顶层的.这里也看到 abd的详细信息

  • 当活动被杀死而不调用`onStop()`时会中断 (17认同)
  • 如果应用崩溃,会发生什么? (3认同)
  • **这是一个非常危险的“解决方案”。** (2认同)

kku*_*udi 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;

}
Run Code Online (Sandbox Code Playgroud)


Cod*_*ous 8

if(!activity.isFinishing() && !activity.isDestroyed())
Run Code Online (Sandbox Code Playgroud)

来自官方文档:

活动#isFinishing()

检查此活动是否正在完成,因为您对其调用了 finish() 或其他人要求它完成。这通常用于 onPause() 来确定活动是简单地暂停还是完全结束。

活动#isDestroyed()

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


mal*_*jir 8

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

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

活动至少部分可见

getLifecycle().getCurrentState().isAtLeast(STARTED)
Run Code Online (Sandbox Code Playgroud)

活动处于前台

getLifecycle().getCurrentState().isAtLeast(RESUMED)
Run Code Online (Sandbox Code Playgroud)

  • getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED) (8认同)

aly*_*002 6

谢谢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; 
} 
Run Code Online (Sandbox Code Playgroud)

如果topActivity与用户正在进行的操作匹配,此示例将为您提供true或false.因此,如果您正在检查的活动没有显示(即是onPause),那么您将无法获得匹配.此外,要执行此操作,您需要向清单添加权限.

<uses-permission  android:name="android.permission.GET_TASKS"/>
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮到你!

  • 此使用权限在 API 级别 21 中已弃用。 http://developer.android.com/reference/android/Manifest.permission.html#GET_TASKS (2认同)
  • 否决答案,因为要访问顶级活动(services[i].topActivity),我们需要最小 API 级别 Q 。低于此级别将不起作用。 (2认同)

coo*_*994 5

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

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

    private static boolean mainActivityIsOpen;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 分配此变量的 getter 和 setter。

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

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

  • 拥有公共设置器是没有意义的,因为活动状态只能由活动本身处理。您应该坚持 Java 命名约定: isActivityOpen 将是一个正确的 getter 方法。还使用 if boolean == true 是多余的。除此之外,将状态管理委托给活动是最好的方法。 (11认同)
  • 这就是为什么你应该更努力地参加你的课程@coolcool ;) (8认同)
  • 您是说使用访问器方法比使用原始公共静态变量更好吗? (3认同)