android android-service intentservice android-intentservice

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 {