0

以下のアクティビティでこのエラーが表示される場合と、そうでない場合があります。

The content of the adapter has changed
but ListView did not receive a notification. Make sure the content of
your adapter is not modified from a background thread, but only from the
UI thread. 

しかし、以下のクラスのどこに間違いがあるのか​​ わかりません。誰にもアイデアはありますか?

public class FavoriteActivity extends SpeakSuperActivity {

        private final static String TAG = FavoriteActivity.class.getSimpleName();

        private Button btn_filter_topic, btn_filter_rating, btn_filter_none;
        private TextView fav_filter_text;
        private static ListView listViewFavorites;
        private static TextView txtNoFavoritesYet;
        private List<Favorite> currentFavorites;
        private ArrayAdapter<Favorite> currentFavoritesArrayAdapter;

        // required for list loading piece by piece
        final int itemsPerLoading = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;
        boolean loadingMore = false;
        private List<Long> idList;
        int currentDataLoaded;

        private static int oldBtnViewId = 0;

        // set the start value as same as the loading value
        int maximumDataLoadedYet = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;

        // 0 = not sorted, 1 = sorted by topic and minimum number of stars
        private int caseSelection = 0;

        private static View progressView;

        private View footerView;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.favorites);
            Log.d(TAG, "FavoritesScreen onCreate()...");

            // indicator for waiting processes
            progressView = UIUtils.addBlockingProgressIndicatorBlack(this);

            // init Listview
            listViewFavorites = (ListView) findViewById(R.id.fav_listview_favorites);

            // add the footer before adding the adapter, else the footer
            // will not load!
            footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listviewfooter, null, false);
            listViewFavorites.addFooterView(footerView);

            listViewFavorites = (ListView) findViewById(R.id.fav_listview_favorites);

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

            btn_filter_none = (Button) findViewById(R.id.btn_fav_filter_none);
            btn_filter_topic = (Button) findViewById(R.id.btn_fav_filter_topic);
            btn_filter_rating = (Button) findViewById(R.id.btn_fav_filter_rating);

            toggleButtonStates(R.id.btn_fav_filter_none);

            LoadDataTask ldTask = new LoadDataTask();
            ldTask.execute();

            // no favorites yet?
            txtNoFavoritesYet = (TextView) findViewById(R.id.fav_no_favorites_yet);

            updateUI();

        }

        /**
         * An asynchronous Task (doesn't block the UI Thread) for loading the Data in background.
         * 
         * @author Jonas Soukup
         */
        private class LoadDataTask extends AsyncTask<Void, Void, LoudmouthException> {

            private final String TAG = LoadDataTask.class.getName();

            protected void onPreExecute() {
                super.onPreExecute();

                if (FavoriteProvider.getInstance().getNumOfFavorites() != 0)
                    progressView.setVisibility(View.VISIBLE);
                else
                    progressView.setVisibility(View.GONE);

                listViewFavorites.setVisibility(View.GONE);

                fav_filter_text.setVisibility(View.GONE);

                btn_filter_none.setVisibility(View.GONE);
                btn_filter_topic.setVisibility(View.GONE);
                btn_filter_rating.setVisibility(View.GONE);
            }

            protected LoudmouthException doInBackground(Void... params) {
                LoudmouthException exception = null;

                Log.d(TAG, "loading data..");
                switch (caseSelection) {
                case 0:
                    // Get FavoriteList without sorting
                    idList = FavoriteProvider.getInstance().getFavoritesByDate();
                    break;
                case 1:
                    // Get FavoriteList sorted by
                    // Topics + amount of stars
                    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

                    float minRating = prefs.getFloat(getResources().getString(R.string.rating_filter_star_amount), 0);

                    idList = FavoriteProvider.getInstance().getFavoritesByTopicAndMinRating(minRating);
                    break;
                default:
                    Log.e(TAG, "No Case with number: " + caseSelection);

                }

                // reset data loaded, so it loads till maximumDataLoadedYet on a
                // refresh of the list
                currentDataLoaded = 0;

                // reset List on Data change
                currentFavorites = new ArrayList<Favorite>();

                Log.d(TAG, "..loading data finished");

                return exception;
            }

            protected void onPostExecute(LoudmouthException result) {

                try {
                    Log.d(TAG, "LoadDataTask.onPostExecute()");
                    super.onPostExecute(result);
                    progressView.setVisibility(View.GONE);
                    if (result != null) {
                        // Error ocurred during loading
                        android.content.DialogInterface.OnClickListener retryClickListener = new android.content.DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog, int which) {
                                new LoadDataTask().execute();

                            }
                        };
                        UIUtils.showRetryCancelAlertDialog(getApplicationContext(), result, retryClickListener, null);
                    } else {
                        // Everythings fine, data loaded

                        // showing & hiding

                        if (FavoriteProvider.getInstance().getNumOfFavorites() == 0) {

                            fav_filter_text.setVisibility(View.GONE);
                            btn_filter_none.setVisibility(View.GONE);
                            btn_filter_topic.setVisibility(View.GONE);
                            btn_filter_rating.setVisibility(View.GONE);
                        } else {

                            fav_filter_text.setVisibility(View.VISIBLE);
                            btn_filter_none.setVisibility(View.VISIBLE);
                            btn_filter_topic.setVisibility(View.VISIBLE);
                            btn_filter_rating.setVisibility(View.VISIBLE);
                        }

                        if (idList.size() == 0) {
                            txtNoFavoritesYet.setVisibility(View.VISIBLE);
                            listViewFavorites.setVisibility(View.GONE);
                        } else {
                            txtNoFavoritesYet.setVisibility(View.GONE);
                            listViewFavorites.setVisibility(View.VISIBLE);

                            runOnUiThread(new Runnable() {
                                public void run() {
                                    btn_filter_none.setOnClickListener(new OnClickListener() {
                                        public void onClick(View v) {
                                            caseSelection = 0;
                                            FavoriteProvider.getInstance().setCurrentFavoriteListStateDirty(true);
                                            toggleButtonStates(v.getId());
                                            updateUI();
                                        }
                                    });

                                    btn_filter_topic.setOnClickListener(new OnClickListener() {
                                        public void onClick(View v) {
                                            caseSelection = 1;
                                            TopicFilterFavDialog tfFavDialog = new TopicFilterFavDialog(FavoriteActivity.this, FavoriteActivity.this, v
                                                    .getId());
                                            tfFavDialog.show();
                                        }
                                    });

                                    btn_filter_rating.setOnClickListener(new OnClickListener() {
                                        public void onClick(View v) {
                                            caseSelection = 1;
                                            RatingFilterFavDialog ratDialog = new RatingFilterFavDialog(FavoriteActivity.this, FavoriteActivity.this, v
                                                    .getId());
                                            ratDialog.show();
                                        }
                                    });
                                }
                            });
                        }
                    }

                    // init listview displaying with data loaded step by step
                    currentFavoritesArrayAdapter = new FavoriteArrayAdapter(FavoriteActivity.this, FavoriteActivity.this, R.layout.favorite_list_entry,
                            currentFavorites);
                    listViewFavorites.setAdapter(currentFavoritesArrayAdapter);
                    currentFavoritesArrayAdapter.notifyDataSetChanged();


                } catch (Exception exception) {
                    // silent catch because activity could be closed meanwhile
                    Log.i(TAG, "silent exception catch in onPostExecute: " + exception.getMessage());
                }
            }
        }

        /**
         * Update UI
         */
        public void updateUI() {
            LoadDataTask ldTask = new LoadDataTask();
            ldTask.execute();
            if (currentFavoritesArrayAdapter != null)
                currentFavoritesArrayAdapter.notifyDataSetChanged();
        }

        @Override
        protected void onResume() {
            super.onResume();
            updateUI();
        }

        private class ListMoreItemsTask extends AsyncTask<Void, Void, LoudmouthException> {
            @Override
            protected LoudmouthException doInBackground(Void... arg0) {
                LoudmouthException exception = null;

                loadingMore = true;

                // reset loading values if adapter was reseted
                if (currentFavoritesArrayAdapter.getCount() == 0)
                    maximumDataLoadedYet = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;

                // Get value of Configuration.LOADEDITEMSONLISTATONCE new listitems
                for (; currentDataLoaded < maximumDataLoadedYet && currentDataLoaded < idList.size(); currentDataLoaded++) {

                    // Fill the list with new information
                    currentFavorites.add(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded)));
                }
                maximumDataLoadedYet += itemsPerLoading;

                // Done loading more.
                loadingMore = false;

                return exception;
            }

            protected void onPostExecute(LoudmouthException result) {
                if (result == null) {
                    // Tell to the adapter that changes have been made, this will
                    // cause
                    // the list to refresh
                    currentFavoritesArrayAdapter.notifyDataSetChanged();

                    // remove loading view when maximum data is reached
                    if (currentFavorites.size() == idList.size()) {
                        listViewFavorites.removeFooterView(footerView);
                    }
                }
            }
        }

        public void toggleButtonStates(int viewId) {

            // set clicked button as selected
            if (viewId != 0) {
                switch (viewId) {
                case R.id.btn_fav_filter_none:
                    btn_filter_none.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_neuste_selected), null, null,
                            null);
                    btn_filter_none.setTextColor(getResources().getColor(color.black));
                    break;
                case R.id.btn_fav_filter_topic:
                    btn_filter_topic.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_themen_selected), null, null,
                            null);
                    btn_filter_topic.setTextColor(getResources().getColor(color.black));
                    break;
                case R.id.btn_fav_filter_rating:
                    btn_filter_rating.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_rating_selected), null, null,
                            null);
                    btn_filter_rating.setTextColor(getResources().getColor(color.black));
                    break;
                default:
                    Log.d("TAG", "No View with id: " + viewId);
                }
            }

            // if previews Button exists and wasn't the same button set the old
            // one
            // to selected false
            if (oldBtnViewId != 0 && oldBtnViewId != viewId) {
                // set clicked button as not selected
                switch (oldBtnViewId) {
                case R.id.btn_fav_filter_none:
                    btn_filter_none.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_neuste), null, null, null);
                    btn_filter_none.setTextColor(getResources().getColor(R.color.font_grey));
                    break;
                case R.id.btn_fav_filter_topic:
                    btn_filter_topic.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_themen), null, null, null);
                    btn_filter_topic.setTextColor(getResources().getColor(R.color.font_grey));
                    break;
                case R.id.btn_fav_filter_rating:
                    btn_filter_rating.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_rating), null, null, null);
                    btn_filter_rating.setTextColor(getResources().getColor(R.color.font_grey));
                    break;
                default:
                    Log.d("TAG", "No View with id: " + viewId);
                }
            }
            oldBtnViewId = viewId;
        }

    }
4

1 に答える 1

1

ListMoreItemsTasks で currentFavorite を変更すると失敗します。これは、アダプターをサポートする基になるリストです。

変更はdoInBackground、UI スレッドではない で行われます。

publishProgress を使用して UI スレッドに追加するデータを受け取り、そこにあるアダプターに追加することをお勧めします (配列ではなく、アダプターのメソッドを介して、おそらくアダプターを作成した後に保持しないでください)。

編集

交換

private class ListMoreItemsTask extends AsyncTask<Void, Void, LoudmouthException> {

private class ListMoreItemsTask extends AsyncTask<Void, Favorite, LoudmouthException> {

進行は好きな要素で、

currentFavorites.add(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded)));

publishProgress(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded));

さらに、AsyncTask に onProgressUpdate を挿入します。

onProgressUpdate(Favorite... values) {
    currentFavorites.add(values[0]);
    currentFavoritesArrayAdapter.notifyDataSetChanged();
}
于 2012-11-21T16:45:54.710 に答える