从线程更新用户界面[重复]

问题描述 投票:-3回答:4

此问题已经在这里有了答案:

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

我使用此方法来更新ListView

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

我的想法是放置一个调用该方法的线程,但是当我尝试执行此操作时,出现以下错误。

仅创建视图层次结构的原始线程可以触摸其视图。

android android-ui
4个回答
0
投票

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

AsyncTask类:

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

1
投票

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

Your_Current_Activity.this.runOnUiThread(new Runnable() {

  @Override
    public void run() {

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

第二种解决方法是使用AsyncTask而不是线程


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

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();
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.