Android IntentService和ResultReceiver的異步處理實現(xiàn)service與activity的交互

使用一個開新工作線程處理一些耗時任務后荆隘,如何通知到啟動它的Activity?

這篇文章主要用的是Android為我們提供的一種封裝好的工具——"ResultReceiver"

【IntentService和ResultReceiver】

service.gif

IntentService繼承自service赴背,在IntentService中我們開啟一個線程執(zhí)行下載任務(service和你的app其實是在一個線程中椰拒,因此不想阻塞主線程的話必須開啟新的線程。

//在這里根據(jù)url進行下載文件凰荚,并通過receiver把需要更新的progressbar的值放在bundle傳過去
public class DownloadService extends IntentService {
    public static final int UPDATE_PROGRESS = 8344;
    public DownloadService() {
        super("DownloadService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        String urlToDownload = intent.getStringExtra("url");
        ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
        HttpURLConnection connection ;
        try {
            URL url = new URL(urlToDownload);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            // this will be useful so that you can show a typical 0-100% progress bar
            int fileLength = connection.getContentLength();
            Log.d("test","fileLength:"+fileLength);
            // download the file
            InputStream input = connection.getInputStream();
            OutputStream output = new FileOutputStream("/sdcard/new.apk");
            byte data[] = new byte[2048];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                Bundle resultData = new Bundle();
                resultData.putInt("progress" ,(int) (total * 100 / fileLength));
                receiver.send(UPDATE_PROGRESS, resultData);
                output.write(data, 0, count);
            }
            output.flush();
            output.close();
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
//記得注冊<service android:name=".DownloadService"/>

activity中這樣調(diào)用DownloadService

  progressDialog.show();                                                
  Intent intent = new Intent(this, DownloadService.class);              
  intent.putExtra("url",url);                                           
  intent.putExtra("receiver", new DownloadReceiver(new Handler()));     
  startService(intent);                                                 

activity中定義一個廣播接收器繼承ResultReceiver燃观,ResultReceiver允許我們接收來自service中發(fā)出的廣播

 //使用ResultReceiver接收來自DownloadService的下載進度通知                                                                
 private class DownloadReceiver extends ResultReceiver {                                                     
     public DownloadReceiver(Handler handler) {                                                              
         super(handler);                                                                                     
     }                                                                                                       

     @Override                                                                                               
     protected void onReceiveResult(int resultCode, Bundle resultData) {                                     
     super.onReceiveResult(resultCode, resultData);                                                          
         if (resultCode == DownloadService.UPDATE_PROGRESS) {                                                
             int progress = resultData.getInt("progress");                                                   
             //(true)就是根據(jù)你的進度可以設置現(xiàn)在的進度值。                                                                     
             //(false)就是滾動條的當前值自動在最小到最大值之間來回移動便瑟,形成這樣一個動畫效果                                                    
             progressDialog.setIndeterminate(false);                                                         
             progressDialog.setProgress(progress);                                                           
             if (progress == 100) {                                                                          
                 progressDialog.dismiss();         
          //自動安裝下載的apk                                                          
                 File file=new File("/sdcard/new.apk");                                                      
                 Intent installIntent = new Intent(Intent.ACTION_VIEW);                                      
                 installIntent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
                 installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                      
                 startActivity(installIntent);                                                               
             }                                                                                               
         }                                                                                                   
     }                                                                                                       
 }                                                                                                           

說明:

1.IntentService是Service類的子類缆毁,用來處理異步請求〉酵浚客戶端可以通過startService(Intent)方法傳遞請求給IntentService脊框,IntentService通過worker thread處理每個Intent對象,執(zhí)行完所有的工作之后自動停止Service践啄。說明:worker thread處理所有通過傳遞過來的請求浇雹,創(chuàng)建一個worker queue,一次只傳遞一個intent到onHandleIntent中屿讽,從而不必擔心多線程帶來的問題昭灵。處理完畢之后自動調(diào)用stopSelf()方 法;默認實現(xiàn)了Onbind()方法伐谈,返回值為null虎锚;

使用IntentService需要兩個步驟:
1、寫構造函數(shù)
2衩婚、復寫onHandleIntent()方法

2.activity調(diào)用service時,傳遞的廣播接收器需要傳入一個Handler效斑,并且這個Handler是可以為null的非春。這個Handler的作用只有一個,就是控制回調(diào)函數(shù)執(zhí)行在創(chuàng)建Handler的線程缓屠。如果在Activity主線程創(chuàng)建的handler實例奇昙,則回調(diào)也會在主線程執(zhí)行。就可以直接在回調(diào)中操作UI敌完。也就是在onReceiveResult更新UI储耐。

3.在intentservice中最主要的方法是通過 receiver.send方法就參數(shù)傳遞給activity。源碼就是在調(diào)用send方法的線程中執(zhí)行onReceiveResult回調(diào)滨溉。


親什湘,給個贊鼓勵一下吧~

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末长赞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闽撤,更是在濱河造成了極大的恐慌得哆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哟旗,死亡現(xiàn)場離奇詭異贩据,居然都是意外死亡,警方通過查閱死者的電腦和手機闸餐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門饱亮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舍沙,你說我怎么就攤上這事近上。” “怎么了场勤?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵戈锻,是天一觀的道長。 經(jīng)常有香客問我和媳,道長格遭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任留瞳,我火速辦了婚禮拒迅,結果婚禮上,老公的妹妹穿的比我還像新娘她倘。我一直安慰自己璧微,他們只是感情好,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布硬梁。 她就那樣靜靜地躺著前硫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荧止。 梳的紋絲不亂的頭發(fā)上屹电,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音跃巡,去河邊找鬼危号。 笑死,一個胖子當著我的面吹牛素邪,可吹牛的內(nèi)容都是我干的外莲。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼兔朦,長吁一口氣:“原來是場噩夢啊……” “哼偷线!你這毒婦竟也來了磨确?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤淋昭,失蹤者是張志新(化名)和其女友劉穎俐填,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翔忽,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡英融,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了歇式。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驶悟。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖材失,靈堂內(nèi)的尸體忽然破棺而出痕鳍,到底是詐尸還是另有隱情,我是刑警寧澤龙巨,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布笼呆,位于F島的核電站,受9級特大地震影響旨别,放射性物質(zhì)發(fā)生泄漏诗赌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一秸弛、第九天 我趴在偏房一處隱蔽的房頂上張望铭若。 院中可真熱鬧,春花似錦递览、人聲如沸叼屠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镜雨。三九已至,卻和暖如春儿捧,著一層夾襖步出監(jiān)牢的瞬間冷离,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工纯命, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痹栖。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓亿汞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親揪阿。 傳聞我的和親對象是個殘疾皇子疗我,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361

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