安卓中"杀不死的Service"

目前在做的一个Android项目,涉及到了后台Service保活的问题,网上找了很多资料,基本的保活方法都测试了。结果是:不同的手机,不同的Android版本保活效果各有差异~。最难绕过的是个厂商对“后台程序保活”管理。下面我总结下实现方案!

一、普通级方案

所谓的普通级保活方案就是通过安卓本身的机制进行保活保活!
1.控制onStartCommand函数的返回值。
我对这个函数的理解是:当服务被异常终止时,是否重启服务?

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        // TODO Auto-generated method stub  
        return START_STICKY;  
        //return super.onStartCommand(intent, flags, startId);  
    }  

2.通过service生命周期 的onDestory里面重启服务
这个在所有能触发onDestory的情况下都是有效的。4台测试机都测试过。直接startService 或者发送广播重启都可以 。测试方法是在“设置”-》应用管理-》正在运行-》停止服务。

  @Override
    public void onDestroy() {
       Intent intent = new Intent(this, AliveService.class);
            intent.putExtra(RecorderService.SERVICE_FIRST_START_KEY,
                    "START_FORM_SELF");
      startService(intent);
    }

3.提示优先级和前台服务

<!--在manifest文件中设置优先级-->
 <service
            android:name=".AliveService"
            android:permission="true"
            android:process="com.android.vesmart.videoserver"></service>
//把Service设置为前台服务
public void onCreate() {
    Notification notification = new Notification();   //此处为创建前台服务,但是通知栏消息为空,这样我们就可                              以在不通知用户的情况下启动前台服务了
    startForeground(1, notification);
  }

4.native守护进程
360不会杀掉native的守护进程,但在魅族和华为TL00H中待机一段时间后还是会被杀掉。当然有人提出双服务保活,但是经过测试完全没鸟用,就算用两个APP不同的Service相互唤醒都会被杀死
http://blog.csdn.net/marswin89/article/details/50916631

5.用 JobScheduler 机制拉活或者alarmManager 机制

public void startKeepLiveService(Context context, int timeMillis,String action) {
    //获取AlarmManager系统服务
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    //包装Intent
    Intent intent = newIntent(context,KeepLiveServie.class);
    intent.setAction(action);
    PendingIntent pendingIntent = PendingIntent.getService(context,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
    //添加到AlarmManager
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),timeMillis,pendingIntent);
}

JobScheduler 鹅厂的文章中有我就不重复造轮子了!
下面带上鹅厂的一篇文章:
http://chuansong.me/n/504099451432

二、入侵级方案

1.通过系统广播拉活
这里写图片描述

估计Google已经开始意识到这些问题,所以在最新的Android N取消了 ACTION_NEW_PICTURE(拍照),ACTION_NEW_VIDEO(拍视频),CONNECTIVITY_ACTION(网络切换)等三种广播,无疑给了很多app沉重的打击,而且很多厂商已经取消了开机广播。

2.通过推送机制拉活
在实际项目中我们都会对接多个推送来达到消息推送的效果。
第三方推送:
友盟推送、极光推送(JPush)、个推、信鸽推送、百度推送
厂商推送:
小米推送、华为推送

//这里贴了一段JPush推送的接收代码 ,在自定义消息中重启Service!
//原理差不多
@Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));

        if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
            String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
            Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
            //send the Registration Id to your server...

        } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
             Intent intent = new Intent(this, AliveService.class);
            intent.putExtra(RecorderService.SERVICE_FIRST_START_KEY,
                    "START_FORM_SELF");
            startService(intent);

        } 
    }

当然还有什么心跳包保活这些的,大同小异。
http://www.infoq.com/cn/articles/wechat-android-background-keep-alive/
3.通过定位机制拉活

    /** 
         * 通过LocationListener来获取Location信息 
         */  
        public static void formListenerGetLocation(){  
            locationManager = (LocationManager)mActivity.getSystemService(Context.LOCATION_SERVICE);  
            locationListener = new LocationListener() {  

                @Override  
                public void onLocationChanged(Location location) {  
                //在用户位置发生变化或者是切换定位方式时重启
                    //位置信息变化时触发  
                    Log4Lsy.i(TAG, "纬度:"+location.getLatitude());  
                    Log4Lsy.i(TAG, "经度:"+location.getLongitude());  
                    Log4Lsy.i(TAG, "海拔:"+location.getAltitude());  
                    Log4Lsy.i(TAG, "时间:"+location.getTime());  
                }  

                @Override  
                public void onStatusChanged(String provider, int status,Bundle extras) {  
                    //GPS状态变化时触发  
                }  

                @Override  
                public void onProviderEnabled(String provider) {  
                    //GPS禁用时触发  
                }  

                @Override  
                public void onProviderDisabled(String provider) {  
                    //GPS开启时触发   
                }  
            };  
            /** 
             * 绑定监听 
             * 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种,前者是GPS,后者是GPRS以及WIFI定位 
             * 参数2,位置信息更新周期.单位是毫秒 
             * 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息 
             * 参数4,监听 
             * 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新 
             */  
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);  
        }  

4.通过常用APP相互唤醒
这种方式也是个大APP常用的方式,在ROOT过的手机中你能看到很多相互唤醒
这里写图片描述
这种方式是通过反编译个大APP监听它发出的广播重启Service
5.通过对接IM进行保活
这种方式和推送机制差不多我就不去找代码展示了!其实更多是依赖与各种IMSDK高超的保活方案

三、攻击级方案

1.通过重启进程保活
http://www.cnblogs.com/angeldevil/archive/2013/05/21/3090872.html
2.通过系统漏洞保活
这种方式太伤天害理,虽然我看过大牛的文章而且的确能够实现到效果。但是避免危害过大我还是不贴出来了!
3.通过添加为系统服务
http://blog.csdn.net/lewif/article/details/50687290

总结:搞了一抹多方法,一句话“随便你怎么玩,该死还是得死”。很多方案在在不同的手机又不同的效果,根据自己项目需求来决定该如何保活,保活到什么程度!如果你有更好的方案请给我提出!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值