Problem
I’m working on an Android app, and at one point I need to retrieve a request code in a callback method and perform some database operations depending on the request code. It started out ok when there were just 2 request codes, but then I had a need to add two more, and I can’t really find a good way to avoid a messy looking method.
This is the method right now
@Override
public void onActivityResult(final int requestCode, int resultCode, Intent data) {
final Context applicationContext = getContext();
DevLog.v(TAG, "onActivityResult() requestCode="+requestCode+" resultCode="+resultCode+" data="+data);
if( (requestCode == ACTIVITY_REQUEST_ADD_SENDER ||
requestCode == ACTIVITY_REQUEST_EDIT_SENDER ||
requestCode == ACTIVITY_REQUEST_ADD_SOS_RECEIVER ||
requestCode == ACTIVITY_REQUEST_EDIT_SOS_RECEIVER)
&& resultCode == RESULT_OK
&& data != null
&& applicationContext != null ){
final String number = getNumberFromContactResultIntent(data);
if (number != null) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
switch (requestCode) {
case ACTIVITY_REQUEST_ADD_SENDER:
AppDatabase.db(applicationContext).getSenderDao().insert(new Sender(number));
break;
case ACTIVITY_REQUEST_EDIT_SENDER:
if (mEditSender != null) {
mEditSender.number = number;
AppDatabase.db(applicationContext).getSenderDao().update(mEditSender);
}
break;
case ACTIVITY_REQUEST_ADD_SOS_RECEIVER:
AppDatabase.db(applicationContext).getSosReceiverDao().insert(new SosReceiver(number));
break;
case ACTIVITY_REQUEST_EDIT_SOS_RECEIVER:
if (mEditSosReceiver != null ) {
mEditSosReceiver.number = number;
AppDatabase.db(applicationContext).getSosReceiverDao().update( mEditSosReceiver );
}
break;
}
}
});
}
}
else
super.onActivityResult(requestCode, resultCode, data);
}
What bugs me the most is the repeated check of the requestCode
parameter. First I need to check if it’s any of four values (the if
), and then I have to perform different operations depending on exactly which of those four values it is (the switch
).
If I remove the if( (requestCode ...
part and move the switch
statement out from the AsyncTask
, I would still need to perform the other checks (resultCode == RESULT_OK && data != null ...
etc), AND I would have to create one AsyncTask
in each case
, so I’d basically end up with even more redundant code than there already is.
I would also need to move the
getNumberFromContactResultIntent(data)
call, since it only makes sense for these four request codes and shouldn’t be called on any other request codes.
I considered putting the four request codes into an array (they are static final int
) and call it something like REQUEST_CODE_GROUP_ADD_OR_EDIT
and perform
Arrays.binarySearch(REQUEST_CODE_GROUP_ADD_OR_EDIT, requestCode)
on it, which would at least reduce the if
statement slightly. But it seems a bit silly to turn four simple and efficient ==
checks into a much more complex operation. It’s highly unlikely I’ll need to add more similar request codes in the future, and if I do it will most certainly only be a limited number of them (2-4).
Is there a neat way to simplify something like this, where one needs to combine first checking for any of a limited set of values, perform some operations that is common to all of them, and then perform some operations that are specific for each value?
Solution
You could define an abstract class that holds a request code and a command.
Then for each code, create a concrete subclass that hold that code and command associated with that code. Then you pass an instance of that concrete subclass, do your null checks, and call the command.