zoukankan      html  css  js  c++  java
  • Android防止进程被第三方软件杀死

    项目测试的时候发现,按home键回到桌面,再用360清理内存,软件被结束,再次进入的时候报错,看了下log,以为是有的地方没有控制好,但是又不知道360结束的是什么(这个现在还没弄明白)。使用小米系统的进程管理优化内存就不报错。

    后来想到用Service防止软件被kill掉,查了下资料,发现google 管方就有,ForegroundService 前台服务,让服务一直以前台任务的方式运行,可以在service 的oncreate来实现前台服务, 通过这个方法必须发送一个通知栏,让用户知道服务在运行。

    Notification notification = new Notification(R.drawable.icon, "服务开启", System.currentTimeMillis());
            notification.flags|= Notification.FLAG_NO_CLEAR;  
            notification.flags=Notification.FLAG_ONGOING_EVENT;
            Intent notificationIntent = new Intent(this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
            notification.setLatestEventInfo(this, "service", "防止服务被任务管理器所杀", pendingIntent);     
            startForeground(ONGOING_NOTIFICATION, notification);

    这样就能保持service 运行,可是通知栏不能清除 ,一清除就会被kill。
    后来一次 做自定义Notification的时候,通知栏没有显示通知,查看后发现 service 也没被kill 。所以就进一步去研究了下 最后发现 只用两行代码就能保持服务不会被kill,并且不会有通知栏通知代码如下:

    Notification notification = new Notification();
    startForeground(1, notification);

    完整代码如下:

    public class TestService extends Service {
        private static final Class[] mStartForegroundSignature = new Class[] {
                int.class, Notification.class };
        private static final Class[] mStopForegroundSignature = new Class[] { boolean.class };
        private NotificationManager mNM;
        private Method mStartForeground;
        private Method mStopForeground;
        private Object[] mStartForegroundArgs = new Object[2];
        private Object[] mStopForegroundArgs = new Object[1];
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            try {
                mStartForeground = TestService.class.getMethod("startForeground",
                        mStartForegroundSignature);
                mStopForeground = TestService.class.getMethod("stopForeground",
                        mStopForegroundSignature);
            } catch (NoSuchMethodException e) {
                mStartForeground = mStopForeground = null;
            }
            // 我们并不需要为 notification.flags 设置 FLAG_ONGOING_EVENT,因为
            // 前台服务的 notification.flags 总是默认包含了那个标志位
            Notification notification =new Notification();
            // 注意使用  startForeground ,id 为 0 将不会显示 notification
            startForegroundCompat(1, notification);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            stopForegroundCompat(1);
        }
    
        // 以兼容性方式开始前台服务
        private void startForegroundCompat(int id, Notification n) {
            if (mStartForeground != null) {
                mStartForegroundArgs[0] = id;
                mStartForegroundArgs[1] = n;
                try {
                    mStartForeground.invoke(this, mStartForegroundArgs);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return;
            }
            mNM.notify(id, n);
        }
    
        // 以兼容性方式停止前台服务
        private void stopForegroundCompat(int id) {
            if (mStopForeground != null) {
                mStopForegroundArgs[0] = Boolean.TRUE;
                try {
                    mStopForeground.invoke(this, mStopForegroundArgs);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return;
            }
            //   在 setForeground 之前调用 cancel,因为我们有可能在取消前台服务之后
            //   的那一瞬间被kill掉。这个时候 notification 便永远不会从通知一栏移除
            mNM.cancel(id);
        }
    }

    经测试,360手机助手,腾讯手机管家都不能kill这个service,但是手动结束后,再次打开发现音频还在播放(跟音频有关的客户端),感觉有点小别扭...

    参考:http://my.eoe.cn/sdaduanbilei/archive/1846.html

    http://blog.csdn.net/qinjuning/article/details/6915482

    有关360清理的资料http://bbs.360.cn/5295927/251879454.html

  • 相关阅读:
    WPF 文本动画 文字BaseLine 字体 行高计算说明
    C#查找窗口,并控制窗口显示隐藏,通过改变窗口样式方式
    c#获取状态栏图标并-模拟鼠标点击-模拟鼠标点击窗体的某些按钮
    IEC 104公约 解析 c#使用通过104公约同步时间
    hprose数据可视化显示,通过c#序列化,列表形式展示,导出excel、csv
    微服务优秀博文资料
    IT 常用单词表
    java 优秀开源项目
    java并发编程学习博客
    LDAP服务端
  • 原文地址:https://www.cnblogs.com/cc-Cheng/p/3146143.html
Copyright © 2011-2022 走看看