package com.nominanuda.hyperapi.async;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Pair;
import com.nominanuda.web.http.Http500Exception;
import com.nominanuda.web.http.HttpAppException;
import com.nominanuda.zen.common.Util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by azum on 13/05/17.
*/
public class AsyncTaskInvocationHandler<API, T> implements InvocationHandler {
private static class AsyncCallTask<API, RESULT> extends AsyncTask<Object, Void, Pair<RESULT, Exception>> {
private final API mApi;
private final Method mMethod;
private final Util.Consumer<RESULT> mResultFnc;
private final Util.Consumer<Exception> mErrorFnc;
private AsyncCallTask(API api, Method method, Util.Consumer<RESULT> resultFnc, Util.Consumer<Exception> errorFnc) {
mApi = api;
mMethod = method;
mResultFnc = resultFnc;
mErrorFnc = errorFnc;
}
@Override
protected Pair<RESULT, Exception> doInBackground(Object... args) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
try {
RESULT data = (RESULT) mMethod.invoke(mApi, args);
return new Pair<RESULT, Exception>(data, null);
} catch (InvocationTargetException e) {
e.printStackTrace();
Throwable cause = e.getCause();
return new Pair<RESULT, Exception>(null, (cause != null && cause instanceof HttpAppException)
? (HttpAppException) cause
: new Http500Exception(e)
);
} catch (Exception e) {
e.printStackTrace();
return new Pair<RESULT, Exception>(null, e);
}
}
@Override
protected void onPostExecute(Pair<RESULT, Exception> result) {
if (result.second != null) {
mErrorFnc.accept(result.second);
} else {
mResultFnc.accept(result.first);
}
}
}
private final API mApi;
private final Util.Consumer<T> mResultFnc;
private final Util.Consumer<Exception> mErrorFnc;
AsyncTaskInvocationHandler(API api, Util.Consumer<T> resultFnc, Util.Consumer<Exception> errorFnc) {
mApi = api;
mResultFnc = resultFnc;
mErrorFnc = errorFnc;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
AsyncCallTask task = new AsyncCallTask<API, T>(mApi, method, mResultFnc, mErrorFnc);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
task.execute(args);
} else {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args);
}
return null; // just for signature check
}
}