Currently I am using an asynchronous http library to execute http requests against our server. However this carries the problem where if an http call is in progress during a screen rotation we will have a reference to the old context when the call finishes. I sort of got around this by keeping a static reference to the latest instance captured in onCreate and would call methods with that reference (and null it out in onDestroy). It worked ok but seemed like a hack. I've seen some people recommend the use of fragments to deal with this, like here:
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
which seem like good ideas but I was thinking I could accomplish this by simply having my Activity extend FragmentActivity and use an AsyncTaskLoader subclass which is specifically purposed for what I'm doing.
Here is my Idea: Implement an AsyncTaskLoader with takes an ApiRequest and returns an ApiResponse. However I want to be able to subclass HttpAsyncTask and override a method that parses the response so I can parse the response and turn it into another kind of object which extends ApiResponse. I'm not sure how to specify the type arguments to achieve this though.
Here is my code:
public class HttpAsyncTaskLoader</*not sure what to put here*/> extends AsyncTaskLoader<? not sure ?> {
private ApiClient mClient ;
private ApiRequest mRequest;
private volatile boolean isExecuting = false;
public HttpAsyncTaskLoader(Context context, ApiClient client, ApiRequest request) {
super(context);
mClient = client;
mRequest = request;
}
/**
* Subclasses should override this method to do additional parsing
* @param response
* @return
*/
protected /*subclass of ApiResponse (or ApiResponse itself)*/ onResponse(ApiResponse response)
{
//base implementation just returns the value, subclasses would
//do additional processing and turn it into some base class of ApiResponse
return response;
}
@Override
public /** not sure ***/ loadInBackground() {
HttpResponse response = null;
ResponseError error = null;
JSONObject responseJson = null;
ApiResponse apiResponse = null;
try {
isExecuting = true;
//synchronous call
response = mClient.execute(mRequest);
isExecuting = false;
responseJson = new JSONObject(EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
error = new ResponseError(e);
} catch (URISyntaxException e) {
error = new ResponseError(e);
} catch (JSONException e) {
error = new ResponseError(e);
} finally {
mClient.getConnectionManager().closeExpiredConnections();
isExecuting = false;
apiResponse = new ApiResponse(getContext().getResources(), response, responseJson, error);
}
return onResponse(apiResponse);
}
@Override
public void onCanceled(ApiResponse response) {
if (isExecuting) {
mClient.getConnectionManager().shutdown();
}
}
}
Anyone have an idea how I can accomplish this? I'm not sure how to specify the type parameters? I want this class to be usable as-is hopefully and also to be able to subclass it. The point is that I don't want to re-implement the functionality in the loadInBackground method above. I'm sure I could just use ApiResponse as my generic parameter and then cast the ApiResponse objects returned in onLoadFinished to the specific base class that I'm expecting but I'd rather do this in a more type-safe manner. Also I'm open to ideas that accomplish essentially the same thing but in another way.