1

상당한 양의 XML 및/또는 JSON을 구문 분석해야하는 Android 앱에서 작업하고 있습니다.AsncTask 메인 (UI) 스레드가 느려집니다

모든 파일을 구문 분석하는 데 3-4 초가 걸리고이 작업은 AsyncTask에서 수행됩니다. 파싱 ​​된 데이터는 내 SQlite 데이터베이스에 삽입됩니다.

내 문제는 UI가 구문 분석하는 동안 매우 느리고 응답이 없습니다.

DDMS를 사용하여 거의 모든 CPU가 구문 분석에 소비하고 이것이 (AsyncTask) 다른 스레드에서 발생한다는 것을 확인했습니다.

저는 주로 느리지 만 두 개의 코어가있는 은하계 연결을 테스트하고 있습니다. 따라서 나는 왜이 UI가 느려지는지 이해하지 못합니다. 그래도 Nexus 7 2013의 속도 저하는 느낄 수 있지만 문제는별로 없습니다.

이 문제의 원인을 찾기 위해 진행할 수있는 방법이 있습니까? 두 개의 코어를 사용할 수있을 때 느린 UI를 얻지 않고도 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(); 
} 

발리는 XML은 다음 콜백이 호출 파일 fetced 때 :

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

메인 스레드가 액세스해야하는 경우 안드로이드 기기가 좋지 스토리지 I/O 성능을 가지고하는 것이 일반적이다 어떤 이유로 든 드라이브가 느려질 수 있습니다. 스토리지는 병목 현상이 아니라 코어 수입니다.

Use the profiler 정확히 어떤 방법이 느린지 확인하십시오. UI가 드라이브에서 데이터를로드하지 못하는 경우가 있습니다. 예를 들어 UI 스레드에 비트 맵을로드하고 일반 조건에서 지연을 알리는 것은 일반적입니다. 이러한 상황에서 배경 데이터 프로세서를 이미 가지고있는 것처럼 UI 스레드에서 모든 I/O 작업을 이동하십시오.

+0

나는 당신이 옳다고 생각한다. 아마도 내가 생각하지 못한 I/O가있을 것입니다. 그러나, 나는 그것을 찾는 방법을 모른다. 다음은 (매우) 느린 UI에서 스크롤하는 동안 DDMS의 스크린 샷입니다. http://imgur.com/SsUHITT – Markus

+0

메인 [1] 스레드의 어두운 부분은 "지연"입니다. 이 패턴은 비동기 작업이 주기적으로 주 스레드를 호출하고 있음을 의미합니다. 주 스레드는 다시 제어를 전달하기 전에 잠시 사용 중입니다. 호출 스택의 메서드 이름은 ListView를 업데이트하는 콜백을 제안합니다. 이 작업을 명시 적으로 수행하거나 자동 데이터 바인딩 일 수 있습니다. 컨트롤이 메인 스레드로 다시 전달되는 방식을 시도해보십시오. 필요한 경우 스레드 [1]의 함수 만 표시하도록 호출 스택 분석을 필터링하십시오. –

관련 문제