2015年7月22日星期三

Android服务之IntentService

服务中的代码默认运行在主线程当中,如果直接在服务里去处理一些耗时的逻辑,很容易出现ANR--即万恶的Application Not Responding。故此时需要用到Android多线程编程的技术,我们应该在服务的每个具体的方法开启一下子线程,然后再这里去处理那些耗时的逻辑,示例如下:

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
            return null;
    }
    @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
             new Thread(new Runnable() {
                    @Override
                     public void run() {
                     // 处理具体的逻辑
                     }
              }).start();
              return super.onStartCommand(intent, flags, startId);
           }
 }

这种服务一旦启动,就会一直处于运行状态,必须调用stopService()或者stopService()方法才能使其停止,我们可以在run()中“//处理具体的逻辑”后调用 stopSelf()方法来实现服务执行完毕后的自动停止功能。

问题又来了,这样比较繁琐不好记,要么忘记开启线程,要么忘记调用stopService()方法,我们会经常性地忽视之。


为了可以简单地创建一个异步的、会自动停止的服务,IntentService闪亮登场啦。

一、新建MyIntentService类继承自IntentService,如下,

public class MyIntentService extends IntentService {

public MyIntentService() {
super("MyIntentService"); // 调用父类的有参构造函数
// TODO Auto-generated constructor stub
}

@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
// 打印当前线程的id
Log.d("MyIntentService", "Thread id is "
+ Thread.currentThread().getId());
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyIntentService", "onDestroy executed");
}


}

可以看到,MyIntentService类分三个部分:

  1. 是一个无参数的构造函数,须在构造函数内部调用父类的有参构造函数。
  2. 实现onHandleIntent()抽象方法,其中处理具体逻辑,且不用担心ANR问题(因为这个方法已经是在子线程中运行的)。为证实,我们Log打印当前线程的id
  3. 重写了onDestroy()方法,其在服务运行结束时运行。 
二、新建Button响应启动MyIntentService服务,并且打印主线程的id,关键代码如下,


@Override
public void onClick(View v) {
switch (v.getId()) {
                .........
case R.id.start_intent_service:
// 打印主线程的id
Log.d("MainActivity", "Thread is " + Thread.currentThread().getId());
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);
default:
break;
}


三、很重要一点,切莫忘记在AndroidManifest对我们的MyIntentService服务注册

四、运行。

   点击StartIntentService按钮,LogCat输出如下,
 

 可以看到,MyIntentService和MainActivity所在的线程id是不一样的;onDestroy()方法得到执行,说明MyIntentService服务运行技术后自动停止销毁啦。

这就是,集开启线程和自动停止于一身的,金光闪亮的IntentService。

LOL

没有评论:

发表评论