Мое приложение полагается на Service
, который находится в синхронизации с внешним оборудованием в фоновом режиме. Поскольку сервис работает на главной линии , он выполняет любую тяжелую работу асинхронно с использованием IntentService. Вот minimalized пример кода для объяснения потока управления:Служба Android расширяет ResultReceiver для IntentService, как реализовать 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 Studio жалуется, что MyResultReceiver
реализует Parcelable, но не обеспечивает поле CREATOR. Проблема одна, MyResultReceiver - это внутренний класс, поэтому я должен поместить его в собственный класс. Я не могу сделать это static
, потому что он должен содержать ссылку на MyService. Это все еще довольно просто:
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;
}
}
}
Теперь я могу добавить публичное статическое поле. Но как правильно использовать 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»? почему бы не сделать «тяжелую работу» в «HandlerThread» внутри 'MyService'? нет необходимости в 'ResultReceiver',' CREATOR' и т. д. (если вы посмотрите на «IntentService», вы увидите, что в нем нет ничего, кроме 'HandlerThread') – pskink
Почему? Поскольку это был первый способ, я получил все, чтобы работать так, как я хочу. Это существующий дизайн рабочего приложения, который является большим, проверенным и производительным, и его нельзя легко изменить. (Выше фрагмента показывается только поток управления.) Ракурс Android обеспечивает класс IntentService и ResultReceiver. Поэтому вопрос заключается в том, как использовать их разумным образом. Я думал, что понял это, см. Выше, но новое требование не подходит. Итак, как дизайн предназначен, если служба хочет загрузить работу в IntentService и получать результаты, хотя они имеют результат? – Paramaeleon
try '@SuppressLint (« ParcelCreator ») класс MyResultReceiver расширяет ResultReceiver {...', но серьезно рассматривает упрощенную архитектуру (без двух сервисов) – pskink