【问题标题】:How would I implement my present threads into an AsyncTask to make the UI respond better?我如何将我当前的线程实现到 AsyncTask 以使 UI 响应更好?
【发布时间】:2014-06-20 12:54:24
【问题描述】:

为了让我的活动发挥作用,我必须从互联网上获取数据。

我实现了线程,但我对 Java 或线程还不是很擅长,所以我有点匆忙通过它只是希望它能工作。它工作得很好,但 UI 有时感觉很慢,因为它需要一段时间才能显示活动。

这是我的代码

一个活动,我们称之为 MainActivity 调用:

JSONObject Data = WebApi.getData(id);

WebApi 类将 url 拼凑在一起:

public static JSONObject getData(String id) {

    String url  = URL;
           url += DATA_URL;     
           url += VALUE_DATA_ID + id;

    return WebInterface.executeWeb(url);               
}

并将其交给 WebInterface,在 WebInterface 中整个事情被执行:

public static String getUrl(final String url) {

    final StringBuilder sb = new StringBuilder();

    Thread thread = new Thread(new Runnable() {
        public void run() 
            {

            try 
            {
                InputStream is = (InputStream) new URL(url).getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                String result, line = reader.readLine();
                result = line;
                while((line=reader.readLine())!=null){
                    result+=line;
                }

                sb.append(result);


            } catch (Exception e)
            {
            // TODO: handle exception
                e.printStackTrace();
            }
        }
      });   

    thread.start();

    try {
        thread.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    String result = sb.toString();
    Log.d(App.TAG, result);

    return result;

}       

public static JSONObject executeWeb(final String url) {

    String result = WebInterface.getUrl(url);

    JSONObject json = null;

    try {
        json = new JSONObject(result.trim());

    } catch (JSONException e) {

        try {
            json = new JSONObject("{}");
        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    return json;                

}

这很好用,但我觉得如果我用 ASyncTask 实现它会更好。我的活动可能会显示一些缓存数据,直到出现“真实”数据。 AsyncTask 可以吗?我需要为此重做很多代码吗?

提前感谢您的帮助!

编辑:

感谢建议 AsyncTaskLoader 的人(我认为有人删除了他的答案) 我是用 AsyncTaskLoader 做的,非常好用,非常简单!

【问题讨论】:

  • 我不知道你为什么认为你需要改变它。如果您要使用AsyncTask 显示一些缓存数据,那么为什么不能没有?
  • @codeMagic 他建议显示缓存数据,然后显示新获取的数据,但他当前的实现不加载缓存数据。我建议检查 Loader 和 LoaderManager 以在后台加载您需要的东西。它为你做 AsyncTask 的事情。
  • 我会自己实现缓存机制。我只是不知道如何执行异步任务

标签: java android multithreading android-asynctask


【解决方案1】:

实际上,由于 thread.join(),您的代码是单线程的。当前线程只是等待新生成的线程完成。您实际上没有从主线程中删除网络,因此 UI “锁定”或感觉很慢。

当你的线程完成时,你可以有一个在主线程上运行的回调,但 AsyncTask 会为你做这件事,并允许你在需要时正确更新进度条。阅读有关如何实现 AsyncTask 的文档。

【讨论】:

  • 我知道这就是为什么我问我如何使用 Asynctask 来做到这一点
【解决方案2】:

svenoaks 是正确的,您使用 thread.join() 正在使您的代码有效地成为单线程。他使用AsyncTask 的解决方案也是正确的。

另一种方法是将Handler 与您已有的线程结合使用。在主线程上创建处理程序,然后在生成的线程obtain() 中创建一条新消息并使用处理程序来处理send 它。然后,您在处理程序(在主线程上执行)中有代码接收消息并更新 UI。

【讨论】:

  • 我知道我已经在我的问题中建议我需要一个 AsyncTask
  • 那么是什么阻止了你?做一些研究,阅读一些教程并开始使用。
【解决方案3】:

如果没有看到您的更多代码,我无法确定您想对数据做什么,但我可以为您提供一个如何使用 AsyncTask 的基本示例。首先,您不需要 getUrl() 中的任何 Thread 内容,所以让我们摆脱它。 getUrl() 应该如下所示:

public static String getUrl(String url) {

    final StringBuilder sb = new StringBuilder();


    try 
    {
        InputStream is = (InputStream) new URL(url).getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String result, line = reader.readLine();
        result = line;
        while((line=reader.readLine())!=null){
            result+=line;
        }

        sb.append(result);


    } catch (Exception e)
    {
    // TODO: handle exception
        e.printStackTrace();
    }


    String result = sb.toString();

    return result;

}

接下来让我们将您对 WebApi.getData 的调用包装在 AsyncTask 中,以便它在后台运行。

        new AsyncTask<Void, Void, JSONObject>(){

        @Override
        protected JSONObject doInBackground(Void... params) {
            JSONObject data = WebApi.getData(id);
            return data;
        }
        @Override
        protected void onPostExecute(JSONObject result){
            //here you can do something with result
        }

    }.execute();

AsynTask 将在后台线程中执行 doInBackground() 中的任何代码,然后将结果返回给 onPostExecute(),后者将在 UI 线程上运行。请注意,在我上面给出的示例中,必须将 id 声明为 final。

如前所述,您可能应该阅读 AsyncTask 上的 documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-11
    • 2021-03-24
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    相关资源
    最近更新 更多