2012-10-19 2 views
2

백그라운드 스레드에 의해 listactivty의 내용을 업데이트하기 위해 따라야 할 모범 사례는 무엇입니까?)?java.lang.IllegalStateException : 어댑터의 내용이 변경되었지만 ListView .... notifydatasetchanged() 호출의 동기

1) 을 호출하면 사용자가 어댑터의 내용을 조작하자마자 notifyDataSetChanged() 어댑터를 업데이트하지만 사용자가 스크롤하거나 목록을 클릭하는 동안 앱이 강제로 닫힙니다. 이 포인터를 막는 것은 매우 도움이 될 것입니다.

Logcat : java.lang.IllegalStateException : 어댑터의 내용이 변경되었지만 ListView가 알림을받지 못했습니다.

2) 어디에서 exaclty가 Listactivity의 내용을 업데이트해야합니까? doInBackground() 또는 onProgressUpdate() 내부에 있습니까?

3) 사용자가 목록 항목을 클릭 할 때 정기적으로 충돌이 발생합니다. 그러면 백그라운드 작업 중에 listactivty에서 클릭 이벤트를 사용 중지하면 문제가 해결됩니까? 그렇다면 항목을 제거하거나 설정하는 방법을 listactivity에 동적으로 적용하는 방법이 확실하지 않습니다. 나에게도 가르쳐주세요.

4) 백그라운드 비동기 작업 실행 중에 모든 UI 상호 작용을 차단하는 것이 문제를 해결하는 유일한 방법이라고 생각하지 않습니다. 이 작업을 수행하는 간단한 방법이 있지만 도움이 필요하다는 것을 알고 있습니다. 사전에

감사합니다.

내에서 onCreate ...

protected void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState); 
setContentView(R.layout.fa); 

tvStatus=(TextView) findViewById(R.id.tvStatus); 

adapter = new SimpleAdapter(
     this, 
     mostPopularList, 
     R.layout.list_item, 
     new String[] {"title","author","views","date"}, 
     new int[] {R.id.textView1,R.id.textView2,R.id.textView4,R.id.textView3}); 
     //populateList(); 


     setListAdapter(adapter); 
    } 

내 비동기 작업입니다 ...

  private class LongOperation extends AsyncTask<String, Void, String> { 

      @Override 
      protected String doInBackground(String... params) { 
     // code for adding new listactivty items 
      }  

      @Override 
      protected void onPostExecute(String networkStatus) { 
      adapter.notifyDataSetChanged(); 
      } 

      @Override 
      protected void onPreExecute() { 

      } 

      @Override 
      protected void onProgressUpdate(Void... values) { 

      } 
      } 

로그 캣 :

에 내가 거의하여 illegalstate 예외도 ... 수 없습니다 그것을 재현하십시오. 내가 다시 만나면 logcat을 게시 할 것입니다.

FATAL EXCEPTION: main 
java.lang.IndexOutOfBoundsException: Invalid index 7, size is 4 
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257) 
    at java.util.ArrayList.get(ArrayList.java:311) 
    at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147) 
    at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126) 
    at android.widget.SimpleAdapter.getView(SimpleAdapter.java:114) 
    at android.widget.AbsListView.obtainView(AbsListView.java:1294) 
    at android.widget.ListView.makeAndAddView(ListView.java:1727) 
    at android.widget.ListView.fillDown(ListView.java:652) 
    at android.widget.ListView.fillGap(ListView.java:623) 
    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944) 
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:2065) 
    at android.widget.ListView.onTouchEvent(ListView.java:3315) 
    at android.view.View.dispatchTouchEvent(View.java:3766) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671) 
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107) 
    at android.app.Activity.dispatchTouchEvent(Activity.java:2086) 
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936) 
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671) 
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107) 
    at android.app.Activity.dispatchTouchEvent(Activity.java:2086) 
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655) 
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1785) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:123) 
    at android.app.ActivityThread.main(ActivityThread.java:4627) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:521) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
+0

listView.postInvalidate()는 어떻습니까? – Shark

+0

게시물을 게시하십시오 나머지 고양이의 더 나은 이해를 위해 –

답변

4

2) exaclty 내가 listactivity의 내용을 업데이트해야 어디? doInBackground() 또는 onProgressUpdate() 내부에 있습니까? 당신이 doInBackground() 콘텐츠를 변경하고 비동기 작업을 호출 이후 시간이 좀 걸릴 수 있기 때문에 onProgressUpdate() 내부 또는 onPostExecute() 내부

당신이

  @Override 
      protected void onPostExecute(String networkStatus) { 
      adapter.notifyDataSetChanged(); 
      } 

3) 정기적 인 충돌을 경험하고 있습니까 호출 할 때 사용자가 클릭 리스트 항목. 그러면 백그라운드 작업 중에 listactivty에서 클릭 이벤트를 사용 중지하면 문제가 해결됩니까? 그렇다면 항목을 제거하거나 설정하는 방법을 listactivity에 동적으로 적용하는 방법이 확실하지 않습니다. 나에게도 가르쳐주세요.

해결책이 아닙니다. UI 스레드에서 데이터 세트를 업데이트하기 만하면됩니다. (콘텐츠를로드하지 않고 이전 버전에서 새 버전으로 업데이트). 예 :

private class LongOperation extends AsyncTask<String, Void, String> { 

     @Override 
     protected List<String> doInBackground(String... params) { 
      List<String> items = loadUpdatedDataset(params); 
      return items; 
     }  

     @Override 
     protected void onPostExecute(List<String> loadedItems) { 
     updateAdapterDataset(loadedItems); 
     adapter.notifyDataSetChanged(); 
     } 

     @Override 
     protected void onPreExecute() { 

     } 

     @Override 
     protected void onProgressUpdate(Void... values) { 

     } 
     } 
2

이 클래스에서 확인하십시오. AsyncTask 및 Listview http://android.okhelp.cz/java_android_code.php?o=%5Candroid-15%5CGestureBuilder%5Csrc%5Ccom%5Candroid%5Cgesture%5Cbuilder%5CGestureBuilderActivity.java#Problem을 사용하는 좋은 예가 있습니다.

나는 귀하의 코드에있는 문제는 어댑터가 ListView를 업데이트하고 현재 사용자가 응용 프로그램에서 충돌을 일으키는 ListView를 클릭하기 때문이라고 생각합니다.

+0

나 역시 같은 생각. 하지만 내 listactivty에 대한 itemclick 리스너가 없습니다. 더 이상 때때로 가끔 다음과 같은 오류가 발생 java.lang.IndexOutOfBoundsException : 잘못된 인덱스 2, 크기는 0입니다. 나는 추락이 스크롤에서 발생하는 것으로 의심합니다 :-( – Jani

1

이 예외는 잘못된 것입니다. 많은 원인이 있습니다. 이 충돌의 원인 중 하나는 ArrayList 개체를 완전히 변경할 수 없다는 것입니다. 내가 항목을 제거 할 때 그래서, 나는이 작업을 수행해야한다 :

mList.clear(); 
mList.addAll(newDataList); 

나를 위해 충돌을 해결했습니다.

+0

그것은 나를 위해 일합니다! 고마워요. – EliaszKubala

0

이 문제는 저를 오랫동안 귀찮게합니다.

나는 listView 전에 Adapter.notifyDataSetChanged()를 호출 클릭 MotionEvent를 사용

, 그것은 Illegalstate 예외 원인 않습니다.

listView 업데이트 전에 ListView.setEnable (false)을 호출하는 것이 유용하다고 생각합니다.

관련 문제