2

別のスレッドでネットワークからデータを受信して​​います(これは他のクラスにありますが、ここで問題全体が発生しますが、レガシーコードの固有の複雑さのために受信コードをアクティビティクラスに入れることはできません)更新したいデータが受信されたときのListView(リアルタイム)..そのために、ListView、ArratAdapter、およびArrayList変数を作成しました...以下は関連するコードです

public class LogInSuccessActivity extends Activity {
    private String LOG_TAG = "LogInSuccessActivity";
    private TextView welcomeTxtLbl = null;
    private ListView buddyListView = null;
    private ArrayAdapter<Buddy> buddyListAdapter = null;
    // BuddyList
    private ArrayList<Buddy> buddyList = null;


    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loginsuccess);
        // get the TextView and ListView
        welcomeTxtLbl = (TextView) findViewById(R.id.loginsuceeslbl);
        buddyListView = (ListView) findViewById(R.id.buddylistview);

        String uname = getIntent().getStringExtra("username");
        if (uname != null) {
            welcomeTxtLbl.setText("Welcome " + uname + ", Greetings!!");
        } else {
            welcomeTxtLbl.setText("SignIn successfull !!");
        }
        buddyList = new ArrayList<Buddy>();
        buddyListAdapter = new ArrayAdapter<Buddy>(this,
                android.R.layout.simple_list_item_1, buddyList);
        buddyListView.setAdapter(buddyListAdapter);

        // persist the context
        ReceiverThread.loginSuccessActi = LogInSuccessActivity.this;
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onResume()
     * 
     * @Override protected void onStart() { // TODO Auto-generated method stub
     * super.onStart();
     * 
     * }
     */

    @Override
    protected void onStop() {
        super.onStop();
        Log.e(LOG_TAG, "onStop is called ");
        buddyListAdapter.clear();
        buddyList.clear();

    }

    public void addBuddy(Buddy buddy) {
        buddyList.add(buddy);
        buddyListAdapter.notifyDataSetChanged();
    }

    Runnable updateTheListView = new Runnable() {
        @Override
        public void run() {
            // synchronized (buddyList) {
            buddyListAdapter.notifyDataSetChanged();

            // }
        }
    };

    public void refreshTheListView(Buddy buddy) {
        System.out.println("Refreshing the ListView list size is : "
                + buddyList.size());
        buddyList.add(buddy);
        // buddyListAdapter.add(buddy);
        // buddyListView.post(updateTheListView);
        this.runOnUiThread(updateTheListView);
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onDestroy()
     */
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        Log.e(LOG_TAG, "onDestroy is called ");
        super.onDestroy();
        buddyList = null;
        buddyListAdapter = null;
        buddyListView = null;
        ReceiverThread.loginSuccessActi = null;
    }

}

スレッドから、新しいバディが受信されるたびにメソッドを呼び出しますaddBuddy()...レシーバースレッドが別のクラスにあるため、これは静的メソッドです...

ただし、コードは機能していません。このコードを改善するための提案をお願いします。私はそれが良くないことを知っていますが、Androidプログラミングの知識が不足しているため、修正方法がわかりません. また、私の場合に使用できるかどうかについてもどこかで読みDataSetObserverました..私はAndroidアリーナの初心者なので、基本的な概念が不足していることを許してください....ありがとう、

編集 私が言及するのを忘れていた 1 つのことは、私は別のスレッドから UI を更新していないことです (私はできないことを知っています)。 addBuddy() を呼び出します...

UI スレッドnotifyDataSetChanged()で、ArrayAdapter のメソッドを呼び出して、ビューの更新を実行します。

EDIT 2 以下は、データを受信する別のスレッドのコードです..

    if (loginSuccessActi != null) {
                        loginSuccessActi.refreshTheListView(new Buddy(values));
//                      loginSuccessActi.addBuddy(new Buddy(values));
                    }

次のエラーが表示 されますアダプターのコンテンツが変更されましたが、ListView は通知を受け取りませんでした。

4

2 に答える 2

1

Android 開発者サイトのProcesses and Threadsを読んでください。

別のスレッドで作業を行っていても、別のプロセスから UI スレッドにアクセスすることはできません。

これを回避する 1 つの方法は、AsyncTaskを実装して作業を行い、メソッドを介してアダプターを更新するonPostExecuteことです。

于 2012-05-09T08:11:22.033 に答える
0

SOに関するほぼすべての同様の質問を読んだ後、最終的に次の手順を使用して解決しました:-

  1. addBuddy() メソッドを呼び出していたスレッドのいくつかの設計上の問題を修正しました。
  2. addBuddy メソッドを次のように変更しました

    public void addBuddy(最後の相棒) {

        Log.i(LOG_TAG, " ADDING BUDDY + " + buddy);
        buddyListView.post(// UI thread ;
                new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        synchronized (buddyList) {
                            buddyList.add(buddy);
                            buddyListAdapter.notifyDataSetChanged();
                        }
                        // buddyListAdapter.add(buddy);
                    }
                });
    }
    

この問題の答えを探しているうちに賢くなったので、アプリケーションの OverAll のデザインも変更しました。今では、Singelton クラスと静的変数を使用してデータを共有しています。次のリンクは、他の誰かが将来同様の問題を抱えている場合に役立ちます。

痛みのないスレッディング

シングルトン クラス

スレッドの使用

同じような問題を抱えている人には、 「自分を信じて、できる」というのが一番のアドバイスです。

于 2012-05-10T12:10:45.063 に答える