当前位置:   article > 正文

判断Android程序前后台切换的几种方法_android 12 判断切后台

android 12 判断切后台
Android在前后台切换时,我们可能需要做一些处理:发送
通知栏消息,提示APP在后台运行;或者我们需要暂停程序里的
某些线程,或者让线程池的执行时间降低,以保证较高的内存,
而避免被回收。那么我们有几种方式可以来判断呢?

思路1:在一个service里,使用一个线程,通过
ActivityManager.RunningAppProcessInfo轮询检测。

  1. public class AppService extends Service implements Runnable{
  2. public static boolean isOnBackground = true;
  3. @Override
  4. public IBinder onBind(Intent intent) {
  5. return null;
  6. }
  7. @Override
  8. public void onCreate() {
  9. // TODO Auto-generated method stub
  10. super.onCreate();
  11. new Thread(this).start();
  12. }
  13. @Override
  14. public int onStartCommand(Intent intent, int flags, int startId) {
  15. // TODO Auto-generated method stub
  16. return super.onStartCommand(intent, flags, startId);
  17. }
  18. @Override
  19. public void run() {
  20. while(true){
  21. boolean isOnBackgroundNew = DeviceUtils.isRunningOnBackground(this);
  22. Log.d("appstatus", "app is on background ? " + (isOnBackgroundNew ?"yes":"no"));
  23. if(isOnBackgroundNew != isOnBackground){
  24. //检测到前后台状态不一致,做一些处理
  25. }
  26. try {
  27. Thread.sleep(500);
  28. } catch (InterruptedException e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34. public static boolean isRunningOnBackground(Context context){
  35. ActivityManager acm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  36. if(acm != null){
  37. List<RunningAppProcessInfo> runApps = acm.getRunningAppProcesses();
  38. if(runApps != null && !runApps.isEmpty()){
  39. for(RunningAppProcessInfo app : runApps){
  40. if(app.processName.equals(context.getPackageName())){
  41. if(app.importance == RunningAppProcessInfo.IMPORTANCE_BACKGROUND){
  42. return true;
  43. }
  44. }
  45. }
  46. }
  47. }
  48. return false;
  49. }
  50. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

缺点:需要创建service,以及线程,暂用大量CPU时间;切换至后台运行时会有延迟。


思路2:实现一个BaseActivity,然后让我们应用程序的Activity都继承自BaseActivity,子类继承BaseActivity非私属性和方法,通过BaseActivity的onStart()和onStop()方法中进行判断应用程序是否进入到后台并且是否从后台返回到了前台。这里我曾经遇到一个坑,先来看看我的第一个版本实现吧。

  1. public class BaseActivity extends Activity {
  2. public static boolean isBackground; //全局变量
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_base);
  7. }
  8. @Override
  9. protected void onStart() {
  10. if (isBackground) {
  11. //app 从后台唤醒,进入前台
  12. isBackground = false;
  13. Log.i("ACTIVITY", "程序从后台唤醒");
  14. }
  15. super.onStart();
  16. }
  17. @Override
  18. protected void onResume() {
  19. super.onResume();
  20. }
  21. @Override
  22. protected void onPause() {
  23. super.onPause();
  24. }
  25. @Override
  26. protected void onStop() {
  27. if (isAppOnForeground()) {
  28. //app 进入后台
  29. isBackground = true;//记录当前已经进入后台
  30. Log.i("ACTIVITY", "程序进入后台");
  31. }
  32. super.onStop();
  33. }
  34. @Override
  35. protected void onDestroy() {
  36. super.onDestroy();
  37. }
  38. /**
  39. * APP是否处于前台唤醒状态
  40. *
  41. * @return
  42. */
  43. public boolean isAppOnForeground() {
  44. ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
  45. String packageName = getApplicationContext().getPackageName();
  46. List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager
  47. .getRunningAppProcesses();
  48. if (appProcesses == null)
  49. return false;
  50. for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
  51. // The name of the process that this object is associated with.
  52. if (appProcess.processName.equals(packageName)
  53. && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
  54. return true;
  55. }
  56. }
  57. return false;
  58. }
  59. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

isAppOnForeground()在不同的Android系统上返回值不同。我的想法是美好的,可是实际却是一个坑。当我点击home时,onStop也被调用了,可以isAppOnForeground()却返回false,系统还没更新状态吗?这可能要去深究源代码才清楚了。后来,就有了以下改进版。

  1. public class BaseActivity extends Activity {
  2. public static boolean activityActive; //全局变量,表示当前在前台的activity数量
  3. public static boolean isBackground ;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_base);
  8. }
  9. @Override
  10. protected void onStart() {
  11. //app 从后台唤醒,进入前台
  12. activityActive++;
  13. isBackground = false;
  14. Log.i("ACTIVITY", "程序从后台唤醒");
  15. super.onStart();
  16. }
  17. @Override
  18. protected void onResume() {
  19. super.onResume();
  20. }
  21. @Override
  22. protected void onPause() {
  23. super.onPause();
  24. }
  25. @Override
  26. protected void onStop() {
  27. activityActive--;
  28. if (activityActive == 0) {
  29. //app 进入后台
  30. isBackground = true;//记录当前已经进入后台
  31. Log.i("ACTIVITY", "程序进入后台");
  32. }
  33. super.onStop();
  34. }
  35. @Override
  36. protected void onDestroy() {
  37. super.onDestroy();
  38. }
  39. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

这个方法是不是很简单 ! ^_^

思路3:其实跟第二种改进版是一样的,只不过放在Application中实现了,感觉还是第二种方法简单哈。

  1. public class TheApplication extends Application {
  2. private int mFinalCount;
  3. @Override
  4. public void onCreate() {
  5. super.onCreate();
  6. registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
  7. @Override
  8. public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
  9. }
  10. @Override
  11. public void onActivityStarted(Activity activity) {
  12. mFinalCount++;
  13. //如果mFinalCount ==1,说明是从后台到前台
  14. Log.e("onActivityStarted", mFinalCount +"");
  15. if (mFinalCount == 1){
  16. //说明从后台回到了前台
  17. }
  18. }
  19. @Override
  20. public void onActivityResumed(Activity activity) {
  21. }
  22. @Override
  23. public void onActivityPaused(Activity activity) {
  24. }
  25. @Override
  26. public void onActivityStopped(Activity activity) {
  27. mFinalCount--;
  28. //如果mFinalCount ==0,说明是前台到后台
  29. Log.i("onActivityStopped", mFinalCount +"");
  30. if (mFinalCount == 0){
  31. //说明从前台回到了后台
  32. }
  33. }
  34. @Override
  35. public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
  36. }
  37. @Override
  38. public void onActivityDestroyed(Activity activity) {
  39. }
  40. });
  41. }
  42. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/144778
推荐阅读