带有 REST API 的 AsyncTask
Posted
技术标签:
【中文标题】带有 REST API 的 AsyncTask【英文标题】:AsyncTask with REST API 【发布时间】:2017-10-21 11:11:57 【问题描述】:我有一个使用 REST API 填充列表的 android 应用。
我正在尝试使用 AsyncTask 获取 API,但我无法理解它的工作原理。我在后台创建 API 对象以避免 NetworkOnMainThreadError,但这会导致我的 createItems() 方法在空对象上被调用。
如何在后台创建 API 对象并在 OnCreate 期间仍然可以使用它?谢谢!
这是我的 OnCreate() 方法的一部分:
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
createLists();
populateNameLists();
new GetAPITask().execute();
createItems();
(...)
这是导致错误的方法(createItems()):
public void createItems()
testString = api.testSession();
itemString = api.getItems(...);
(...)
这里是异步任务:
private class GetAPITask extends AsyncTask<String, Integer, String>
protected void onPreExecute()
super.onPreExecute();
protected String doInBackground(String... params)
api = new API(getString(R.string.dev_id), getString(R.string.auth_key));
return "API Created";
protected void onProgressUpdate(Integer... values)
super.onProgressUpdate(values);
protected void onPostExecute(String result)
super.onPostExecute(result);
【问题讨论】:
【参考方案1】:使用 AsyncTask 的目的是在后台获取数据,一旦获得数据,就可以使用它填充视图。仅当数据准备好使用时,您才运行您的方法来填充视图,这应该在 onPostExecute
中处理。你应该这样做:
protected void onPostExecute(String result)
super.onPostExecute(result);
createItems();
【讨论】:
【参考方案2】:您的 ASyncTask 引用了外部类
将签名改为
private static class GetAPITask extends AsyncTask<String, Integer, String>
这将阻止您访问类中的代码和变量。
这是您在 ASyncTask 之外访问 api
的方式 - 导致您的困惑
更多解释在这里:https://***.com/a/10540669/413127
这意味着您无法访问 ASyncTask 之外的 api
变量(这是正确的)。然后,您必须将代码移动到后台线程中,并决定您的 ASyncTask 要返回什么。目前它返回一个String
;
您可以通过回调访问该字符串:
private static class GetAPITask extends AsyncTask<String, Integer, String>
interface Callback
void onComplete(String text);
private final API api;
private final Callback callback;
GetAPITask(API api, Callback callback)
this.api = api;
this.callback = callback;
protected String doInBackground(String... params)
return "API Created";
protected void onPostExecute(String result)
super.onPostExecute(result);
callback.onComplete(result);
然后像这样使用它:
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
//createLists();
//populateNameLists();
API api = new API(getString(R.string.dev_id), getString(R.string.auth_key));
new GetAPITask(api, new GetAPITask.Callback()
@Override
public void onSuccess(String result)
Log.d("TUT", "My asynctask returned: " + result);
).execute();
//createItems();
(...)
如您所见,现在它已被清理干净,您的 ASyncTask 除了在 doInBackground()
方法中返回字符串外什么也没做。您需要将要执行的代码移到此处!
(即将createItems
移动到doInBackground()
内)
类似:
protected String doInBackground(String... params)
String testString = api.testSession();
String itemString = api.getItems(...);
(...)
return testString;
protected void onPostExecute(String result)
super.onPostExecute(result);
callback.onComplete(result);
如果你想从 ASyncTask 返回多个字符串,你必须创建一个数据类并返回它。
【讨论】:
以上是关于带有 REST API 的 AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章