I am working on Android applications for last 2 years and about 80% applications I have developed involve web-services consumption followed by some sort of XML or JSON parsing. Initially, when I had to call a web service, I had to create a separate AsyncTask
class and then parsing was also the part of that AsyncTask class. The HTTP request sending and other stuff was being handled in my ConnectionManager
class. Then I realized there should be some general and single structure which can handle such things like Async
call, HttpGet
and HttpPost
and parsing stuff. So I created this simple structure.
Now my question is, what changes and improvements I can add to make it work better and handle such different use cases?
TaskResult.class
public class TaskResult {
public static int CODE_ERROR = 0;
public static int CODE_SUCCESS = 1;
public int code = CODE_ERROR;
public String message = null;
private Object data = null;
public Object getResultData() {
return data;
}
public void setResultData(Object data) {
this.data = data;
}
}
BaseParser.class
public interface BaseParser {
public TaskResult parse(InputStream in);
}
ConnectionManager.class
public class ConnectionManager {
private ArrayList <NameValuePair> params;
private ArrayList <NameValuePair> headers;
private String url;
public static int GET_REQUEST = 0;
public static int POST_REQUEST = 1;
private int mRequestType = POST_REQUEST;
public ConnectionManager() {
params = new ArrayList<NameValuePair>();
headers = new ArrayList<NameValuePair>();
}
public void addParam(String name, String value) {
params.add(new BasicNameValuePair(name, value));
}
public void addHeader(String name, String value) {
headers.add(new BasicNameValuePair(name, value));
}
public void setRequestType(int type) {
mRequestType = type;
}
public void setUrl(String url) {
this.url = url;
}
public InputStream getHttpInputStream() throws ClientProtocolException, Exception {
if(url == null) {
throw new NullPointerException();
}
System.setProperty("http.keepAlive", "false");
if(mRequestType == POST_REQUEST) {
HttpPost request = new HttpPost(url);
request.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);
for(int i = 0; i < headers.size(); i++) {
StringEntity entity = new StringEntity(headers.get(i).getValue(), "UTF-8");
request.setEntity(entity);
}
if(!params.isEmpty()){
HttpEntity httpEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
request.setEntity(httpEntity);
}
DefaultHttpClient mClient = new DefaultHttpClient();
HttpResponse httpResponse;
httpResponse = mClient.execute(request);
HttpEntity mEntity = httpResponse.getEntity();
if (mEntity != null) {
return mEntity.getContent();
}
}
else if(mRequestType == GET_REQUEST) {
String queryString = "";
for(int i = 0; i < params.size(); i++) {
if(i == 0) {
queryString = queryString + params.get(i).getName( ) + "=" + params.get(i).getValue();
}
else {
queryString = queryString + "&" + params.get(i).getName( ) + "=" + params.get(i).getValue();
}
}
DefaultHttpClient mClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url + queryString);
HttpResponse httpResponse;
httpResponse = mClient.execute(httpGet);
HttpEntity mEntity = httpResponse.getEntity();
if (mEntity != null) {
return mEntity.getContent();
}
}
return null;
}
}
BaseAsyncTask.class
public class BaseAsyncTask extends AsyncTask<Void, Integer, TaskResult>{
ConnectionManager mConnectionManager = null;
OnTaskCompleteListener mListener;
BaseParser mParser;
public BaseAsyncTask.class() {
mConnectionManager = new ConnectionManager();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected TaskResult doInBackground(Void... params) {
String message = "";
try {
InputStream in = mConnectionManager.getTestInputStream();
return mParser.parse(in);
} catch (ClientProtocolException e) {
e.printStackTrace();
message = e.getMessage();
} catch (IOException e) {
e.printStackTrace();
message = e.getMessage();
} catch(Exception e) {
e.printStackTrace();
message = e.getMessage();
}
TaskResult rs = new TaskResult();
rs.message = "Internal error. Please try later." + message;
return rs;
}
@Override
protected void onPostExecute(TaskResult result) {
super.onPostExecute(result);
mListener.onComplete(result);
}
public void setRequestType(int type) {
mConnectionManager.setRequestType(type);
}
public void setUrl(String url) {
mConnectionManager.setUrl(url);
}
public void addParam(String name, String value) {
mConnectionManager.addParam(name, value);
}
public void addHeader(String name, String value) {
mConnectionManager.addHeader(name, value);
}
public void setCallbackListener(OnTaskCompleteListener listener) {
this.mListener = listener;
}
public void setParser(BaseParser parser) {
this.mParser = parser;
}
public interface OnTaskCompleteListener {
public void onComplete(TaskResult rs);
}
}
and this is how I call a web-service:
BaseAsyncTask mAsyncTask = new BaseAsyncTask();
mAsyncTask.setUrl(WEB_URL);
mAsyncTask.addParam("id", "some_id");
mAsyncTask.setRequestType(ConnectionManager.GET_REQUEST);
mAsyncTask.setCallbackListener(callbackListener);
mAsyncTask.setParser(new MyListingParser());
mAsyncTask.execute();
public class MyListingParser implements BaseParser {
@Override
public TaskResult parse(InputStream in) {
TaskResult result = new TaskResult();
// convert inputstream to string and then parse
ArrayList<MyClass> data = parseString(in);
result.setResultData(data);
result.code = TaskResult.CODE_SUCCESS;
return result;
}
}
private OnTaskCompleteListener callbackListener = new OnTaskCompleteListener() {
@Override
public void onComplete(TaskResult rs) {
if(rs.code == TaskResult.CODE_ERROR) {
// handle error
}
else if(rs.code == TaskResult.CODE_SUCCESS) {
// handle success case like getting data from TaskResult and populating some listview or other stuff
}
}
};