在Android开发中,咱们常常想知道是否本身的服务处于后台运行中,由于在后台运行的服务器优先级会下降,也就极有可能会被系统给回收掉,有什么好办法呢?Google推荐咱们将服务运行到前台,如何知道服务是否处于后台运行呢?能够经过获取堆栈信息中栈顶的Activity是否为本应用便可。java
1。下面是关健部分代码:android
(记得加上权限:<uses-permission android:name="android.permission.GET_TASKS"/>)服务器
mPackageName为本应用包名,mActivityManager为Activity管理对象app
mActivityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));函数
mPackageName = getPackageName();post
public boolean isAppOnForeground() { List<RunningTaskInfo> tasksInfo = mActivityManager.getRunningTasks(1); if (tasksInfo.size() > 0) { L.i("top Activity = " + tasksInfo.get(0).topActivity.getPackageName()); // 应用程序位于堆栈的顶层 if (mPackageName.equals(tasksInfo.get(0).topActivity .getPackageName())) { return true; } } return false; }
2。下面又会有一个新问题,咱们何时调用这个函数呢?有两个办法,一个是主动,一个是被动,this
①.主动办法:在服务中开启一个线程,每隔一段时间调用一下这个函数便可。spa
②.被动办法:自定义一个BaseActivity继承Activity,而后在onPause函数中回调通知一下服务中的此函数,而后应用中的每一个Activity都继承BaseActivity,便可知道栈顶中是否还有本应用的Activity。线程
3.当咱们知道栈顶中的Activity不是本应用的了,咱们的服务也就相应的下降了优先级,也就说系统须要内存的时候,首先就会回收此服务消耗的内存。此时,咱们只需将服务设置为前台运行便可:code
①.设置为前台:第一个参数是通知ID,第二个参数是Notification对象
startForeground(SERVICE_NOTIFICATION, n);
②.中止前台服务可调用:true表明清除通知栏
stopForeground(true);
public void updateServiceNotification(String message) { if (!PreferenceUtils.getPrefBoolean(this, PreferenceConstants.FOREGROUND, true)) return; String title = PreferenceUtils.getPrefString(this, PreferenceConstants.ACCOUNT, ""); Notification n = new Notification(R.drawable.login_default_avatar, title, System.currentTimeMillis()); n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; Intent notificationIntent = new Intent(this, MainActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); n.contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); n.setLatestEventInfo(this, title, message, n.contentIntent); startForeground(SERVICE_NOTIFICATION, n); } // 判断程序是否在后台运行的任务,其实我的以为这个办法并不太好, Runnable monitorStatus = new Runnable() { public void run() { try { L.i("monitorStatus is running... " + mPackageName); mMainHandler.removeCallbacks(monitorStatus); // 若是在后台运行而且链接上了 if (!isAppOnForeground()) { L.i("app run in background..."); // if (isAuthenticated())//不判断是否链接上了。 updateServiceNotification(getString(R.string.run_bg_ticker)); return;// 服务已在前台运行,能够中止重复执行此任务 } else { stopForeground(true); } mMainHandler.postDelayed(monitorStatus, 1000L); } catch (Exception e) { e.printStackTrace(); L.i("monitorStatus:"+e.getMessage()); } } };
OK,以上仅是本人的一点心得体会,可能有不正确的地方,请你们甄别使用,谢谢!