Android Service相關(guān)

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類型場景

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ù))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市讲冠,隨后出現(xiàn)的幾起案子瓜客,更是在濱河造成了極大的恐慌,老刑警劉巖竿开,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谱仪,死亡現(xiàn)場離奇詭異,居然都是意外死亡否彩,警方通過查閱死者的電腦和手機(jī)疯攒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來列荔,“玉大人敬尺,你說我怎么就攤上這事√悖” “怎么了砂吞?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長崎溃。 經(jīng)常有香客問我蜻直,道長,這世上最難降的妖魔是什么袁串? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任概而,我火速辦了婚禮,結(jié)果婚禮上囱修,老公的妹妹穿的比我還像新娘赎瑰。我一直安慰自己,他們只是感情好破镰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布餐曼。 她就那樣靜靜地躺著压储,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晋辆。 梳的紋絲不亂的頭發(fā)上渠脉,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天宇整,我揣著相機(jī)與錄音瓶佳,去河邊找鬼。 笑死鳞青,一個胖子當(dāng)著我的面吹牛霸饲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臂拓,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼厚脉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胶惰?” 一聲冷哼從身側(cè)響起傻工,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孵滞,沒想到半個月后中捆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坊饶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年泄伪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匿级。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟋滴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痘绎,到底是詐尸還是另有隱情津函,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布孤页,位于F島的核電站尔苦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏散庶。R本人自食惡果不足惜蕉堰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悲龟。 院中可真熱鬧屋讶,春花似錦、人聲如沸须教。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乐疆,卻和暖如春划乖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挤土。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工琴庵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仰美。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓迷殿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咖杂。 傳聞我的和親對象是個殘疾皇子庆寺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容