一,概述
在平时安卓的开发过程中,若遇到耗时操作的话,为了尽可能的减少ANR (Application Not Responding),我们都会把耗时操作放在Service中执行。
但是呢,安卓中Service默认是执行在主线程中的,所以一般情况下我们会开启一个子线程进行操作。由于大多数启动服务都不必同时处理多个请求(实际上,这种多线程情况可能很危险),因此使用 IntentService 类实现服务也许是最好的选择。
二,IntentService介绍
IntentService继承自Service类,是用来处理异步请求的,它会执行以下操作:
- ** 创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent。**
- ** 创建工作队列,用于将一个 Intent 逐一传递给 onHandleIntent() 实现,这样就永远不必担心多线程问题。 **
- ** 在处理完所有启动请求后停止服务,因此永远不必调用 stopSelf()。**
- ** 提供 onBind() 的默认实现(返回 null)。**
- ** 提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent() 实现。**
综上所述,我们只需实现 onHandleIntent() 来完成客户端提供的工作即可。(还需要为服务提供小型构造函数。)
代码实现
以下是 IntentService 的实现示例:
public class MyIntentService extends IntentService {
private String TAG = "MyIntentService";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public MyIntentService() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "这是onHandleIntent方法");
/**
* 让程序睡眠10秒钟
*/
long endTime = System.currentTimeMillis() + 10 * 1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
Log.d(TAG, "当前线程id:" + Thread.currentThread().getId());
wait(endTime - System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "启动了IntentService服务");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "IntentService服务已销毁");
}
}
可以看到,IntentService的使用非常简单,一般情况下只需要一个构造函数和一个 onHandleIntent() 实现即可。如果需要重写其他回调方法(如 onCreate()、onStartCommand() 或 onDestroy()),确保调用超类实现,以便 IntentService 能够妥善处理工作线程的生命周期。
MainActivity代码:
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
/**
* 启动服务
*/
Intent intent = new Intent(MainActivity.this, MyIntentService.class);
startService(intent);
Log.d(TAG, "当前线程id:" + Thread.currentThread().getId());
}
}
在这个例子中,我在IntentService里面的操作是睡眠10秒钟,在onHandleIntent()里执行我们需要的操作时,程序创建了另一个工作线程用来执行该操作,当操作执行完毕之后,IntentService就立即销毁了,它不像Service一直在后台运行。说到这里,很多读者可能会认为它不就是和Thread非常像吗,既然要进行耗时操作,为什么不用Thread和Handler而使用IntentService呢?因为它是一个服务,所以导致它的优先级比单纯的线程要高很多,当内存不足时不容易被系统杀死,所以IntentService比较适合执行一些高优先级的后台任务。在平时开发过程中,若要进行一些文件下载或者上传,可以用到IntentService,非常方便。
以下是打印出来的日志
07-18 10:06:38.102 16655-16655/com.neworin.intentservicedemo D/MainActivity: 当前线程id:1
07-18 10:06:38.119 16655-16655/com.neworin.intentservicedemo D/MyIntentService: 启动了IntentService服务
07-18 10:06:38.121 16655-28044/com.neworin.intentservicedemo D/MyIntentService: 这是onHandleIntent方法
07-18 10:06:38.121 16655-28044/com.neworin.intentservicedemo D/MyIntentService: 当前线程id:195
07-18 10:06:48.125 16655-16655/com.neworin.intentservicedemo D/MyIntentService: IntentService服务已销毁
平时如果你的需求可以使用IntentService来做,可以尽可能的使用,但是若考虑到同时处理多个请求的情况,还是需要用Service,IntentService并不适合。