您的位置:首页 > 移动开发

Android中如何判断本app是否在前台运行

2016-05-08 12:43 429 查看
缘由:

  在做App升级时,遇到的需求。在发现升级信息后,如果当前App在前台运行,则弹窗提示有升级信息; 如果App此正在后台运行,则在通知栏发送通知。那么问题的关键点在于:如何判断本App正在前台运行?

 

解决方法:

1、调用系统API

这是很多应用锁所采用的方法。获取当前正在前台运行的App包名,判断是否是自己。不过这个方法存在缺陷,依赖于系统对API的开放程度,必须增加权限。而且此功能过于强大,没有必要使用。代码参考如下:

private boolean isRunningForeground (Context context)  

{  

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

    ComponentName cn = am.getRunningTasks(1).get(0).topActivity;  

    String currentPackageName = cn.getPackageName();  

    if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(getPackageName()))  

    {  

        return true ;  

    }  

   

    return false ;  

}  

 

此外,并不是所有的系统都可用此代码,例如:

Android L开始,Google开始对getRunningTasks接口进行限制使用。
默认情况下,普通的三方应用(非系统应用)不能使用该接口。这种方式以及废弃。应用要使用该接口必须声明权限 android.permission.REAL_GET_TASKS。而这个权限是不对三方应用开放的。(在Manifest里申请了也没有作用)系统应用(有系统签名)可以调用该权限。Google这样做的原因还是出于安全考虑,对普通应用开发该接口可能会造成用户的隐私泄露。
 

2、在BaseActivity中监控Activity的生命周期

另一种就是自己监控自己所有Activity的运行状态。整个系统维护一个运行在前台的Activity计数,当任意activity进入onResue()时,增加计数;当退出前台时进入onPause()时,减少计数。为达到此目的,需要为所有应用中的Activiy增加一个基类BaseActivity,BaseActivity再继承自系统中的Activity。BaseActivity中添加如下代码。这也说明了自定义一个Activity的便利性。

@Override
protected void onResume() {
    super.onResume();
    topActivity = this;
    BuluApplication.setIsAppRunningFront(true);
    MobclickAgent.onResume(this);
}

@Override
protected void onPause() {
    super.onPause();
    BuluApplication.setIsAppRunningFront(false);
    MobclickAgent.onPause(this);
}


为什么是onPause()而不是onStop()?

通过观察Activity的生命周期状态图,可以看到,App可能会在onPause()或onStop()调用后被杀死,而onPause()先于onStop()运行,所以,为了保证计数的准确,必须在onPause()处理Activity的计数递减;否则就可能出现Activity在onPause()调用后,立即被杀死,而Activity计数没有递减的状态。

 

判断当前App是否在前台运行的方法?

只要检查计数是否>0。

public static boolean isAppRunningFront() {

    return activityVisiableCount > 0;

}

public static void setIsAppRunningFront(boolean isAppRunningFront) {

    if (isAppRunningFront) {

        activityVisiableCount++;
    } else if (activityVisiableCount > 0){

        activityVisiableCount--;
    }

}

 

 

如何判断在前台的是哪个Activty?

首先判断前当前App是否在前台运行,然后获取topActivity即可。

 

3、在Application中注册Activity状态切换的监控回调 

此方式同第2种方式原理是一样的,只不过使用Application注册相应接口。

public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {

public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {

回调的接口如下:

public interface ActivityLifecycleCallbacks {

    void onActivityCreated(Activity activity, Bundle savedInstanceState);
    void onActivityStarted(Activity activity);
    void onActivityResumed(Activity activity);
    void onActivityPaused(Activity activity);
    void onActivityStopped(Activity activity);
    void onActivitySaveInstanceState(Activity activity, Bundle outState);
    void onActivityDestroyed(Activity activity);

}

同样的,在onActivityResumed和onActivityPaused中增加同第2种方式相同的代码即可。

 

总结

这个问题回答了回为什么有必要了解Activity的生命周期,否则难以想到第2、3种方式的原理,以及注意Activity回收时机而将计数递减代码放在onPause而不是onStop的原因。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: