Android 的 Service 是四大組件之一恍飘,有著非常重要的地位熬词。下面來記錄一些重要的知識點(diǎn)牧氮。
常用方法
方法 | 說明 |
---|---|
startService() | 啟動服務(wù)(兩種啟動方式之一) |
bindService() | 綁定服務(wù)(兩種啟動方式之一) |
stopService() | 關(guān)閉服務(wù)(對應(yīng)startService) |
unbindService() | 解綁服務(wù)(對應(yīng)bindService) |
onCreate() | 創(chuàng)建服務(wù)(生命周期) |
onStartCommand() | 開始服務(wù)(生命周期) |
onDestroy() | 銷毀服務(wù)(生命周期) |
onBind() | 綁定服務(wù)(生命周期) |
onUnbind() | 解綁服務(wù)(生命周期) |
生命周期
startService
startService -> onCreate -> onStartCommand -> stopService -> onDestory
注意 :多次調(diào)用startService郭赐,onCreate 只會執(zhí)行一次更振,onStartCommand 會多次調(diào)用
bindService
bindService -> onCreate -> onBind -> unbindService -> onUnBind -> onDestory
同時使用 startService 和 bindService
startService -> onCreate -> onStartCommand -> bindService -> onBind -> unbindService -> onUnBind -> stopService -> onDestory
特別注意
- startService()和stopService()只能開啟和關(guān)閉Service鲫趁,無法操作Service
- bindService()和unbindService()可以操作Service
- startService開啟的Service斯嚎,調(diào)用者退出后Service仍然存在
- bindService開啟的Service,調(diào)用者退出后挨厚,Service隨著調(diào)用者銷毀
Service 的類型及應(yīng)用場景
Service 和 Thread 區(qū)別
Service和Thread之間沒有任何關(guān)系
名稱 | 相同點(diǎn) | 不同點(diǎn) |
---|---|---|
Service | 作用:執(zhí)行異步處理 | 1堡僻、運(yùn)行在主線程(不能處理耗時操作 否則ANR) 2、依賴進(jìn)程而非Activity |
Thread | 作用:執(zhí)行異步處理 | 1疫剃、運(yùn)行于工作線程 2钉疫、依賴某個Activity |
Service 可以和 Thread 配合使用處理耗時操作~
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//新建工作線程
new Thread(new Runnable() {
@Override
public void run() {
// 開始執(zhí)行后臺任務(wù)
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
class MyBinder extends Binder {
public void service_connect_Activity() {
//新建工作線程
new Thread(new Runnable() {
@Override
public void run() {
// 執(zhí)行具體的下載任務(wù)
}
}).start();
}
}
Service 和 IntentService 區(qū)別
IntentService是Android里面的一個封裝類,繼承自四大組件之一的Service巢价。用來處理異步請求陌选,實(shí)現(xiàn)多線程。(常用于 按順序蹄溉、在后臺執(zhí)行 的下載場景)
IntentService源碼
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);
}
}
public IntentService(String name) {
super();
mName = name;
}
@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(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable 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
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
從源碼可以看出
- IntentService本質(zhì)是采用Handler & HandlerThread
- 通過HandlerThread單獨(dú)開啟一個名為IntentService的線程
- 創(chuàng)建一個名叫ServiceHandler的內(nèi)部Handler
- 把內(nèi)部Handler與HandlerThread所對應(yīng)的子線程進(jìn)行綁定
- 通過onStartCommand()傳遞給服務(wù)intent咨油,依次插入到工作隊列中,并逐個發(fā)送給onHandleIntent()
- 通過onHandleIntent()來依次處理所有Intent請求對象所對應(yīng)的任務(wù)
因此依據(jù)源碼注釋提示柒爵,復(fù)寫方法onHandleIntent()役电,再在里面根據(jù)Intent的不同進(jìn)行不同的線程操作就可以了。
注意事項(xiàng)
- IntentService是以隊列執(zhí)行的棉胀,如果一個任務(wù)正在IntentService中執(zhí)行法瑟,此時再發(fā)送一個新的任務(wù)請求,這個新的任務(wù)會一直等待直到前面一個任務(wù)執(zhí)行完畢才開始執(zhí)行唁奢。
原因:多次startService時霎挟,onCreate只執(zhí)行一次,只會創(chuàng)建一個工作線程麻掸!卻會多次執(zhí)行onStartCommand酥夭,由源碼可見,只是把消息加入消息隊列中等待執(zhí)行~
- 不要使用bindService 啟動 IntentService
源碼中,onBind()是默認(rèn)返回null的熬北,而采用bindService() 啟動 IntentService的生命周期是:onCreate() —>onBind()—>onunbind()—>onDestory()
并不會調(diào)用onstart()或者onstartcommand()方法疙描,所以不會將消息發(fā)送到消息隊列,那么onHandleIntent()將不會回調(diào)讶隐,即無法實(shí)現(xiàn)多線程的操作起胰。
**如上介紹了IntentService,Service 和 IntentService 區(qū)別主要是
名稱 | 不同點(diǎn) |
---|---|
Service | 1巫延、依賴于應(yīng)用程序的主線程(不是獨(dú)立的進(jìn)程 or 線程)2效五、需要主動調(diào)用stopSelft()來結(jié)束服務(wù) |
IntentService | 1、創(chuàng)建一個工作線程來處理多線程任務(wù) 2炉峰、IntentService不需要(在所有intent被處理完后畏妖,系統(tǒng)會自動關(guān)閉服務(wù)) |