android如何判断应用是否在前台

git中总结了5种方法:https://github.com/wenmingvs/AndroidProcess

方法一ActivityManager:

通常情况下,我们判断app是否在前台都是通过 ActivityManager。

/**
   * Activity是否在前台
   * @param context
   * @return
   */
  private boolean isOnForground(Context context){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> appProcessInfoList = activityManager.getRunningAppProcesses();
    if(appProcessInfoList == null){
      return false;
    }

    String packageName = context.getPackageName();
    for(ActivityManager.RunningAppProcessInfo processInfo : appProcessInfoList){
      if(processInfo.processName.equals(packageName) && processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND ){
        return true;
      }
    }
    return false;
  }

但是这个并不是最好的:

  • 性能差,相当于遍历所有的进程来找前台的且包名符合的。
  • 在有些手机上 不适用。

方法二ActivityLifecycleCallbacks:

Application可以通过 registerActivityLifecycleCallbacks 来注册 ActivityLifecycleCallbacks 接口,以实现对所有Activity生命周期的回调。

this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

      }

      @Override
      public void onActivityStarted(Activity activity) {

      }

      @Override
      public void onActivityResumed(Activity activity) {

      }

      @Override
      public void onActivityPaused(Activity activity) {

      }

      @Override
      public void onActivityStopped(Activity activity) {

      }

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

      }

      @Override
      public void onActivityDestroyed(Activity activity) {

      }
    });

每一个Activity的生命周期都会回调相应的方法。意思是Application能监听所有Activity的生命周期咯,是不是很牛x。 
这个功能可以用来做某种统计,或者弄成一个Activity链表可以知道前后Activity什么的,虽然目前还没遇到这种需求,当然了”判断APP是否在前台“这个功能算半个不过分吧。

生命周期
然后,为了达到 ”判断APP是否在前台“这个功能,我们需要先知道activity的生命周期。是不是很简单? 
但是很多人不知道 如果ActivityA intent跳转到 ActivityB,这两个的生命周期是怎么切换的。 
公布答案: 
ActivityA.OnPause() —> AcitivityB.OnCreate() —> AcitivityB.OnStart() —> ActivityB.OnResume() —> ActivityA.OnStop() 
其实,也确实应该是这样嘛,你要切换新界面,总得等新界面显示出来了,才能去处理旧界面。总不能先把旧的处理掉,然后黑屏加载新界面吧。

判断APP是否在前台

在Application中继承 Application.ActivityLifecycleCallbacks ,

并在onCreate()方法中注册监听:registerActivityLifecycleCallbacks(this);

最后通过isForeground来判断即可。具体可查看下面代码:

public class BaseApplication extends MultiDexApplication implements Application.ActivityLifecycleCallbacks {

    private int activityCount;//activity的count数
    public static boolean isForeground;//是否在前台
    private static Context context;
    private static Resources resource;
    private String TAG = "----BaseApplication ";
    protected static String BASE_URL = "";

public static Resources getAppResources() {
    return resource;
}

@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().setContext(this);
context = getApplicationContext();
resource = context.getResources();
//全局管理Activity生命周期
registerActivityLifecycleCallbacks(this);
}

public static Context getContext() {
return context;
}

public static void setContext(Context context) {
BaseApplication.context = context;
}

public static boolean debug() {
return BuildConfig.DEBUG;
}

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(getApplicationContext());
}

@Override
public File getCacheDir() {
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        File cacheDir = getExternalCacheDir();
        if (cacheDir != null && (cacheDir.exists() || cacheDir.mkdirs())) {
            return cacheDir;
        }
    }
    File cacheDir = super.getCacheDir();
    return cacheDir;
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    Log.e(TAG+"activityCount","-----onActivityCreated="+activityCount);
}


@Override
public void onActivityStarted(Activity activity) {
    activityCount++;
    Log.e(TAG+"activityCount","-------onActivityStarted="+activityCount);
}

@Override
public void onActivityResumed(Activity activity) {
Log.e(TAG+"activityCount","-------onActivityResumed="+activityCount);
isForeground();
}

@Override
public void onActivityPaused(Activity activity) {
    Log.e(TAG+"activityCount","-------onActivityPaused="+activityCount);
}

@Override
public void onActivityStopped(Activity activity) {
    activityCount--;
    Log.e(TAG+"activityCount","-------onActivityStopped="+activityCount);
    isForeground();
}

/**
* 判断是否在前台
*/
private void isForeground() {
    if (activityCount>0) {
       isForeground = true;
    }else {
    isForeground=false;
    }
    Log.e(TAG+"activityCount=",+activityCount+"-------isForeground="+isForeground);
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    Log.e(TAG+"activityCount","-------onActivitySaveInstanceState="+activityCount);
}

@Override
public void onActivityDestroyed(Activity activity) {
    Log.e(TAG+"activityCount","-------onActivityDestroyed="+activityCount);
}

}

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值