1

我正在研究Android應用程序,它需要解析大量的XML和/或JSON。AsncTask減慢主要(UI)線程

每個文件都需要3-4秒才能解析,這是在AsyncTask中完成的。解析的數據然後被插入到我的SQlite數據庫中。

我的問題是,UI在分析過程中變得非常緩慢且無響應。

我已經驗證,使用DDMS,幾乎所有的CPU都花費解析,而這發生在另一個(AsyncTask)線程中。

我主要是測試一個速度慢,但有兩個核心的星系連結。因此我不明白爲什麼我遇到這個UI放緩。我仍然可以感受到我的Nexus 7 2013的速度放慢,但它的問題要少得多

你知道我該如何解決這個問題嗎?當有兩個內核可用時,不應該在AsyncTask上負擔沉重的負擔而不得到滯後用戶界面?

代碼示例

下面的第一塊開始排球和請求號碼的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(); 
} 

當排球已經fetced一個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(); 
     } 
    } 


} 
+0

所有這些沉重的代碼都在doInBackground? – tianwei

+0

是的。如果我打破解析方法,我可以看到代碼目前正在執行一個名爲AsyncTask(不是主線程)的線程。 – Markus

+0

您可以在這裏發佈代碼嗎? –

回答

2

是很常見的Android設備已儲存差I/O性能,如果主線程需要訪問無論出於何種原因,事情可能會變得緩慢。存儲是瓶頸,而不是核心數量。

Use the profiler準確地看到哪些方法很慢。您可能會發現UI卡住從驅動器加載數據。例如,通常在UI線程上加載位圖,並且在正常情況下從不會注意到滯後。在這種情況下,將所有I/O操作移出UI線程,就像您已經擁有背景數據處理器一樣。

+0

我認爲你是對的。可能有一些我沒有想到的I/O。但是,我不知道如何找到它。這是一個DDMS的截圖,而在非常滯後的用戶界面中滾動。 http://imgur.com/SsUHITT – Markus

+0

主[1]線上的任何黑色部分都是「滯後」。該模式意味着異步任務定期調用主線程,然後在將控制權交給控制權之前,主線程會忙一會兒。調用堆棧中的方法名稱提示某種更新ListView的回調。你可能會明確地這樣做,或者它可能是自動數據綁定。試着弄清楚控制是如何傳遞迴主線程的;如果必須的話,過濾調用堆棧分析以僅顯示線程[1]上的函數。 –