【问题标题】:AsyncTask operation with return type具有返回类型的 AsyncTask 操作
【发布时间】:2015-09-19 18:00:46
【问题描述】:

我是 android 开发的新手,作为我学习的一部分,我正在制作一个多语言新闻阅读器应用程序,该应用程序从 google 新闻获取 rss 提要并进行解析。

为此,我使用选项卡式视图来显示多种语言,用户可以滑动浏览不同的语言。应用程序包含印地语、马拉雅拉姆语、英语和泰米尔语选项卡,都列出了特定的新闻项目。

每个语言视图页面都是单独的片段。并且应用程序中总共有四个片段,主要活动包含所有这些。

对于所有这些片段,我有一个 AsyncTask 扩展类,它从服务器加载和解析新闻。并在其 doInBackground 方法上返回一个数组列表,但问题是当我从一个选项卡滑动到另一个选项卡时,它非常有效慢。我正在粘贴我的代码。我认为我的 AsyncTask 用法不正确,因为我在 onPreExecute 方法中显示了一个进度条,但它也没有正确显示。

请任何人查看我的代码并帮助我更正

EnglishNewsFragment.java

    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
ArrayList<HashMap<String, String>> newsWrapper;
            context = getActivity();
            View rootView = inflater.inflate(R.layout.english_news_fragment, container, false);
            NewsLoader newsLoader = new NewsLoader(context, language);
            newsLoader.execute();
            try {

                newsWrapper = newsLoader.get();

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                showNews(newsWrapper);
            }
            return rootView;
        }

新闻加载器

public class NewsLoader extends AsyncTask{

    public NewsLoader(Context context, String language) {

            this.context = context;
            this.language = language;

        }

        @Override
        protected void onPreExecute() {

            startDialogue();
            initAll(language);
        }


        @Override
        protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
                       getNews();
                news = processXML();

            } catch (Exception e) {
                e.printStackTrace();
            }
            return news;
        }


        @Override
        protected void onPostExecute(ArrayList<HashMap<String, String>> aVoid) {
            super.onPostExecute(aVoid);
            stopDialogue();
        }
}

更新

AsyncTask.get() 会阻塞 UI。所以我必须实现一个回调接口,有人可以帮我做吗?我从here读了一点,但是它的调用将如何以及如何将结果传递给 MainActivity ?

截图

【问题讨论】:

  • 顺便说一句:调用super.onPostExecute()super.onPreExecute() 是没用的,因为在超类中没有默认实现
  • 为什么不使用 onProgressUpdate 来更新进度条?
  • bcs我不更新进度,只显示一个spinner,就够了
  • 你能在片段中发布 showNews() 并在 AsyncTask 方法中发布 initAll()
  • 这是一个非常好的 AsyncTask 用法示例 - vogella.com/tutorials/AndroidBackgroundProcessing/…

标签: java android android-fragments android-asynctask


【解决方案1】:

我已经知道答案了。

我已经做了一个回调接口,用于将结果传递给Fragment

public interface CallBackReciever {

    public void recieveData(ArrayList<HashMap<String,String>> result);

}

并用片段实现了这个接口。

然后将此接口的上下文传递给AsyncTask。并在其 onPostExecute() 方法中调用 recieveData() 方法

片段

@Override
    public void recieveData(ArrayList<HashMap<String, String>> result) {
        newsWrapper = result;
        showNewsOnUI();
    }

异步任务

public class NewsLoader extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>{

public NewsLoader(CallBackReciever callBackReciever) {
        this.callBackReciever = callBackReciever;
    }
 @Override
    protected void onPreExecute() {
        startDialogue();

    }
    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
        initAll(language);
        result = processNews()
        return result;
}
    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        stopDialogue();
        callBackReciever.recieveData(result);
    }
}

【讨论】:

  • 有趣的答案!由于最终结果是文本的 ArrayList,您可以使用非 UI 线程,如 Thread 和 Handler 吗?我在 NewsLoader 中没有看到太多的 UI 处理。你当然知道得更好。恭喜!
  • @TheOriginalAndroid 在我的 doInBackground() 方法中有一个名为 processNews() 的方法,它从 Internet 获取新闻并返回解析的 xml。使 AsyncTask 成为强制性的。
  • 即使有那个工作,它也不涉及 UI。那么也许您可以将 Thread 类与 Runnable 一起使用?
【解决方案2】:

UI 中的减速或瓶颈可能来自onPreExecute() 或onPostExecute()。添加Log.d() 之类的代码并打印时间差以查看导致瓶颈的代码。例如,代码initAll(language) 可能会移动到doInBackground() 的非UI 线程。也许这种方法很慢。基本上使用onPreExecuteonPostExecute,无论需要做什么都要快。

我认为您无需致电super.onPreExecute()super.onPostExecute(aVoid)。谷歌的样本没有这样做或建议@AsyncTask。也许这也会导致瓶颈。

希望对您有所帮助...

【讨论】:

    【解决方案3】:

    Asynctask.get() 方法会阻止 UI,直到 doInBackground() 完成。您可以改用 onPostExecute() 在 UI 上返回结果。

    【讨论】:

    • 你能用例子或任何链接解释一下吗?
    • 对不起,我没有具体的链接,但网上有一些关于android后台处理的教程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 2013-06-12
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    相关资源
    最近更新 更多