使用一個開新工作線程處理一些耗時任務后荆隘,如何通知到啟動它的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)滨溉。
親什湘,給個贊鼓勵一下吧~