Android 保证Service服务不被杀死的几个方法


Bound绑定:bound形式的服务是指一个应用组件通过调用bindService()方法与服务绑定。一个绑定的服务提供一个接口,允许组件与服务交互,发送请求、获得结果、甚至进行进程间通信。一个绑定的服务只和与其绑定的组件同时运行。多个组件可以同时绑定到一个服务,当全部解除绑定后,服务就会被销毁
虽然分为两类,但是一个服务可以同时使用这两种方式-使用started永久运行,同时允许绑定。只要在服务中实现两个回调方法:onStartCommand()允许组件开启服务,onBind()允许绑定。

不论引用程序是怎么起服务的,任何应用程序都可以用这个服务。同样的,任何组件可以使用一个Activity通过传递Intent开启服务。你也可以在配置文件设置服务为私有来防止其他应用访问该服务。

注意:一个服务在进程中的主线程运行,服务不会自己创建线程和进程(除非特别指定或者开启一个线程)。这意味着,如果服务需要做一些频繁占用CPU的工作或者会发生阻塞的操作,需要在服务另外开启线程。

1.3 Service生命周期


启动服务:startService()->onCreate()->onStartCommand()->running->stopService()/stopSelf()->onDestroy()->stopped,其中,服务未运行时会调用一次onCreate(),运行时不会调用。
绑定服务:bindService()->onCreate()->onBind()->running->onUnbind()->onDestory()->stopped。

第二章 实现Service
实现服务有两种方式,继承service或者IntentService。后者是前者的子类。前者包含上一章节中Service的几个重要的方法,用于普通的服务。后者可以自己开一个工作线程,串行的处理多个请求。

2.2 继承IntentService
大多数服务不需要同时处理多个请求,继承IntentService是最好的选择。 
IntentService处理流程:

创建一个worker线程处理传递给onStartCommand()所有的intent,在非UI线程中工作。
创建一个工作队列依次传递一个intent到你实现的onHandleIntent()方法,避免了多线程。
在所有启动请求被处理后自动关闭服务,不需要调用stopSelf()
默认提供onBind()的实现,并返回null
默认提供onStartCommand()的实现,实现发送intent到工作队列再到你的onHandleIntent()方法实现。
这些都加入到IntentService中了,你需要做的就是实现构造方法和onHandleIntent(),如下:

public class HelloIntentService extends IntentService {
 
  public HelloIntentService() {
      super("HelloIntentService");
  }
 
  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

第三章 如何保证服务不被杀死
有以下几种方法保持Service不被杀死。

3.2 提升Service优先级
前台服务是被认为用于已知的正在运行的服务,当系统需要释放内存时不会优先杀掉该进程。前台进程必须发一个notification在状态栏中显示,直到进程被杀死。因为前台服务一直消耗一部分资源,但不像一般服务那样会在需要的时候被杀掉,所以为了节约资源,保护电池寿命,一定要在建前台服务的时候发送notification,提示用户。当然系统提供的方法就必须有notification参数的,所以不要想着怎么把notification隐藏掉。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    Intent notificationIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification noti = new Notification.Builder(this)
                .setContentTitle("Title")
                .setContentText("Message")
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(pendingIntent)
                .build();
    startForeground(123456,noti);
    return Service.START_STICKY;
}

startForeground()方法就是将服务设置为前台服务,参数123456就是这个通知的唯一的id,只要不为0即可。

3.3 在onDestory()中发送广播开启自己
service+broadcast方式,就是当service调用到ondestory()的时候,发送一个自定义的广播,当收到广播的时候,重新启动service;

<receiver android:name="com.example.demo.MyReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.USER_PRESENT"/>
        <action android:name=com.example.demo.destroy"/>// 这个是自定义的action
    </intent-filter>
</receiver>

在service中的ondestroy()时候:

@Override
public void onDestroy(){
    stopForeground(true);
    Intent intent = new Intent("com.example.demo.destroy");
    sendBroadcast(intent);
    super.onDestroy();
}

在MyReceiver中

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals("com.example.demo.destroy")){
            Intent sevice = new Intent(this, MyService.class);  
            this.startService(sevice); 
        }
    }
}

当然,从理论上来讲这个方案是可行的,实验一下结果也是可行的。但是有些情况下,发送的广播在消息队列中排的靠后,就有可能服务还没有接收到广播就销毁了(只是猜想)。所以为了能让这个机制完美运行,可以开启两个服务,相互监听,相互启动。服务A监听B的广播来启动B,服务B监听A的广播来启动A。经过实验,这个方案是可行的。

完!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了保证一个后台服务不被杀死,可以考虑以下几种方法。 首先,可以通过设置服务的优先级来提高其在系统中的重要性,从而减少被系统杀死的可能性。在Android中,可以使用startForeground()方法服务置于前台,并在通知栏显示一个持续存在的通知,使得用户意识到服务正在运行。 其次,可以使用startService()方法启动服务,并在服务的onStartCommand()方法中返回START_STICKY或START_REDELIVER_INTENT,这样当服务杀死后,系统会尝试重新启动服务,并尽可能恢复之前的状态。 此外,可以在服务中使用onTaskRemoved()方法,在服务杀死之前保存相关的数据或状态,以便在服务重新启动后恢复。可以使用SharedPreferences或将数据保存到数据库或文件中。 另外,为了节省资源并使服务更加省电,可以使用AlarmManager定时唤醒服务,执行相应的操作后再将服务置于休眠状态。 最后,为了防止系统对长时间运行的服务进行优化并杀死,可以在服务的onCreate()方法中调用startForegroundService()方法,并在启动服务后的一段时间内调用startForeground()方法进行前台展示,这样可以让系统认为服务正在进行一项重要的工作。 需要注意的是,以上方法只能尽量减少服务杀死的可能性,但并不能保证服务永远不会被杀死,因为系统为了保证整体的稳定性和资源管理,仍然有可能关闭一些不重要的后台服务

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值