My app relies on a Service
which stays in sync with external hardware in the background. Because the service operates on the main Thread, it does any heavy work asynchronously using an IntentService. Here is a minimalized example of the code to explain the control flow:
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;
}
}
Now, after half a year and some updates, Android Studio complains that MyResultReceiver
implements Parcelable but does not provide a CREATOR field. Problem one, MyResultReceiver is an inner class, so I have to put it into an own class. I cannot make it static
because it must hold a reference to MyService. That is still quite easy:
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;
}
}
}
Now I can add a public static field. But how to implement CREATOR correctly?
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) {
// ???
}
};
If you want to: Why is this necessary? What will it be used for?
Consider using WorkManager or JobIntentService , which uses jobs instead of services when running on Android 8.0 or higher. IntentService is an extension of the Service component class that handles asynchronous requests (expressed as Intent s) on demand. Clients send requests through Context.
If the task doesn't require any and also not a very long task you can use service. If the Background task is to be performed for a long time we can use the intent service. Service will always run on the main thread.
Multiple requests to start the service result in multiple corresponding calls to the service's onStartCommand(). However, only one request to stop the service (with stopSelf() or stopService()) is required to stop it.
your current architecture is too complex imho: you could easily do that in one Service
but it is up to you, when it comes to your problem: you don't need to create any CREATOR
as what you got is a lint warning, just add SuppressLint annotation like this:
@SuppressLint("ParcelCreator")
public class MyResultReceiver extends ResultReceiver {
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With