使用一個(gè)開(kāi)新工作線(xiàn)程處理一些耗時(shí)任務(wù)后,如何通知到啟動(dòng)它的Activity?
這篇文章主要用的是Android為我們提供的一種封裝好的工具——"ResultReceiver"
【IntentService和ResultReceiver】

service.gif
IntentService繼承自service,在IntentService中我們開(kāi)啟一個(gè)線(xiàn)程執(zhí)行下載任務(wù)(service和你的app其實(shí)是在一個(gè)線(xiàn)程中,因此不想阻塞主線(xiàn)程的話(huà)必須開(kāi)啟新的線(xiàn)程。
//在這里根據(jù)url進(jìn)行下載文件,并通過(guò)receiver把需要更新的progressbar的值放在bundle傳過(guò)去
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();
}
}
}
//記得注冊(cè)<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中定義一個(gè)廣播接收器繼承ResultReceiver,ResultReceiver允許我們接收來(lái)自service中發(fā)出的廣播
//使用ResultReceiver接收來(lái)自DownloadService的下載進(jìn)度通知
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ù)你的進(jìn)度可以設(shè)置現(xiàn)在的進(jìn)度值。
//(false)就是滾動(dòng)條的當(dāng)前值自動(dòng)在最小到最大值之間來(lái)回移動(dòng),形成這樣一個(gè)動(dòng)畫(huà)效果
progressDialog.setIndeterminate(false);
progressDialog.setProgress(progress);
if (progress == 100) {
progressDialog.dismiss();
//自動(dòng)安裝下載的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);
}
}
}
}
說(shuō)明:
1.IntentService是Service類(lèi)的子類(lèi),用來(lái)處理異步請(qǐng)求??蛻?hù)端可以通過(guò)startService(Intent)方法傳遞請(qǐng)求給IntentService,IntentService通過(guò)worker thread處理每個(gè)Intent對(duì)象,執(zhí)行完所有的工作之后自動(dòng)停止Service。說(shuō)明:worker thread處理所有通過(guò)傳遞過(guò)來(lái)的請(qǐng)求,創(chuàng)建一個(gè)worker queue,一次只傳遞一個(gè)intent到onHandleIntent中,從而不必?fù)?dān)心多線(xiàn)程帶來(lái)的問(wèn)題。處理完畢之后自動(dòng)調(diào)用stopSelf()方 法;默認(rèn)實(shí)現(xiàn)了Onbind()方法,返回值為null;
使用IntentService需要兩個(gè)步驟:
1、寫(xiě)構(gòu)造函數(shù)
2、復(fù)寫(xiě)onHandleIntent()方法
2.activity調(diào)用service時(shí),傳遞的廣播接收器需要傳入一個(gè)Handler,并且這個(gè)Handler是可以為null的。這個(gè)Handler的作用只有一個(gè),就是控制回調(diào)函數(shù)執(zhí)行在創(chuàng)建Handler的線(xiàn)程。如果在Activity主線(xiàn)程創(chuàng)建的handler實(shí)例,則回調(diào)也會(huì)在主線(xiàn)程執(zhí)行。就可以直接在回調(diào)中操作UI。也就是在onReceiveResult更新UI。
3.在intentservice中最主要的方法是通過(guò) receiver.send方法就參數(shù)傳遞給activity。源碼就是在調(diào)用send方法的線(xiàn)程中執(zhí)行onReceiveResult回調(diào)。
親,給個(gè)贊鼓勵(lì)一下吧~