Service和IntentService的區(qū)別

多線程的應用

  • 繼承Thread類
  • 實現(xiàn)Runnable接口
  • AsyncTask
  • Handler
  • HandlerThread
  • IntentService

實現(xiàn)步驟

步驟1:定義IntentService的子類:傳入線程名稱、復寫onHandleIntent()方法
步驟2:在Manifest.xml中注冊服務
步驟3:在Activity中開啟Service服務

package com.newbeeair.cleanser.services;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.joshdholtz.sentry.Sentry;
import com.kf5sdk.init.KF5SDKInitializer;
import com.newbeeair.cleanser.BuildConfig;
import com.newbeeair.cleanser.constants.AppConstants;
import com.newbeeair.cleanser.umeng.PushManager;
import com.newbeeair.cleanser.utils.DebugLog;
import com.newbeeair.cleanser.utils.PreferenceUtils;
import com.umeng.analytics.MobclickAgent;
import com.youzan.sdk.YouzanSDK;

import cn.sharesdk.framework.ShareSDK;

/**
 * <pre>
 *     author : lzy
 *     e-mail : zanyang.lin@newbeeair.com
 *     time   : 2017/07/11
 *     desc   : 初始化IntentService
 * </pre>
 */

public class InitService extends IntentService {

    private static final String ACTION_INIT = "com.newbeeair.cleanser.action.init";


    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public InitService() {
        super("InitService");
    }

    public static void startInit(Context context) {

        Intent intent = new Intent(context, InitService.class);
        intent.setAction(ACTION_INIT);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        DebugLog.e("initService onHandleIntent");

        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_INIT.equals(action)) {
                DebugLog.e(">>>>>>>>>>>>>>>>>>>>>>>>>>");
                PreferenceUtils.initialize(this);
                initYiChuangYun(this);
                //initGrowingIO(this);
                initUmengPush(this);
                initFresco(this);

                initSentry(this);
                initYouzan(this);
                initUmeng(this);

                initShareSDK(this);


            }
        }

    }

    private void initShareSDK(Context context) {
        ShareSDK.initSDK(context);
    }

    private void initGrowingIO(Context context) {
    }


    private void initFresco(Context context) {
        Fresco.initialize(context);
    }

    private void initYiChuangYun(Context context) {
        KF5SDKInitializer.initialize(context);
    }

    private void initUmengPush(Context context) {
        PushManager.getInstance(context).registPushAgent();
    }

    private void initYouzan(Context context) {
        YouzanSDK.init(context, AppConstants.YOUZAN_USERAGENT);
    }

    private void initSentry(Context context) {
        Sentry.init(context, BuildConfig.SENTRY_DSN);
    }

    private void initUmeng(Context context) {
        MobclickAgent.setDebugMode(false);// 測試模式
        MobclickAgent.openActivityDurationTrack(false);// 禁止默認的頁面統(tǒng)計方式
        MobclickAgent.enableEncrypt(true);// 日志加密
        MobclickAgent.setScenarioType(context, MobclickAgent.EScenarioType.E_UM_NORMAL);// 場景設置
    }
}

步驟2:在Manifest.xml中注冊服務

 <service android:name=".services.InitService" />

區(qū)別

Service

Service 是長期運行在后臺的應用程序組件。

Service 不是一個單獨的進程,它和應用程序在同一個進程中黍衙,Service 也不是一個線程,它和線程沒有任何關(guān)系,所以它不能直接處理耗時操作。如果直接把耗時操作放在 Service 的 onStartCommand() 中誓焦,很容易引起 ANR .如果有耗時操作就必須開啟一個單獨的線程來處理

IntentService

IntentService 是繼承于 Service 并處理異步請求的一個類,在 IntentService 內(nèi)有一個工作線程來處理耗時操作着帽,啟動 IntentService 的方式和啟動傳統(tǒng) Service 一樣杂伟,同時,當任務執(zhí)行完后仍翰,IntentService 會自動停止赫粥,而不需要我們?nèi)ナ謩涌刂啤A硗庥杞瑁梢詥?IntentService 多次越平,而每一個耗時操作會以工作隊列的方式在IntentService 的 onHandleIntent 回調(diào)方法中執(zhí)行翠肘,并且齐饮,每次只會執(zhí)行一個工作線程,執(zhí)行完第一個再執(zhí)行第二個悼瘾,以此類推龟再。

而且书闸,所有請求都在一個單線程中,不會阻塞應用程序的主線程(UI Thread)利凑,同一時間只處理一個請求浆劲。 那么,用 IntentService 有什么好處呢哀澈?首先牌借,我們省去了在 Service 中手動開線程的麻煩,第二割按,當操作完成時膨报,我們不用手動停止 Service

源碼分析

// IntentService源碼中的 onCreate() 方法
@Override
public void onCreate() {
    super.onCreate();
    // HandlerThread繼承自Thread,內(nèi)部封裝了 Looper
    //通過實例化andlerThread新建線程并啟動
    //所以使用IntentService時不需要額外新建線程
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    //獲得工作線程的 Looper,并維護自己的工作隊列
    mServiceLooper = thread.getLooper();
    //將上述獲得Looper與新建的mServiceHandler進行綁定
    //新建的Handler是屬于工作線程的现柠。
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

//IntentService的handleMessage方法把接收的消息交給onHandleIntent()處理
//onHandleIntent()是一個抽象方法院领,使用時需要重寫的方法
    @Override
    public void handleMessage(Message msg) {
        // onHandleIntent 方法在工作線程中執(zhí)行,執(zhí)行完調(diào)用 stopSelf() 結(jié)束服務够吩。
        onHandleIntent((Intent)msg.obj);
      //onHandleIntent 處理完成后 IntentService會調(diào)用 stopSelf() 自動停止比然。
        stopSelf(msg.arg1);
    }
}

////onHandleIntent()是一個抽象方法,使用時需要重寫的方法
@WorkerThread
protected abstract void onHandleIntent(Intent intent);


  • 總結(jié)
    從上面源碼可以看出周循,IntentService本質(zhì)是采用Handler & HandlerThread方式:
    通過HandlerThread單獨開啟一個名為IntentService的線程
    創(chuàng)建一個名叫ServiceHandler的內(nèi)部Handler
    把內(nèi)部Handler與HandlerThread所對應的子線程進行綁定
    通過onStartCommand()傳遞給服務intent强法,依次插入到工作隊列中,并逐個發(fā)送給onHandleIntent()
    通過onHandleIntent()來依次處理所有Intent請求對象所對應的任務
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末湾笛,一起剝皮案震驚了整個濱河市饮怯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迄本,老刑警劉巖硕淑,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嘉赎,居然都是意外死亡置媳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門公条,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拇囊,“玉大人,你說我怎么就攤上這事靶橱×认” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵关霸,是天一觀的道長传黄。 經(jīng)常有香客問我,道長队寇,這世上最難降的妖魔是什么膘掰? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮佳遣,結(jié)果婚禮上识埋,老公的妹妹穿的比我還像新娘。我一直安慰自己零渐,他們只是感情好窒舟,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诵盼,像睡著了一般惠豺。 火紅的嫁衣襯著肌膚如雪银还。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天洁墙,我揣著相機與錄音见剩,去河邊找鬼。 笑死扫俺,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的固翰。 我是一名探鬼主播狼纬,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骂际!你這毒婦竟也來了疗琉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤歉铝,失蹤者是張志新(化名)和其女友劉穎盈简,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體太示,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡柠贤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了类缤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臼勉。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖餐弱,靈堂內(nèi)的尸體忽然破棺而出宴霸,到底是詐尸還是另有隱情,我是刑警寧澤膏蚓,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布瓢谢,位于F島的核電站,受9級特大地震影響驮瞧,放射性物質(zhì)發(fā)生泄漏氓扛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一剧董、第九天 我趴在偏房一處隱蔽的房頂上張望幢尚。 院中可真熱鬧,春花似錦翅楼、人聲如沸尉剩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽理茎。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間皂林,已是汗流浹背朗鸠。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留础倍,地道東北人烛占。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像沟启,于是被迫代替她去往敵國和親忆家。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

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