带有 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的主要内容,如果未能解决你的问题,请参考以下文章

带有 REST API 的 CQRS

javascript 带有REST API调用的Html表

带有 eppn 的 REST-API users.list

带有付款的 PayPal REST API 交叉参考交易

带有图像处理的 REST API?

带有 jwt 身份验证的 django rest api 要求 csrf 令牌