El servicio de Android amplía ResultReceiver para IntentService, ¿cómo implementar CREATOR?
android-service android-intentservice (1)
Mi aplicación se basa en un Service
que se mantiene sincronizado con el hardware externo en segundo plano. Debido a que el servicio opera en el subproceso principal , realiza un trabajo pesado de forma asincrónica utilizando un IntentService. Aquí hay un ejemplo minimalizado del código para explicar el flujo de control:
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;
}
}
Ahora, después de medio año y algunas actualizaciones, Android Studio se queja de que MyResultReceiver
implementa Parcelable pero no proporciona un campo CREADOR . Problema uno, MyResultReceiver es una clase interna, así que tengo que ponerlo en una clase propia. No puedo hacerlo static
porque debe contener una referencia a MyService. Eso sigue siendo bastante fácil:
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;
}
}
}
Ahora puedo agregar un campo estático público. ¿ Pero cómo implementar CREADOR correctamente?
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) {
// ???
}
};
Si quieres: ¿Por qué es necesario? ¿Para qué será utilizado?
Su arquitectura actual es demasiado compleja. Puede hacerlo fácilmente en un Service
pero depende de usted, cuando se trata de su problema: no necesita crear ningún CREATOR
ya que lo que recibió es una advertencia de pelusa, solo agregue Suprimir la anotación de esta manera:
@SuppressLint("ParcelCreator")
public class MyResultReceiver extends ResultReceiver {