从线程更新UI

时间:2013-03-01 12:39:25

标签: android android-ui

我在尝试自动更新Android活动中的视图时遇到了一些麻烦。 应用程序显示一些消息,如聊天。我使用ListView将消息与ArrayAdapter放在一起。

我使用这个metod来更新ListView

public void loadMessages() {
ArrayList<String> messages = this.dbHelper.getMessages();
conversationArrayAdapter.clear();
conversationArrayAdapter.addAll(messages);
conversationArrayAdapter.notifyDataSetChanged();
}

我的想法是设置一个调用该metod的线程,但是当我尝试这样做时,我有以下错误。

  

只有创建视图层次结构的原始线程才能触及其视图。

4 个答案:

答案 0 :(得分:1)

因为您正在尝试从Thread访问或更新UI元素。为避免此错误,您将使用runOnUiThread从Thread更新UI:

Your_Current_Activity.this.runOnUiThread(new Runnable() {

  @Override
    public void run() {

        // Update UI here    
        loadMessages();                             
    }
});

,第二个解决方案是使用AsyncTask而不是线程

答案 1 :(得分:1)

使用此代码。

public class MainActivity extends Activity
{
    private Timer autoUpdate;

    @Override
     public void onResume()
     {
        super.onResume();
        autoUpdate = new Timer();
        autoUpdate.schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                runOnUiThread(new Runnable()
                {
                    public void run()
                    {
                        updateScore();
                    }
                });
            }
        }, 0, 5000); // updates each 5 seconds
     }


     @Override
     public void onPause()
     {
         autoUpdate.cancel();
         super.onPause();
     }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        // initialize view layout
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cleanermain);
        super.onResume();
    }


        private void updateScore()
        {
            // decide output
            // update cricket score
        }
}

答案 2 :(得分:0)

您必须使用自己的线程。这是使用AsyncTask的解决方案......

所有代码都放在您的Activity类中。

    public void toCallAsynchronous() {
                final Handler handler = new Handler();
                Timer timer = new Timer();
                TimerTask doAsynchronousTask = new TimerTask() {
                    @Override
                    public void run() {
                        handler.post(new Runnable() {
                            public void run() {
                                try {


    //ASYNC TASK OBJECT   CALL EVERY 2 SECOND                   
    AutoPretraga zadatak = new AutoPretraga();
    zadatak.execute(txtPretraga.getText().toString());


                            }
                        });
                    }
                };
timer.schedule(doAsynchronousTask, 0, 2000); // execute in every 2 second

            }

AsyncTask类.....

 private class AutoPretraga extends
                AsyncTask<String, Object, List<Korisnici>> {

            @Override
            protected List<Korisnici> doInBackground(String... params) {
   //DONT TOUCH GUI OBJECT IN THIS FUNCTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   //CALL DATABASE IN THIS FUNCTION             


        return null;

            }

            @Override
            protected void onPostExecute(List<Korisnici> result) {


                super.onPostExecute(rezultat);


                //IN THIS FUNCTION YOU HAVE RESUT FROM DATABASE 
                        //AND YOU CAN CHANGE GUI

            }

        }

答案 3 :(得分:0)

简单:

public void loadMessages() {
    ArrayList<String> messages = this.dbHelper.getMessages();
    conversationArrayAdapter.clear();
    conversationArrayAdapter.addAll(messages);

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            conversationArrayAdapter.notifyDataSetChanged();
        }
    });
}