Android Service服务保活

基于Android 10.11 实现的Service服务保活

最近公司要实现app程序不被杀死 实现持续定位,在网上看了很多个文章 也看到双进程保活,我忘了在那看到这篇文章了 

下面 具体显现

创建 MyService 集成 service 服务

public class MyService extends Service {
    private final static String TAG = MyService.class.getSimpleName();
    // 启动notification的id,两次启动应是同一个id
    private final static int NOTIFICATION_ID = android.os.Process.myPid();
    private AssistServiceConnection mServiceConnection;


    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onCreate() {
        super.onCreate();
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            //数字是随便写的“40”,
            nm.createNotificationChannel(new NotificationChannel("40", "App Service", NotificationManager.IMPORTANCE_DEFAULT));
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "40");

            //其中的2,是也随便写的,正式项目也是随便写
            startForeground(2 ,builder.build());
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 测试线程,判断Service是否在工作
        new Thread(mRunnable).start();
        // 设置为前台进程,降低oom_adj,提高进程优先级,提高存活机率
        setForeground();
        return START_STICKY;

    }

    // 要注意的是android4.3之后Service.startForeground() 会强制弹出通知栏,解决办法是再
    // 启动一个service和推送共用一个通知栏,然后stop这个service使得通知栏消失。
    private void setForeground() {
        if (Build.VERSION.SDK_INT < 18)
        {
            startForeground(NOTIFICATION_ID, getNotification());
            return;
        }
        if (mServiceConnection == null)
        {
            mServiceConnection = new AssistServiceConnection();
        }
        // 绑定另外一条Service,目的是再启动一个通知,然后马上关闭。以达到通知栏没有相关通知
        // 的效果
        bindService(new Intent(this, AssistService.class), mServiceConnection,
                Service.BIND_AUTO_CREATE);
    }

    private class AssistServiceConnection implements ServiceConnection
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Service assistService = ((AssistService.LocalBinder)service)
                    .getService();
            MyService.this.startForeground(NOTIFICATION_ID, getNotification());
            assistService.startForeground(NOTIFICATION_ID, getNotification());
            assistService.stopForeground(true);

            MyService.this.unbindService(mServiceConnection);
            mServiceConnection = null;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    private Notification getNotification()
    {
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "")
                .setContentTitle("服务运行于前台")
                .setContentText("service被设为前台进程")
                .setTicker("service正在后台运行...")
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setWhen(System.currentTimeMillis())
                .setDefaults(NotificationCompat.DEFAULT_ALL)
                .setContentIntent(pendingIntent);
        Notification notification = builder.build();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        return notification;
    }

    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            while (true)
            {
                Log.e(TAG+1111, "" + System.currentTimeMillis());
   发送广播
                Intent intent=new Intent();
                //指定广播的名字
                intent.setAction("com.yy.time.TIME_CHANGED_ACTION");
                //指定广播的内容
                // 此行  对8.0以上广播接受不到 增加处理 “包名” ,“广播地址” intent.setComponent( new ComponentName( "com.example.webwebsocket" ,
                            "com.example.webwebsocket.Service.UITimeReceiver") );

                try {
                    intent.setComponent( new ComponentName( "com.example.webwebsocket" ,
                            "com.example.webwebsocket.Service.UITimeReceiver") );

                    //此处我传递了值   你们不传递也行
                    intent.putExtra("time",getTime());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                //发送广播
                sendBroadcast(intent);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
    }

}

再创建 AssistService 一个类也集成service服务

public class AssistService extends Service {
    public AssistService() {
    }

    public class LocalBinder extends Binder
    {
        public AssistService getService()
        {
            return AssistService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new LocalBinder();
    }
}

在AndroidManifest.xml 清单文件里注册service服务   和一个广播 

  <service android:name=".Service.MyService"></service>
<!--注册广播-->
        <receiver
            android:name=".Service.UITimeReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.yy.time.TIME_CHANGED_ACTION" />
            </intent-filter>
        </receiver>

在创建一个广播接收器 利用广播传递消息

public class UITimeReceiver extends BroadcastReceiver {
   
    private  Context mContext;
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(MainActivity.TIME_CHANGED_ACTION.equals(action)){
          
           
           //此处处理你需要处理的逻辑 我写的接口回调  具体看个人需求
              
        }
    }
}
在MainActivity使用注册启动service 服务  此处做个Android版本判断 否则会出错
 //开启服务做兼容处理
        Intent intentOne = new Intent(this, MyService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intentOne);
        } else {
            startService(intentOne);
        }

 完毕

我觉得直接复制就好  完成用不上demo  本人亲测 Android10 .11  oppo 小米机型 保活24小时   再往常的时间没试,大家可以试试 ,可以给楼主反馈。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值