用IntentService 與ResultReceiver連線web service

idaretobe發表於2015-01-09

IntentService 與ResultReceiver的搭配可以很方便地處理簡單的非同步問題,用這種方法可以避免啟動一大堆錯綜複雜且難以管理的執行緒。

 

舉個例子,你想從web service取一些資料:
1. 呼叫startService。
2. service中開始操作處理,並且通過訊息告訴activity處理已經開始。
3. activity處理訊息並且顯示進度條
4. service完成處理並且返回給activity需要的資料。
5. activity處理資料。
6. service通過訊息告訴activity處理完成,並且kill掉自己。
7. activity取得訊息並且結束掉進度條。


一、先介紹一下IntentService

IntentService繼承自Service,從原始碼上看,它是Service、HandlerThread和Handler的強強聯合。具有任務佇列,順序處理,

當處理完全部任務後,它會自動kill掉自己,完全不用我們操心。大家有興趣可以去查一下資料。

二、ResultReceiver

這個是用來接收返回資訊的類,來自 android.os.ResultReceiver。


三、使用方法:

複製程式碼
public class HomeActivity extends Activity implements ResultReceiver {
public void onCreate(Bundle savedInstanceState) {
...
final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, QueryService.class);
intent.putExtra("receiver", this);
intent.putExtra("command", "query");
startService(intent);
}

public void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
case RUNNING:
//show progress
break;
case FINISHED:
List results = resultData.getParcelableList("results");
// do something interesting
// hide progress
break;
case ERROR:
// handle the error;
break;
}
}
service程式碼:
public class QueryService extends IntentService {
protected void onHandleIntent(Intent intent) {
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
String command = intent.getStringExtra("command");
Bundle b = new Bundle();
if(command.equals("query") {
receiver.send(STATUS_RUNNING, Bundle.EMPTY);
try {
// get some data or something
b.putParcelableArrayList("results", results);
receiver.send(STATUS_FINISHED, b)
} catch(Exception e) {
b.putString(Intent.EXTRA_TEXT, e.toString());
receiver.send(STATUS_ERROR, b);
}
}
this.stopSelf();
}
}
複製程式碼

相關文章