我是Android的新手。自从我开始从事这个项目以来已经过了几周。阅读已经编写的代码我看到很多私有异步任务基本相同(调用API)所以我想知道是否有更好的解决方案,我的想法是创建一个名为ApiCaller的公共异步任务,它将返回一个JSONObject和负责解析JSON的是调用ApiCaller的类:
public class ApiCaller extends AsyncTask<String, String, JSONObject> {
private static final String TAG = "ApiCall";
private final String apiVersion = "v1";
private final String baseURL = "http://my.api.com/";
private String URL = null;
/**
* Generates the URL to call the API.
*
* @param params List with the params to call the API.
*/
public ApiCaller(ArrayList<NameValuePair> params){
String apiURL = this.baseURL + this.apiVersion + "/?";
String paramsList = URLEncodedUtils.format(params, "utf-8");
this.URL = apiURL + paramsList;
}
@Override
protected JSONObject doInBackground(String ... params) {
Log.i(TAG, "API:");
Log.i(TAG, this.URL);
JSONManager jParser = new JSONManager();
JSONObject jsonObject = jParser.getJSONFromUrl(this.URL);
return jsonObject;
}
有没有办法将JSONObject返回到类之外,所以我可以这样做:
JSONObject js = apiCaller.execute();
或者每次我需要调用API时避免创建新的asynctas的任何其他解决方案?使用我目前的代码,我无法得到它,但我不知道缺少什么?也许在onPostExecute中返回它?
答案 0 :(得分:1)
前段时间我曾问过类似的问题
One AsyncTask for multiple Activities
我找到的解决方案在另一个问题中得到了解答:
Common class for AsyncTask in Android?
基本上,您需要的是interface
。
我将解释基础知识,但您应该通过@SirDarius查看原始答案。
您可以创建如下界面:
interface AsyncTaskCompleteListener<T> {
public void onTaskComplete(T result);
}
并在您需要使用AsynTask
的所有类中实现该接口,然后,在您的通用Asynstask
中,您需要回调AsyncTaskCompleteListener
并从{{1}调用它}}
onPostExecute
答案 1 :(得分:1)
因为异步AsyncTask不能调用方法并获取返回值;
你可以在你的内联代码上使用AsyncTask并获得postExecute你的JSON对象:
new AsyncTask<String, String, JSONObject>(){
@Override
protected Void doInBackground(String... params) {
//...
}
@Override
protected void onPostExecute(JSONObject result) {
// ...
}
}.execute(...);
答案 2 :(得分:0)
您应该实现一个将传递给异步任务的侦听器。当asynctask完成时,它将调用监听器的方法:
首先,在新的java文件中创建一个监听器:
public interface onTaskDoneListener{
void onTaskDone(JSONObject result);
}
将其传递给AsyncTask:
private onTaskDoneListner donelistner;
public ApiCaller(ArrayList<NameValuePair> params,onTaskDoneListener donelistener){
String apiURL = this.baseURL + this.apiVersion + "/?";
String paramsList = URLEncodedUtils.format(params, "utf-8");
this.URL = apiURL + paramsList;
this.donelistener = donelistener;
}
然后,在AsyncTask的onPostExecute方法中
this.donelistener.onTaskDone(result)
用法:
new ApiCaller(params,new onTaskDoneListener() {
@Override
public void onTaskDone(JSONObject result) {
//This will be called when the asynctask finishes
//Do something with the result
});
答案 3 :(得分:0)
步骤1:定义界面。
public interface WebServiceListener {
public void onLoginActionComplete (ArrayList<String> arrayList);
}
第2步:在您的活动类中实现WebServiceListener。
public class LoginActivity extends Activity implements WebServiceListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
/* Calling the AsyncTask here,you could call in Login Button Click... */
WebServiceClient httpclient = new WebServiceClient(this);
httpclient.execute(ssoURLStr);
}
@Override
public void onLoginActionComplete (ArrayList<String> arrayList) {
// TODO Auto-generated method stub
/* Read the response */
String Response = arrayList.get(0);
}
}
第3步:你的AsynTask类代码。
public class WebServiceClient extends
AsyncTask<String, Integer, ArrayList<String>> {
WebServiceListener listener = null;
/* Constructor added WebServiceListener here */
public WebServiceClient ( WebServiceListener listener)
{
this.listener = listener;
}
@Override
protected ArrayList<String> doInBackground(String... params) {
// TODO Auto-generated method stub
ArrayList<String> arrayList = null;
" write your http code here and get the response and update the
arrayList <String> here"
return arrayList;
}
@Override
protected void onPostExecute(ArrayList<String> arrayList) {
// Returns the contents of the HTML page
listener.onLoginActionComplete (arrayList);
}
}