Java – Custom asynchronous HTTP client in Android

Custom asynchronous HTTP client in Android… here is a solution to the problem.

Custom asynchronous HTTP client in Android

I use https://github.com/loopj/android-async-http but I think this can be applied to asynchronous tasks ( native tasks).

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {

@Override
    public void onStart() {
         called before request is started
       Some debugging code here
    }

@Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
         called when response HTTP status is "200 OK"
        here is the interesting part
    }

@Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
         called when response HTTP status is "4XX" (eg. 401, 403, 404)
         Some debugging code here, show retry dialog, feedback etc. 
    }

@Override
    public void onRetry(int retryNo) {
         Some debugging code here-------

}
});

I use it a lot in many separate classes. onStart, onFailure, onRetry are the same everywhere, just copy and paste, only onSuccess is different.

I

want to keep my code as clean as possible and reuse code I’ve already written, so my question is, how do I customize it in a separate “file” and then reuse it. I just need the “OnSuccess” function. Thanks

—————————————-

Solutions for GET and POST (thanks to furkan3ayraktar).

The first file, RequestListener

package com.classicharmony.krakenmessages.utils.AsyncHttp;
import org.apache.http.Header;
public interface RequestListener {
    public void onSuccess(int statusCode, Header[] headers, byte[] response);
}

The second file, RequestHandler

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;

import org.apache.http.Header;
import org.apache.http.entity.StringEntity;

import java.io.UnsupportedEncodingException;

public class RequestHandler {

private static RequestHandler instance;

private AsyncHttpClient client;
    private static final boolean SHOW_DEBUG_ALERT_DIALOG = true;

private RequestHandler() {
        client = new AsyncHttpClient();

}

public static RequestHandler getInstance() {
        if (instance == null) {
            instance = new RequestHandler();
        }
        return instance;
    }

public void make_get_Request(final Context context, final String url, final RequestListener listener) {
        client.get(url, new AsyncHttpResponseHandler() {

@Override
            public void onStart() {
                Log.v("▒▒▒▒▒▒▒ GET ", url);
            }

@Override
            public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                listener.onSuccess(statusCode, headers, response);
            }

@Override
            public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
                Log.e("▒▒▒▒▒▒▒ GET FAILED ", url);
                Log.e("▒▒▒▒▒▒▒ GET FAILED ", e.getLocalizedMessage());

if (DUtils.isDebuggable(context) && SHOW_DEBUG_ALERT_DIALOG) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                    builder.setTitle("▒▒▒▒▒ ERROR ▒▒▒▒▒");
                    String error_msg;
                    if (errorResponse != null) {
                        try {
                            error_msg = String.valueOf(new String(errorResponse, "UTF-8"));
                        } catch (UnsupportedEncodingException e1) {
                            error_msg = e.getLocalizedMessage();
                        }
                    } else {
                        error_msg = e.getLocalizedMessage();
                    }

builder.setMessage(context.getClass().getSimpleName() + " -> " + error_msg)
                            .setCancelable(true)
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    dialog.dismiss();
                                }
                            });
                    AlertDialog alert = builder.create();
                    alert.show();
                }
            }

@Override
            public void onRetry(int retryNo) {
                Log.e("▒▒▒▒▒▒▒ RETRYING ", "....." + String.valueOf(retryNo));

}
        });
    }

public void make_post_Request(final Context context, final StringEntity entity, final String url, final RequestListener listener) {
        client.post(context, url, entity, "application/json", new AsyncHttpResponseHandler() {

@Override
            public void onStart() {
                Log.v("▒▒▒▒▒▒▒ POST ", url);
            }

@Override
            public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                listener.onSuccess(statusCode, headers, response);
            }

@Override
            public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
                Log.e("▒▒▒▒▒▒▒ POST FAILED ", url);
                Log.e("▒▒▒▒▒▒▒ POST FAILED ", context.getClass().getSimpleName() + " -> " + e.getLocalizedMessage());

if (DUtils.isDebuggable(context) && SHOW_DEBUG_ALERT_DIALOG) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                    builder.setTitle("▒▒▒▒▒ ERROR ▒▒▒▒▒");
                    String error_msg;
                    if (errorResponse != null) {
                        try {
                            error_msg = String.valueOf(new String(errorResponse, "UTF-8"));
                        } catch (UnsupportedEncodingException e1) {
                            error_msg = e.getLocalizedMessage();
                        }
                    } else {
                        error_msg = e.getLocalizedMessage();
                    }

builder.setMessage(context.getClass().getSimpleName() + " -> " + error_msg)
                            .setCancelable(true)
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    dialog.dismiss();
                                }
                            });
                    AlertDialog alert = builder.create();
                    alert.show();
                }

}

@Override
            public void onRetry(int retryNo) {
                Log.e("▒▒▒▒▒▒▒ RETRYING ", "....." + String.valueOf(retryNo));
            }
        });
    }

}

The third “utility” for displaying or not displaying dialog boxes.

public static boolean isDebuggable(Context ctx) {
    boolean debuggable = false;
    X500Principal DEBUG_DN = new X500Principal("CN=Android Debug,O=Android,C=US");
    try {
        PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES);
        Signature signatures[] = pinfo.signatures;

CertificateFactory cf = CertificateFactory.getInstance("X.509");

for (int i = 0; i < signatures.length; i++) {
            ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
            X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);
            debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
            if (debuggable)
                break;
        }
    } catch (PackageManager.NameNotFoundException e) {
        debuggable variable will remain false
    } catch (CertificateException e) {
        debuggable variable will remain false
    }
    return debuggable;
}

Example of how to call it for POST:

JSONObject jsonParams = new JSONObject();
        StringEntity entity;

try {
            jsonParams.put("from_user_id", "dan");
            jsonParams.put("to_user_id", "vili");
            jsonParams.put("message", "hello world");
            entity = new StringEntity(jsonParams.toString());
        } catch (JSONException e) {
            e.printStackTrace();
            return;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return;
        }

RequestHandler handler = RequestHandler.getInstance();
        handler.make_post_Request(getActivity(), entity, "http://your_server/api/etc", new RequestListener() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] response) {
                try {
                    String server_response = String.valueOf(new String(response, "UTF-8"));
                    Log.v("Server response",server_response);
                } catch (UnsupportedEncodingException e1) {

}
            }
        });

Solution

You can create your own empty version of AsyncHttpResponseHandler, which does not implement the onSuccess method.

public abstract class OWADVLHttpResponseHandler extends AsyncHttpResponseHandler {

@Override
    public void onStart() {}

@Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {}

@Override
    public void onRetry(int retryNo) {}
}

Your code will look like this:

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new OWADVLHttpResponseHandler() {
     @Override
     public void onSuccess(int statusCode, Header[] headers, byte[] response) {
      ....
    }
});

Obviously, you can fill in some things in the non-overriding methods in the base class.

Related Problems and Solutions