0

しばらくの間、この問題を解決しようとして、頭を壁にぶつけました。私は経験豊富なAndroidの人ではないので、その解決策は本当に簡単かもしれません。そうは言っても、私は次のコードを持っています:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.adminusers);
    super.onCreate(savedInstanceState);

    // set user_type for Viewall
    mUserType = 0;

    lv_adminusersListContent.addFooterView(footerView);
    mUsersAdapter = new AdminUsersAdapter(mUsersList, AdminUsers.this);
    lv_adminusersListContent.setAdapter(mUsersAdapter);

    getUsersList();

}

private void getUsersList() {

    if (UsefulFcts.isOnline(AdminUsers.this)) {

        if (mThread != null && mThread.isAlive()) {
            mThread.interrupt();
        }

        mThread = new Thread() {
            @Override
            public void run() {

                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        pDialog = new ProgressDialog(AdminUsers.this);
                        pDialog.setMessage("Loading.. Please wait!");
                        pDialog.setCancelable(false);
                        pDialog.show();
                    }
                });

                mUsersList.clear();
                mUsersList.addAll(mServiceManager.getUsersList(mUserType,
                        0 + "", AdminServiceManager.sHowManyToLoad));
                mArrayLength = mUsersList.size();

                Log.d("arrayLength", String.valueOf(mArrayLength));
                Log.d("total_results",
                        String.valueOf(ParserJSON.total_results));

                mHandler.post(new Runnable() {

                    @Override
                    public void run() {

                        // refresh listview

                        mUsersAdapter.notifyDataSetChanged();

                        if (mArrayLength < ParserJSON.total_results) {

                            lv_adminusersListContent
                                    .addFooterView(footerView);

                        } else if (mArrayLength >= ParserJSON.total_results) {

                            lv_adminusersListContent
                                    .removeFooterView(footerView);
                        }

                        if (0 == mArrayLength) {

                            Toast.makeText(AdminUsers.this,
                                    "No username found!",
                                    Toast.LENGTH_SHORT).show();
                        }

                        pDialog.dismiss();
                    }
                });
            }
        };
        mThread.start();
    } else {
        Toast.makeText(AdminUsers.this, "Internet connection required!",
                Toast.LENGTH_LONG).show();
    }
}

@Override
protected void linkUI() {

    // begin load_more view
    footerView = AdminUsers.this.getLayoutInflater().inflate(
            R.layout.loadmore, null);

    btn_loadmore = (Button) footerView.findViewById(R.id.btn_loadmore);
    // end load_more view

    btn_adminusersViewall = (Button) findViewById(R.id.btn_adminusersViewall);
    btn_adminusersAdmins = (Button) findViewById(R.id.btn_adminusersAdmins);
    btn_adminusersClients = (Button) findViewById(R.id.btn_adminusersClients);
    btn_adminusersDevs = (Button) findViewById(R.id.btn_adminusersDevs);

    btn_adminAdd = (ImageButton) findViewById(R.id.btn_adminAdd);

    lv_adminusersListContent = (ListView) findViewById(R.id.lv_adminusersListContent);
}

@Override
protected void setAction() {

    // begin Buttons UnderHeader

    btn_adminusersViewall.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            UsefulFcts.setButtonClicked(btn_adminusersViewall,
                    btn_adminusersClients, btn_adminusersAdmins,
                    btn_adminusersDevs);

            mUserType = 0;

            mArrayLength = -1;

            lv_adminusersListContent.removeFooterView(footerView);

            getUsersList();

        }
    });

    btn_adminusersClients.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            UsefulFcts.setButtonClicked(btn_adminusersClients,
                    btn_adminusersDevs, btn_adminusersAdmins,
                    btn_adminusersViewall);

            mUserType = 1;

            mArrayLength = -1;

            // view.setVisibility(View.GONE);

            getUsersList();
        }
    });

    btn_adminusersDevs.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            UsefulFcts.setButtonClicked(btn_adminusersDevs,
                    btn_adminusersClients, btn_adminusersAdmins,
                    btn_adminusersViewall);

            mUserType = 2;

            mArrayLength = -1;

            lv_adminusersListContent.removeFooterView(footerView);

            getUsersList();
        }
    });

    btn_adminusersAdmins.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            mUserType = 3;

            mArrayLength = -1;

            lv_adminusersListContent.removeFooterView(footerView);

            getUsersList();
        }
    });

    // end Buttons UnderHeader

    btn_loadmore.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            mThread2 = new Thread() {
                @Override
                public void run() {
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {

                            progressBar = new ProgressDialog(
                                    AdminUsers.this);
                            progressBar
                                    .setMessage("Loading more projects.. ");
                            progressBar.setCancelable(true);
                            progressBar.show();
                        }
                    });

                    mUsersList.addAll(mServiceManager.getUsersList(
                            mUserType, String.valueOf(mArrayLength),
                            AdminServiceManager.sHowManyToLoad));

                    mArrayLength = mUsersList.size();

                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {

                            mUsersAdapter.notifyDataSetChanged();

                            if (mArrayLength >= ParserJSON.total_results) {
                                lv_adminusersListContent.removeFooterView(footerView);
                            }
                            progressBar.dismiss();
                        }
                    });

                };
            };
            mThread2.start();
        }
    });

注:基本的に、押しているボタン(タブのように見える)に応じてサーバーから要求されるコンテンツのリストビューがあります(mUserType = 0/1/2/3)。また、[さらに読み込む]ボタンを使用します(footerView =ボタン付きのシンプルなレイアウト)。すべてが正常に機能しているように見えますが、ボタンを数回「再生」した後(乱数!)、次の例外がスローされてクラッシュします。

02-21 11:00:49.252: E/AndroidRuntime(11728): java.lang.IllegalStateException: 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. [in ListView(2131296461, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]

そのため、コードを振り返りましたが、「UIスレッドにない」リストビュー通知は表示されませんでした。

1.問題は何でしょうか?

2. 2つのスレッド(mThreadとmThread2)を使用する必要がありますか、それとも同じスレッドを使用できますか?一方の作業はもう一方の終了時に開始する必要があり(またはそうではありませんか?)、静的であると宣言する必要がありますか?

また、将来使用できる「グッドプラクティス」のトリック、または私が行った「間違ったプラクティス」を教えていただければ幸いです。

PS。linkUI()とsetAction()はsuper()。onCreate()で呼び出されます。

4

1 に答える 1

2

エラーメッセージは理解できるようです:mThreadからアダプタを変更しています:

mUsersList.clear();
mUsersList.addAll(mServiceManager.getUsersList(mUserType,
                    0 + "", AdminServiceManager.sHowManyToLoad));

あなたはこのようなことを試すことができます:

            final List newUserList = mServiceManager.getUsersList(mUserType,
                    0 + "", AdminServiceManager.sHowManyToLoad);

            mArrayLength = newUserList.size();

            Log.d("arrayLength", String.valueOf(mArrayLength));
            Log.d("total_results",
                    String.valueOf(ParserJSON.total_results));

            mHandler.post(new Runnable() {

                @Override
                public void run() {
                    mUsersList.clear();
                    mUsersList.addAll(newUserList);
                    // refresh listview

                    mUsersAdapter.notifyDataSetChanged();
于 2013-02-21T09:30:21.687 に答える