Android 从线程更新UI

Android 从线程更新UI,android,android-ui,Android,Android Ui,我在尝试自动更新android活动中的视图时遇到了一些问题。 应用程序会显示一些类似聊天的消息。我正在使用ListView将消息放入ArrayAdapter 我使用此方法更新ListView public void loadMessages() { ArrayList<String> messages = this.dbHelper.getMessages(); conversationArrayAdapter.clear(); conversationArrayAdapter.ad

我在尝试自动更新android活动中的视图时遇到了一些问题。 应用程序会显示一些类似聊天的消息。我正在使用ListView将消息放入ArrayAdapter

我使用此方法更新ListView

public void loadMessages() {
ArrayList<String> messages = this.dbHelper.getMessages();
conversationArrayAdapter.clear();
conversationArrayAdapter.addAll(messages);
conversationArrayAdapter.notifyDataSetChanged();
}
public void loadMessages(){
ArrayList messages=this.dbHelper.getMessages();
conversationArrayAdapter.clear();
会话ArrayAdapter.addAll(消息);
conversationArrayAdapter.notifyDataSetChanged();
}
我的想法是放置一个称为metod的线程,但是当我尝试这样做时,我有以下错误

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


因为您正试图从线程访问或更新UI元素。为避免此错误,您需要使用以下方式从线程更新UI:

Your_Current_Activity.this.runOnUiThread(new Runnable() {

  @Override
    public void run() {

        // Update UI here    
        loadMessages();                             
    }
});
第二种解决方案是使用而不是线程使用此代码

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
        }
}

只能从UI(主)线程更新UI。 下面是一个使用AsyncTask的解决方案

public void asyncCallWithSchedule() {
        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 {
                                new SearchAsync().execute(txtSearch.getText().toString());
                            }
                        });
                }
            };
            timer.schedule(doAsynchronousTask, 0, 2000);
        }
}
异步任务类:

private class SearchAsync extends
AsyncTask < String, Object, List < Users >> {

    @Override
    protected List < Users > doInBackground(String...params) {
        // Call DB here   
        return null;
    }

    @Override
    protected void onPostExecute(List < Users > result) {
        super.onPostExecute(result);
        // Update UI here
    }
}
私有类SearchAsync扩展
AsyncTask>{
@凌驾
受保护列表doInBackground(字符串…参数){
//在这里呼叫数据库
返回null;
}
@凌驾
受保护的void onPostExecute(列表<用户>结果){
super.onPostExecute(结果);
//在此处更新用户界面
}
}
简单:

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();
        }
    });
}
public void loadMessages(){
ArrayList messages=this.dbHelper.getMessages();
conversationArrayAdapter.clear();
会话ArrayAdapter.addAll(消息);
新的处理程序(Looper.getMainLooper()).post(新的Runnable()){
公开募捐{
conversationArrayAdapter.notifyDataSetChanged();
}
});
}

使用AsyncTask而不是普通线程。@User2121530我放置了一个线程,该线程将在5秒后重新加载UI。检查我的答案。