2

バックグラウンド スレッド (非同期タスク) によって listactivty の内容を更新するために従うべきベスト プラクティスは何ですか?

1)アダプターの内容を操作するとすぐにアダプターを更新するためにnotifyDataSetChanged()を呼び出していますが、ユーザーがリストをスクロールまたはクリックしている間、アプリは強制的に閉じられます。これを防ぐための指針は非常に役に立ちます。

Logcat: java.lang.IllegalStateException: アダプターの内容が変更されましたが、ListView は通知を受け取りませんでした。

2) listactivity の内容をどこで正確に更新する必要がありますか? doInBackground() または onProgressUpdate() 内?

3) ユーザーがリスト項目をクリックすると、通常のクラッシュが発生します。バックグラウンド操作中にlistactivtyのクリックイベントを無効にすると、問題は解決しますか? その場合、アイテムクリックリスナーを動的にリストアクティビティに削除または設定する方法がわかりません。についても教えてください。

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) {

           }
          }

ログキャット:

私はめったに違法状態の例外もありません...それを再現できません。もう一度見つけたら、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)
4

4 に答える 4

4

2) listactivity の内容をどこで正確に更新する必要がありますか? doInBackground() または onProgressUpdate() 内?

onProgressUpdate()onPostExecute() の内部または内部でコンテンツを変更しdoInBackground()、非同期タスクを呼び出すと、

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

3) ユーザーがリスト項目をクリックすると、通常のクラッシュが発生します。バックグラウンド操作中にlistactivtyのクリックイベントを無効にすると、問題は解決しますか? その場合、アイテムクリックリスナーを動的にリストアクティビティに削除または設定する方法がわかりません。についても教えてください。

これは解決策ではありません。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) {

       }
      }
于 2012-10-19T16:50:17.677 に答える
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 をクリックしてアプリケーションがクラッシュしたためだと思います。

于 2012-10-19T16:57:46.423 に答える
1

この例外は誤解を招きます。多くの原因があります。このクラッシュの原因の 1 つは、ArrayList オブジェクトを完全に変更できないことです。したがって、アイテムを削除するときは、次のことを行う必要があります。

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

これでクラッシュが修正されました。

于 2013-03-27T21:08:01.837 に答える