私のアプリは、バックグラウンドで外部ハードウェアと同期しているService
に依存しています。このサービスはメインスレッドで動作するため、IntentServiceを使用して非同期で大量の作業を行います。ここでは、制御フローを説明するためのコードのminimalized例です。Androidサービスは、IntentService用のResultReceiverを拡張し、CREATORを実装する方法は?
public class MyService extends Service {
private final Handler handler = new Handler();
void someMethodDoesCallBarAsynchronously(){
Intent i = new Intent(this, MyIntentService.class);
i.putAction(ACTION_FOO);
i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(handler));
startService(toGetScannerStatus);
}
void receivedFooResult(String bar){
//...
}
public class MyResultReceiver extends ResultReceiver{
public MyResultReceiver(Handler handler){
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
switch(resultCode){
case RESULT_CODE_FOO:
receivedFooResult(resultData.getString(FOO_RESULT));
break;
}
}
}
}
public class MyIntentService extends IntentService {
public MyIntentService(){super("MyIntentService");}
@Override
protected void onHandleIntent(Intent intent) {
switch (intent.getAction()) {
case ACTION_FOO:
ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER);
Bundle bundle = new Bundle()
bundle.putString(FOO_RESULT, foo());
receiver.send(RESULT_CODE_FOO, b);
break;
}
}
、半年や一部の更新後に、AndroidのメーカーはMyResultReceiver
がParcelableを実装していますが、CREATORフィールドを提供していないと文句を言い。問題1、MyResultReceiverは内部クラスなので、私はそれを自分のクラスに入れなければなりません。 MyServiceへの参照を保持する必要があるため、static
にできません。それでもまだ簡単です:
public class MyService extends Service {
private final Handler handler = new Handler();
void someMethodDoesCallBarAsynchronously(){
Intent i = new Intent(this, MyIntentService.class);
i.putAction(ACTION_FOO);
i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(this, handler));
startService(toGetScannerStatus);
}
void receivedFooResult(String bar){
//...
}
}
public class MyResultReceiver extends ResultReceiver{
private final MyService myService;
public MyResultReceiver(MyService s, Handler handler){
super(handler);
this.myService = myService;
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
switch(resultCode){
case RESULT_CODE_FOO:
myService.receivedFooResult(resultData.getString(FOO_RESULT));
break;
}
}
}
ここで私はpublic staticフィールドを追加できます。しかし、どのようにCREATORを正しく実装するのですか?
public class MyResultReceiver extends ResultReceiver {
public static final Parcelable.Creator<MyResultReceiver> CREATOR
= new Parcelable.Creator<MyResultReceiver>() {
public MyResultReceiver[] newArray(int size) {
return new MyResultReceiver[size];
}
public MyResultReceiver createFromParcel(Parcel in) {
// ???
}
};
あなたがしたい場合:なぜこれが必要なのか?それは何のために使われますか?
なぜですか? 'MyIntentService'は何のために必要ですか? 'MyService'の中の' HandlerThread'で '大仕事 'をしないのはなぜですか? 'ResultReceiver'、' CREATOR'などの必要はありません( 'IntentService'を見てみると、' HandlerThread'だけが表示されます) – pskink
なぜですか?これが最初の方法だったので、私はすべてのものが私がそれらにしたい方法で動作するようにしました。これは、大規模で、テストされ、生産的で、簡単に変更できない作業アプリケーションの既存の設計です。 (上のスニペットはコントロールフローを示すためのものです)。AndroidフレームワークはIntentServiceクラスとResultReceiverを提供します。だから問題は、それらを賢明な方法で使用することです。私はそれを理解していると思っていましたが、上記の新しい要件は適合しませんでした。サービスがIntentServiceに作業をロードし、ResultsReceiverを使用して結果を受け取る場合、設計はどのように意図されていますか? – Paramaeleon
'@SuppressLint(" ParcelCreator ")クラスを試してみてください。MyResultReceiverはResultReceiver {...を拡張しますが、単純に2つのサービスを除いて単純化されたアーキテクチャを検討します。 – pskink