Reputation: 2724
I have a external library to use which communicates with a server via the internet. Everytime I need to get some info from the internet, android forces me to use an asynctask. So far no problem. However, I'm getting more and more tasks to retrieve (in different ways) data from the internet and I'm not liking the increase of different classes for each single call. So long story short: I have different internet-calls, and instead of creating an asynctask-class for each call, I would prefere one single class to manage all different calls. Is that somehow possible? And more importantly, what is the proper way to do so?
Upvotes: 4
Views: 122
Reputation: 766
Yes it is possible but you need to create some generic AsyncTask that takes API(url to call) and handler when result is received.
Async class:
public class AsyncTaskThread extends AsyncTask<Object, Object, Object> {
//instance variables
Handler myHandler;
public AsyncTaskThread(String uriString, Handler myHandler) {
//set these arguments to respective instance variables
this.myHandler=myHandler;
}
protected Object doInBackground(Object... obj){
//business logic
}
//----implement other methods of Async as per your requirement
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
Message message = new Message();
message.obj = result;
myHandler.sendMessage(message);
}
}
Pass handler for thread:
You need to pass handler to above Async task in argument.
new AsyncTaskThread(uri,new MyHandler())
import android.os.Handler;
private class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
Model response = (Model) msg.obj;
}
}
when result received call sendMessage() method on passed handler from your async task.
My suggestion:
If you are using okhttp client library for API calls, please see https://github.com/square/okhttp/wiki/Recipes
Upvotes: 1
Reputation: 3007
I was also facing similer problem like you have.But i solved this problem by Reflection Technique. I have made a method to prevent increasing of different classes to call single hit. I have made single asynctask class and passed functionName and context of the activity and returned response by onPostExecute.
Here is sample -
AsyncTaskConnection.java
public class AsyncTaskConnection extends AsyncTask<String, String, Object>{
JSONObject mainObject;
Context mContext;
String returnFunctionName;
public AsyncTaskConnection (Context context){
mContext = context;
}
protected void onPreExecute() {
// preExecute
}
@Override
protected Object doInBackground(String... arguments) {
String apiFunctionName = arguments[0]; // get api FunctionName
String jsonString = arguments[1]; // get data
returnFunctionName = apiFunctionName+"Response"; // return function name
// some connection code...
//then call...
try {
ht.call(NAMESPACE, requestEnvelop);
} catch (IOException ex) {
Log.d(mContext.getClass().getName(), "Io exception bufferedIOStream closed" + ex);
ex.printStackTrace();
}
return mainObject.toString();
} catch (Exception e) {
Log.d("Exception", e.toString());
return "no";
}
}
// main thing is there, i have use the reflaction here....
@Override
protected void onPostExecute(Object backresult) {
Method m;
try {
m = mContext.getClass().getDeclaredMethod(returnFunctionName, String.class);
m.invoke(mContext, (String) backresult);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
in caller class
//call this class where you want and get dynamic response
new AsyncTaskConnection(this).execute("getHomepage",jo.toString());
// and make response fuction
protected void getHomepageResponse(String backresult) {
try {
// this is your response
mainObject = new JSONObject(backresult);
} catch (JSONException e) {
e.printStackTrace();
}
}
And there can be many ways to get result that you want.
Upvotes: 2