@xujun94
2016-07-23T00:24:06.000000Z
字数 7558
阅读 1141
转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/52000680
我们知道Service和Activity一样是Android的四大组件之一,Service简称为后台服务,具有较高的优先级别。我们平时在Activity中直接开启Service,是运行在主线程的。如果想要执行耗时任务,我们必须自己开启线程。而IntentService是把任务放在子线程中执行的。
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
简单来说主要有一下几点
- Service是运行在子线程的;
- 多个请求会按启动的顺序执行,但是一次只会处理一个任务;
public class MyIntentService extends IntentService {
private static final String ACTION_DOWNLOAD = "com.szl.intentservicedemo.action.DOWNLOAD";
private static final String ACTION_UPLOAD = "com.szl.intentservicedemo.action.UPLOAD ";
private static final String EXTRA_PARAM1 = "com.szl.intentservicedemo.extra.PARAM1";
private static final String EXTRA_PARAM2 = "com.szl.intentservicedemo.extra.PARAM2";
public static final String TAG="tag";
public MyIntentService() {
super("MyIntentService");
}
//这里省略了若干个方法
//处理我们启动的Service
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_DOWNLOAD.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM1);
final String param2 = intent.getStringExtra(EXTRA_PARAM2);
handleDOwnload(param1, param2);
} else if (ACTION_UPLOAD.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM1);
final String param2 = intent.getStringExtra(EXTRA_PARAM2);
handleUpload(param1, param2);
}
}
}
}
<service
android:name=".MyIntentService"
android:exported="false">
</service>
Intent intent = new Intent(context, MyIntentService.class);
intent.setAction(ACTION_UPLOAD);
intent.putExtra(EXTRA_PARAM1, param1);
intent.putExtra(EXTRA_PARAM2, param2);
context.startService(intent);
public void onButtonClick(View view) {
switch (view.getId()) {
case R.id.btn_download:
MyIntentService.startActionDownLoad(MainActivity.this, "下载", "发起者主线程");
break;
case R.id.btn_upload:
MyIntentService.startActionUpload(MainActivity.this, "上传", "发起者主线程");
break;
default:
break;
}
}
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService(String name) {
super();
mName = name;
}
/**
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
*
* <p>If enabled is true,
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_REDELIVER_INTENT}, so if this process dies before
* {@link #onHandleIntent(Intent)} returns, the process will be restarted
* and the intent redelivered. If multiple Intents have been sent, only
* the most recent one is guaranteed to be redelivered.
*
* <p>If enabled is false (the default),
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
* dies along with it.
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
/**
* Unless you provide binding for your service, you don't need to implement this
* method, because the default implementation returns null.
* @see android.app.Service#onBind
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* This method is invoked on the worker thread with a request to process.
* Only one Intent is processed at a time, but the processing happens on a
* worker thread that runs independently from other application logic.
* So, if this code takes a long time, it will hold up other requests to
* the same IntentService, but it will not hold up anything else.
* When all requests have been handled, the IntentService stops itself,
* so you should not call {@link #stopSelf}.
*
* @param intent The value passed to {@link
* android.content.Context#startService(Intent)}.
*/
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
这里我们以startService()为例分析,从我们启动一个IntentService,调用的过程大概是这样的,
构造方法 ->onCreate()- >onStartCommand()- >onStart()->Service running-->
public IntentService(String name) {
super();
mName = name;
}
其实很简单,只是调用父类的构造方法,并保存我们的那么字段
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
简单来说,就是为我们初始化一个线程thread并启动它,并将线程的looper与我们的mServiceHandler绑定在一起。
* 3)接着我们来看onStartCommand()方法做了什么?
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
我们可以看到在onStartCommand转调了onStart()方法
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在onStart()方法里面其实就是用我们的mServiceHandler发送信息(mServiceHandler.sendMessage(msg);),这样在我们handleMessage()里面讲可以收到我们的信息,在handleMessage()里面有调用onHandleIntent()去处理我们的Intent,这就是为什么我们需要重写onHandleIntent的原因。
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
到此IntentService源码分析位置
转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/52000680
例子源码下载地址: http://download.csdn.net/detail/gdutxiaoxu/9583047