2011-02-24 3 views
0

나는 chatty net enabled 응용 프로그램을 작성하고 있으며 향상된 사용자 환경을 위해 모든 종류의 동시성 구조를 사용하고 있습니다. 네트워크에서 들어오는 정보에는 텍스트 항목과 이미지 URL이 들어 있습니다. 현재 이미지를 가져 오기 위해 새 스레드를 생성하지 않고 블로킹 방식으로 이미지를 가져옵니다. 이 작업은 정상적으로 수행되지만 이미지를 가져 오기 위해 다른 스레드를 생성하여 작업을 훨씬 더 멋지게 만들 수 있음을 깨달았습니다. 이 작업을 처리하기 위해 2 개의 작업자 스레드가있는 스레드 풀에 정착했지만 이제는 응용 프로그램이 중단되는 중 간헐적 인 문제가 발생합니다. 그것은 무작위로 발생하는 것으로 보이며 정확하게 무엇이 잘못 될지 알지 못합니다. 따라서 현재 내가하는 일은 다음과 같습니다.android random crashing concurrency issues

  1. 사용자 탭 검색과 새로운 AsyncTask가 필요한 정보를 가져 오기 위해 생성됩니다.

  2. 새로운 AsyncTask 정보가 조금씩 나타납니다. 단일 항목에 대해 충분한 정보를 사용할 수있게되면 목록 어댑터에 항목을 추가하고 주 스레드로 이동하여 notifyDataSetChanged()을 호출하여 목록을 업데이트하십시오. 또한 이미지를 가져 오려면 스레드 풀에 작업을 제출하고 이미지가 준비되면 notifyDataSetChanged()으로 호출하십시오.

  3. 더 이상 처리 할 항목이 없을 때까지 목록을 계속 업데이트하십시오.

내 설정이 꽤 좋다고 생각하지만, 충돌을 일으키는 원인을 추적하는 방법을 개선하기위한 몇 가지 제안을 원합니다.

02-23 21 : 30 : 20.303 : DEBUG/AndroidRuntime (1209) : 30 : 20.313 : VM 02-23 21 종료 여기서

는 로그 캣 출력의 WARN/dalvikvm (1209) : threadid = 1 : catch되지 않은 예외 (그룹 = 0x4001d800)로 종료하는 스레드 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : 치명적인 예외 : 주 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime 1209) : java.lang.IllegalStateException : 어댑터의 내용이 변경되었지만 ListView가 알림을받지 못했습니다. 어댑터의 내용이 백그라운드 스레드에서 수정되지 않고 UI 스레드에서만 수정되었는지 확인하십시오. [어댑터 (클래스 android.widget.HeaderViewListAdapter)를 사용하여 ListView (16908298, 클래스 android.widget.ListView)] 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.ListView.layoutChildren ListView.java:1492) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.AbsListView.onLayout (AbsListView.java:1147) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : android.view.View.layout (View.java:7035) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.LinearLayout.setChildFrame (LinearLayout.java : 1249) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : android.widget.LinearLayout.layoutVertical (LinearLayout.java:1125) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.LinearLayout.onLayout (LinearLayout.java:1042) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.view.View.layout (View.java:7035) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android .widget.FrameLayout.onLayout (FrameLayout.java:333) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.view.View.layout (View.java:7035) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.LinearLayout.setChildFrame (LinearLayout.java:1249) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.LinearLayout .layoutVertical (LinearLayout.java:1125) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.widget.LinearLayout.onLayout (LinearLayout.java:1042) 02-23 21:30:20 .342 : ERROR/AndroidRuntime (1209) : android.view.View.layout (View.java:7035) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : android.widget.FrameLayout.onLayout FrameLayout.java : 333) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : android.view.View.layout (View.java:7035) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : android.view.ViewRoot.performTraversals (ViewRoot.java:1045) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.view.ViewRoot.handleMessage (ViewRoot.java : 1727) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.os.Handler.dispatchMessage (Handler.java:99) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.os.Looper.loop (Looper.java:123) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : android.app.ActivityThread. main (ActivityThread.java:4627) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : java.lang.reflect.Method.invokeNative (기본 메소드) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : java.lang.reflect.Method.invoke (Method.java:521) 02-23 21 : 30 : 20.342 : 오류/AndroidRuntime (1209) : at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:868) 02-23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : com.android.internal.os.ZygoteInit.main (ZygoteInit.java:626) 02- 23 21 : 30 : 20.342 : ERROR/AndroidRuntime (1209) : dalvik.system.NativeStart.main (기본 메소드) 02-23 21 : 30 : 20.402 : WARN/ActivityManager (72) : 강제 종료 활동 com.daveco. pricewatcher/.SearchActivity

+0

당신은 logcat 출력을 제공 할 수 있습니까? – ingsaurabh

답변

3

AsyncTask의 작업자 스레드에서 목록 어댑터를 업데이트 할 때 사용할 수있는 것처럼 들립니다. 같은 어댑터가 UI 스레드에서 순회되어 목록을 렌더링합니다. 이전 notifyDataSetChanged()에 여전히 응답하는 동안 다음 항목에 대한 목록 어댑터를 업데이트 할 수 있기 때문에 임의의 충돌이 발생할 수 있습니다.

목록 어댑터를 업데이트하는 더 좋은 방법은 핸들러를 사용하여 목록 어댑터를 업데이트 할 UI 스레드에 실행 파일을 게시하고 notifyDataSetChanged()을 호출하는 것입니다.

이미지 업데이트로 비슷한 일이 발생할 수 있습니다.

일반적인 전략으로 UI가 종속 된 모든 데이터 구조는 UI 스레드에서 업데이트해야합니다. 그것은 모든 곳에서 더 안전 해지는 경향이 있습니다. 대체 전략은 코드의 중요한 부분을 신중하게 동기화하는 것이지만, 올바르게 진행하는 것이 훨씬 어렵습니다.

+0

핸들러를 사용하여'notifyDataSetChanged()'와 함께 실행 파일을 게시하고 있지만 업데이트와 데이터 변경이 동시에 일어날 수 있다고 생각합니다. – davidk01

+0

무슨 일이 일어 났는지 당신이 옳았습니다. 나는 몇 조각을 움직여 문제를 해결했다. – davidk01