3
\$\begingroup\$

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
 }
 }
 };
rolfl
98.1k17 gold badges219 silver badges419 bronze badges
asked Feb 10, 2014 at 12:41
\$\endgroup\$

4 Answers 4

3
\$\begingroup\$

Your idea seems quite feasible, I just had a brief look through and these would be my suggestions:

  1. TaskResult class

    • "code" and "message" members should probably be encapsulated via getter/setter with proper namings.
  2. ConnectionManager class

    • Depending on your scenario maybe you should consider calling "shutdown" on your mClient member.
    • When creating your queryString you should use String.format() instead of manually concatenating strings.
    • The getHttpInputStream() method could suffer a bit of refactoring, you have common code and behaviour in both if/else branches.

Other then that, imo the code looks okey.

answered Feb 25, 2014 at 10:57
\$\endgroup\$
1
  • \$\begingroup\$ Yeah, your points are very noteworthy and I will add them to my original code. \$\endgroup\$ Commented Feb 26, 2014 at 11:22
3
\$\begingroup\$

I use volley library to do these work. Volley is a library developed by Google, it is tried and tested. It has other features network response caching, network image caching, request cancelation etc..

answered Apr 9, 2014 at 5:54
\$\endgroup\$
1
\$\begingroup\$

It's simple and elegant and useful for many cases but I'd do something else

  1. I would enhance HttpRequest with Multipart (I know, it's not what you wanted but it's very useful for Http Connections, if you want to upload/download something,Multipart is a MUST)
  2. I would enhance HttpResponse instead TaskResult and there, I would also use Multipart
200_success
146k22 gold badges190 silver badges479 bronze badges
answered Sep 25, 2014 at 17:21
\$\endgroup\$
0
1
\$\begingroup\$

Just one thing I'd like to mention here.

  1. In your AsyncTask you are not doing anything in onPreExecute() so I would remove it.
answered Sep 25, 2014 at 20:35
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.