2

我在一个单独的线程中从网络接收数据(这是在其他一些类中,这里是整个问题,但是由于遗留代码的固有复杂性,我不能将接收代码放在活动类中)并且我想更新接收数据时的 ListView(实时).. 为此,我创建了一个 ListView、ArratAdapter 和一个 ArrayList variavles...以下是一些相关代码

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()现在,每当收到新的好友时,我都会从线程中调用该方法......这是一个静态方法,因为接收者线程在不同的类中......

但是代码不起作用,请给我建议以改进此代码。我知道它不好,但我不知道如何解决它,因为我缺乏对安卓编程的了解。我还在某处读到DataSetObserver它们可以在我的情况下使用..我是android领域的新手,所以请原谅我缺乏基本概念....谢谢,

编辑 我忘了提到的一件事是我没有从单独的线程更新 UI(我知道我不能),我所做的是每当 Somedata (为了简单起见我当然做了所有过滤)到达时我调用 addBuddy()...

现在在 UI 线程上,我将调用notifyDataSetChanged()ArrayAdapter 的方法来进行视图更新。

编辑 2 以下是我接收数据的另一个线程中的代码..

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

我收到以下错误 适配器的内容已更改,但 ListView 未收到通知。

4

2 回答 2

1

您应该阅读android 开发者网站上的Processes and Threads 。

即使您在单独的线程上进行工作,也无法从另一个进程访问 UI 线程。

解决此问题的一种方法是实现AsyncTask来完成工作,然后通过该onPostExecute方法更新您的适配器。

于 2012-05-09T08:11:22.033 回答
0

在阅读了几乎所有关于 SO 的类似问题后,我终于通过以下步骤解决了它:-

  1. 修复了调用 addBuddy() 方法的线程中的一些设计问题,
  2. 将我的 addBuddy 方法更改为

    公共无效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);
                    }
                });
    }
    

我还更改了应用程序的整体设计,因为我在寻找这个问题的答案时变得更聪明了。现在我使用 Singelton 类和静态变量共享数据。如果其他人将来遇到类似问题,以下链接可能会很有用。

无痛穿线

单例类

使用线程

对于那些有类似问题的人来说,最好的建议是“相信自己,你可以做到”。

于 2012-05-10T12:10:45.063 回答