Service和IntentService的区别1

Service

Service 是长期运行在后台的应用程序组件。

Service 不是一个单独的进程,它和应用程序在同一个进程中,Service 也不是一个线程,它和线程没有任何关系,所以它不能直接处理耗时操作。如果直接把耗时操作放在 Service 的 onStartCommand() 中,很容易引起 ANR .如果有耗时操作就必须开启一个单独的线程来处理。

IntentService

IntentService 是继承于 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。

而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 那么,用 IntentService 有什么好处呢?首先,我们省去了在 Service 中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止 Service。

接下来让我们来看看如何使用,写一个Demo来模拟两个耗时操作。

比较Service 和 IntentService 处理耗时操作的结果

先分别在 Service 和 IntentService 里面处理耗时,看看是什么结果。首先创建一个 Service 服务,在其 onStartCommand() 中执行一个20s的耗时。

public class MyService extends Service { String TAG = "MyService";
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Logger.d(TAG, "-->开始睡眠");
    try {
          Thread.sleep(20000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
    Logger.d(TAG, "-->睡眠结束");
    return super.onStartCommand(intent, flags, startId);

  }

  public static void startMyService(Context mContext) {
    Intent intent = new Intent(mContext, MyService.class);
    mContext.startService(intent);
  }
}

结果发生ANR。 ANR

然后试试 IntentService

public class MyIntentService extends IntentService {
  String TAG = "MyIntentService";
  public MyIntentService() {
    super("luwenje");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    Logger.d(TAG, "-->开始睡眠");
    try {
          Thread.sleep(20000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
    Logger.d(TAG, "-->睡眠结束");
  }


  public static void startMyIntentService(Context mContext){
    Intent intent = new Intent(mContext,MyIntentService.class);
    mContext.startService(intent);
  }
}       

IntentService 默认实现了 OnBind(),返回值为 null。

IntentService 必须实现 MyIntentService() 构造方法和 onHandleIntent(Intent intent)。

注意:
IntentService 的构造函数一定是参数为空的构造函数,然后再在其中调用 super(“name”) 这种形式的构造函数。
因为 Service 的实例化是系统来完成的,而且系统是用参数为空的构造函数来实例化Service的。

启动 IntentService,果然没有发生ANR。

为了看看 IntentService 异步处理的能力 我想不如这样来极端的启动它。

for (int i = 0; i < 20; i++) {
  MyIntentService.startMyIntentService(this);
}   

循环20次启动 IntentSerivce 然后我们来看看log信息。

Log日志 结果是20组 有序的这样开始-结束 开始-结束,所以IntentService是等前面的请求结束之后再执行下一个。 这个证实了 IntentService 采用单独的线程每次只从队列中拿出一个请求进行处理

IntentService 的生命周期和执行过程

再来写个 demo 看看 IntentService 的生命周期和执行过程

public class MyIntentService2 extends IntentService {
  String TAG = "MyIntentService2";
  public MyIntentService2() {
    super("luwenjie2");
  }

  @Override
  public void onCreate() {
    Logger.d(TAG,"onCreate");
    super.onCreate();
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Logger.d(TAG,"onStartCommand");
    return super.onStartCommand(intent, flags, startId);
  }

  @Override
  public void onStart(Intent intent, int startId) {
    Logger.d(TAG,"onStart");
      super.onStart(intent, startId);
  }

  @Override
  public IBinder onBind(Intent intent) {
    Logger.d(TAG,"onBind");
    return super.onBind(intent);
  }

  @Override
  public void setIntentRedelivery(boolean enabled) {
    super.setIntentRedelivery(enabled);
    Logger.d(TAG,"setIntentRedelivery");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务
    String action = intent.getExtras().getString("param");
    if (action.equals("oper1")) {
      Logger.d("Operation1");
    }else if (action.equals("oper2")) {
      Logger.d("Operation2");
    }

    try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
  }

  @Override
  public void onDestroy() {
    Logger.d(TAG,"onDestroy");
    super.onDestroy();
  }
}

我把生命周期方法全打印出来了,待会我们来看看它执行的过程是怎样的。接下来是 Activity,在 Activity 中创建2个带不同值的 Intent 来启动 IntentService:

//Operation 1
Intent startServiceIntent = new Intent(this,MyIntentService2.class);
Bundle bundle = new Bundle();
bundle.putString("param", "oper1");
startServiceIntent.putExtras(bundle);
startService(startServiceIntent);

//Operation 2
Intent startServiceIntent2 = new Intent(this,MyIntentService2.class);
Bundle bundle2 = new Bundle();
bundle2.putString("param", "oper2");
startServiceIntent2.putExtras(bundle2);
startService(startServiceIntent2);

日志打印的顺序是:
onCreate -> onStartCommand -> onStart -> onStartCommand -> onStart -> Operation1 -> Operation2 -> onDestroy

从结果可以看到,onCreate 方法只执行了一次,而 onStartCommand 和 onStart 方法执行了两次,开启了两个 Work Thread,这就证实了之前所说的,启动多次,但IntentService 的实例只有一个,这跟传统的 Service 是一样的。Operation1 也是先于 Operation2 打印,并且我让两个操作间停顿了2s,最后是 onDestroy 销毁了IntentService。

总结

这就是IntentService,一个方便我们处理业务流程的类,它是一个Service,但是比Service更智能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值