• Android之后台服务判断本应用Activity是否处于栈顶


    在Android开发中,我们经常想知道是否自己的服务处于后台运行中,因为在后台运行的服务器优先级会降低,也就极有可能会被系统给回收掉,有什么好办法呢?Google推荐我们将服务运行到前台,如何知道服务是否处于后台运行呢?可以通过获取堆栈信息中栈顶的Activity是否为本应用即可。

    1。下面是关健部分代码:

    (记得加上权限:<uses-permission android:name="android.permission.GET_TASKS"/>)

    mPackageName为本应用包名,mActivityManager为Activity管理对象

     

    mActivityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));

    mPackageName = getPackageName();

    	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。下面又会有一个新问题,我们什么时候调用这个函数呢?有两个办法,一个是主动,一个是被动,

    ①.主动办法:在服务中开启一个线程,每隔一段时间调用一下这个函数即可。

    ②.被动办法:自定义一个BaseActivity继承Activity,然后在onPause函数中回调通知一下服务中的此函数,然后应用中的每个Activity都继承BaseActivity,即可知道栈顶中是否还有本应用的Activity。


    3.当我们知道栈顶中的Activity不是本应用的了,我们的服务也就相应的降低了优先级,也就说系统需要内存的时候,首先就会回收此服务消耗的内存。此时,我们只需将服务设置为前台运行即可:

    ①.设置为前台:第一个参数是通知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,以上仅是本人的一点心得体会,可能有不正确的地方,请大家甄别使用,谢谢!

  • 相关阅读:
    AC自动机模板
    hdu 6034 贪心模拟 好坑
    UVA 10870
    hdu 2604 递推 矩阵快速幂
    hdu 3117 Fibonacci Numbers 矩阵快速幂+公式
    hdu 1575 Tr A 矩阵快速幂
    POJ_1151 扫描线+离散化+线段树
    HDU_2227 求不减子序列的个数(树状数组+DP)
    深夜敲模板_5——KMP
    深夜敲模板_4——无向图的割顶和桥
  • 原文地址:https://www.cnblogs.com/riasky/p/3468817.html
Copyright © 2020-2023  润新知