Custom Async Http Client in Android
I am using https://github.com/loopj/android-async-http but I think this can be applied to Async task (native)
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 different classes. OnStart, onFailure and onRetry are the same all over the world, just copy-paste, only onSuccess is different.
I want my code to be as clean as possible and reuse what I already wrote, so my question is how to make this custom in a separate "file" and just reuse it. I need the "OnSuccess" function. Thanks you
---------------------------------------
SOLUTION for GET and POST (thanks to furkan3ayraktar)
1st RequestListener file
package com.classicharmony.krakenmessages.utils.AsyncHttp;
import org.apache.http.Header;
public interface RequestListener {
public void onSuccess(int statusCode, Header[] headers, byte[] response);
}
Second RequestHandler file
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" is to display the dialog or not.
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;
}
An 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) {
}
}
});
source to share
Create a generic request handler and listener. You can also create different request methods like makeRequest for each request you want, and create different listeners. Here is a simple template that I mainly use,
public class RequestHandler{
private static RequestHandler instance;
private AsyncHttpClient client;
private RequestHandler(){
client = new AsyncHttpClient();
}
public static RequestHandler getInstance(){
if(instance == null){
instance = new RequestHandler();
}
return instance;
}
// You can add more parameters if you need here.
public void makeRequest(String url, RequestListener listener){
client.get(url, 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) {
listener.onSuccess(statusCode, headers, response);
}
@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-------
}
});
}
}
public interface RequestListener{
public void onSuccess(int statusCode, Header[] headers, byte[] response);
}
Then use as low as possible anywhere.
RequestHandler handler = RequestHandler.getInstance();
handler.makeRequest("http://www.google.com", new RequestListener(){
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// do whatever you want here.
}
});
source to share
You can create your own empty version AsyncHttpResponseHandler
that doesn't implement the method onSuccess
.
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) {}
}
Then 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 content in non-overridden methods in the base class.
source to share
First, you create an abstract base class that implements the normal behavior. Something like that:
public abstract class AsyncHttpResponesHandlerBase implements AsyncHttpResponseHandler {
@Override
public void onStart() {
// called before request is started
// Some debugging code here
}
@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-------
}
}
Then for each url that you inherited from the base class and implement a method onSuccess()
to handle the response.
public class GoogleGetHandler extends AsyncHttpResponesHandlerBase {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
// do the Google specific handling
}
}
And you make an HTTP request like this:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new GoogleGetHandler());
So if you want to make calls to more URLs, just keep creating new subclasses based on the base class to inherit the general error handling.
source to share
*********************************************
Calling Api USing Retrofit
*********************************************
**Dependancies** :-
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.google.code.gson:gson:2.2.4'
enter code here
**Model**
use the Pozo class
**Api Call**
-> getLogin() // use the method
//API call for Login
private void getLogin()
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams requestParams = new RequestParams();
requestParams.put("email_id", edit_email.getText().toString());
requestParams.put("password", edit_password.getText().toString());
Log.e("", "LOGIN URL==>" + Urls.LOGIN + requestParams);
Log.d("device_token", "Device_ Token" + FirebaseInstanceId.getInstance().getToken());
client.post(Urls.LOGIN, requestParams, new JsonHttpResponseHandler() {
@Override
public void onStart() {
super.onStart();
ShowProgress();
}
@Override
public void onFinish() {
super.onFinish();
Hideprogress();
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
Log.e("", "Login RESPONSE-" + response);
Login login = new Gson().fromJson(String.valueOf(response), Login.class);
edit_email.setText("");
edit_password.setText("");
if (login.getStatus().equals("true")) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("User Login Successfully!"),
MDToast.LENGTH_SHORT, MDToast.TYPE_SUCCESS);
mdToast.show();
Utils.WriteSharePrefrence(SignInActivity.this, Util_Main.Constant.EMAIL, login.getData().getEmailId());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERID, login.getData().getId());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERNAME, login.getData().getFirstName());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.PROFILE, login.getData().getProfileImage());
hideKeyboard(SignInActivity.this);
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("Login Denied"),
MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
mdToast.show();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
super.onFailure(statusCode, headers, responseString, throwable);
Log.e("", throwable.getMessage());
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, "Something went wrong",
MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
mdToast.show();
}
});
}
implements LocationListener {
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private String vendorId, vendorName, vendorPhone, vendorImg, vendorDistance, vendorStar, vendorRate, vendorAddress, vendorSummary, vendorOtherService;
LocationManager locationManager;
private FusedLocationProviderClient mFusedLocationProviderClient;
private boolean mLocationPermissionGranted;
private Location mLastKnownLocation;
init()
{
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
}
@Click
public void lnrCurrentLocation() {
getLocationPermission();
getDeviceLocation();
}
private void getDeviceLocation() {
try {
if (mLocationPermissionGranted)
{
final Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
MarkerOptions markerOptions = new MarkerOptions();
if (task.isSuccessful()) {
mLastKnownLocation = task.getResult();
if(mLastKnownLocation!=null)
{
Double lat = mLastKnownLocation.getLatitude();
Double lng = mLastKnownLocation.getLongitude();
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(AddAddressActivity.this, Locale.getDefault());
try {
Log.e("latitude", "inside latitude--" + lat);
addresses = geocoder.getFromLocation(lat, lng, 1);
if (addresses != null && addresses.size() > 0) {
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
edtAddress.setText(address );
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (lat != null && lng != null) {
fastSave.saveString(Constant.CURR_LAT, String.valueOf(mLastKnownLocation.getLatitude()));
fastSave.saveString(Constant.CURR_LON, String.valueOf(mLastKnownLocation.getLongitude()));
} else {
getDeviceLocation();
}
}
}
}
});
}
else {
Log.d("@permision","======== Permision not found =========");
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
private void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
}
void getLocation() {
try {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this);
}
catch(SecurityException e) {
e.printStackTrace();
}
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
"GOOGLE MAP IN ANDROID"
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.android.gms:play-services-maps:11.8.0'
implementation 'com.github.pedroSG94:AutoPermissions:1.0.3'
<meta-data
android:name="@string/permissions_loader_meta_key"
android:value="android.permission.WRITE_EXTERNAL_STORAGE, android.permission.CAMERA,android.permission.ACCESS_FINE_LOCATION,android.permission.ACCESS_COARSE_LOCATION" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
implements OnMapReadyCallback, AutoPermissionsListener {
private GoogleMap mMap;
AutoPermissions.Companion.loadActivityPermissions(DashboardActivity.this, 1);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
AutoPermissions.Companion.parsePermissions(DashboardActivity.this, requestCode, permissions, this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(0.0, 0.0);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in India"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
@Override
public void onDenied(int i, String[] strings) {
}
@Override
public void onGranted(int i, String[] strings) {
}
source to share
import com.google.gson.Gson;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashSet;
import cz.msebera.android.httpclient.Header;
source to share