android - AsncTask 减慢主 (UI) 线程速度

标签 android multithreading android-asynctask user-experience

我正在开发一个 Android 应用程序,它需要解析大量的 XML 和/或 JSON。

每个文件需要 3-4 秒来解析,这是在 AsyncTask 中完成的。然后将解析后的数据插入到我的 SQlite 数据库中。

我的问题是在解析过程中 UI 变得非常缓慢且无响应。

我已经使用 DDMS 验证了几乎所有的 CPU 都用于解析,并且这发生在另一个 (AsyncTask) 线程中。

我主要在 Galaxy Nexus 上进行测试,该星系速度较慢,但​​有两个核心。因此,我不明白为什么我会遇到 UI 速度变慢的情况。我仍然能感觉到 Nexus 7 2013 的速度变慢,但这已经不是什么问题了

您知道我该如何解决此问题的原因吗?当有两个可用核心时,是否应该可以在 AsyncTask 上承受重负载而不导致 UI 滞后?

代码示例

下面的第一部分启动 Volley 并请求一些 XML 文件。

public static void start_update(final Context context,
        Subscription subscription) {
    if (updateConnectStatus(context) == NO_CONNECT)
        return;

    mContext = context;

    RequestManager.initIfNeeded(context);
    RequestQueue requestQueue = RequestManager.getRequestQueue();

    Cursor subscriptionCursor = Subscription.allAsCursor(context
            .getContentResolver());

    while (subscriptionCursor.moveToNext()) {

        Subscription sub = Subscription.getByCursor(subscriptionCursor);

        if (subscription == null || sub.equals(subscription)) {

            StringRequest jr = new StringRequest(sub.getUrl(),
                    new MyStringResponseListener(context
                            .getContentResolver(), sub),
                    createGetFailureListener());

            int MY_SOCKET_TIMEOUT_MS = 300000;
            DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(
                    MY_SOCKET_TIMEOUT_MS,
                    DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            jr.setRetryPolicy(retryPolicy);

            // Add the request to Volley
            requestQueue.add(jr);
            processCounts.incrementAndGet();

        }
    }
    requestQueue.start();
}

当 Volley 获取 XML 文件时,将调用以下回调:

static class MyStringResponseListener implements Listener<String> {

    static FeedHandler feedHandler = new FeedHandler();
    Subscription subscription;
    ContentResolver contentResolver;
    final JSONFeedParserWrapper feedParser = null;

    public MyStringResponseListener(ContentResolver contentResolver,
            Subscription subscription) {
        this.subscription = subscription;
        this.contentResolver = contentResolver;
    }

    @Override
    public void onResponse(String response) {


        new ParseFeedTask().execute(response); // Execute the parsing as a AsyncTask
    }

    private class ParseFeedTask extends AsyncTask<String, Void, Void> {
        protected Void doInBackground(String... responses) {

            Subscription sub = null;
            String response = responses[0];
            try {
                sub = feedHandler.parseFeed(contentResolver, subscription,
                        response.replace("", "")); // Remove the Byte Order Mark
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnsupportedFeedtypeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(Long result) {
            decrementProcessCount();
        }
    }


}

最佳答案

Android 设备的存储 I/O 性能较差是很常见的,如果主线程出于某种原因需要访问驱动器,事情可能会变得缓慢。存储是瓶颈,而不是核心数量。

Use the profiler看看到底哪些方法是慢的。您可能会发现 UI 无法从驱动器加载数据。例如,在 UI 线程上加载位图是很常见的,并且在正常情况下永远不会注意到延迟。在这种情况下,请将所有 I/O 操作移出 UI 线程,就像您已经使用后台数据处理器一样。

关于android - AsncTask 减慢主 (UI) 线程速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22373251/

相关文章:

java - Android AsyncTask 错误,试图分配较弱的访问权限。

java - 如何在另一个类中调用 ListView 然后清除它

Android Canvas : Draw only part of precalculated Path

java - 在服务于 Socket 连接的两个线程之间共享公共(public)数据

ios - 如何从线程更新 UI

android - 如何中断AsyncTaskLoader的后台线程?

java - AsyncTask 什么时候在后台运行?

java - 特定用户的所有通知都将从数据库中删除,而实际上只应删除一条通知

android - 尝试发送 Android 图像时应用程序崩溃

multithreading - 是否有最小化线程数的搜索算法?