Starting an activity with result the clean way
[IMPORTANT NOTICE] THIS SOLUTION DOES NOT WORK. It was a good idea but in fact it wasn't : the base activity A keep a track of all handlers, so when you start an activity B, and because of memory pressure A is killed, then when B finishWithResult, A is recreated, so it does not have any handlers, and nothing will get called. Please do NOT use this solution.
I didn't like the way Android handles the startActivityForResult and the onActivityResult. It felt wrong to me, so I created a little base class allowing a cleaner way (to my point of view) of doing this.
In other words :
This sucks :
private void onButtonClicked(){
Intent intent = new intent(this, Activity.class);
startActivityForResult(intent, MY_REQUEST_CODE); //we have to keep the request code, who cares ?
}
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case MY_REQUEST_CODE: //when did we asked for this ?
if(resultCode == Activity.RESULT_OK){
// use data
}
}
}
This is what we want :
private void onButtonClicked(){
Intent intent = new intent(this, Activity.class);
startActivityForResult(intent, Activity.RESULT_OK, new SuccessResultHandler() {
@Override
public void onResult(Intent data) {
//here you have your results data. The resultCode has already been checked against Activity.RESULT_OK
}
});
}
To have this feature, just create a base class for all your activities or fragment containing the following :
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by philippeauriach on 18/10/2016.
*/
public class BaseActivity extends AppCompatActivity {
private Map<Integer, HandlerHolder> resultHandlers = new HashMap<>();
private AtomicInteger counter = new AtomicInteger(Integer.MIN_VALUE);
private int getNewRequestCode() {
return new AtomicInteger().incrementAndGet();
}
protected void startActivityForResult(Intent intent, int successResultCode, SuccessResultHandler handler) {
int requestCode = getNewRequestCode();
resultHandlers.put(requestCode, new HandlerHolder(successResultCode, handler));
startActivityForResult(intent, requestCode);
}
protected void startActivityForResult(Intent intent, ResultHandler handler) {
int requestCode = getNewRequestCode();
resultHandlers.put(requestCode, new HandlerHolder(handler));
startActivityForResult(intent, requestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
HandlerHolder handler = resultHandlers.get(requestCode);
if (handler != null) {
if (handler.successHandler != null) {
if (resultCode == handler.successResultCode) {
handler.successHandler.onResult(data);
}
return;
}
if (handler.resultHandler != null) {
handler.resultHandler.onResult(resultCode, data);
return;
}
}
}
public interface SuccessResultHandler {
void onResult(Intent data);
}
public interface ResultHandler {
void onResult(int resultCode, Intent data);
}
protected class HandlerHolder {
private Integer successResultCode;
private SuccessResultHandler successHandler;
private ResultHandler resultHandler;
public HandlerHolder(Integer successResultCode, SuccessResultHandler successHandler) {
this.successResultCode = successResultCode;
this.successHandler = successHandler;
}
public HandlerHolder(ResultHandler resultHandler) {
this.resultHandler = resultHandler;
}
}
}
Written by Philippe Auriach
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Android
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#