如何从其他线程修改UI线程中声明的变量?

时间:2016-06-06 17:11:49

标签: java android multithreading

我目前正在开发我的第一个Android应用程序。

应用程序访问数据库以获取我想在屏幕上打印的一些信息。要在网络上发送请求并获得答案,我需要使用一个新的线程(我将其命名为“N thread”),与UI线程不同。这部分还可以。

现在,我想修改变量 eventList 以获取N线程中存储在集合中的值。

public class MainActivity extends AppCompatActivity {
public List<Event> eventList = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    /* I fill the list in an other thread */
    new Thread(new Runnable() {
        public void run(){
            eventList = new WebService().getEvents(); //returns a list
        }
        // if I check here, eventList contains elements
    }).start();


    /* I check the result */
    TextView respView = (TextView) findViewById(R.id.responseView);
    if(eventList != null)
    {
        respView.setText("Ok");
    } else {
        respView.setText("Not ok");
    }

    ...
}

问题是: eventList 未被修改。如何修改此变量并从UI线程中打印? 谢谢你的帮助。

3 个答案:

答案 0 :(得分:1)

您可以使用runOnUiThread函数或Handler从其他线程更新UI。我建议您先阅读以下教程:AndroidBackgroundProcessing

答案 1 :(得分:0)

试试这个

new AsyncTask<Void, Void, Void>() {
    @Override
    protected Void doInBackground(Void... params)
    {
        eventList = new WebService().getEvents();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TextView respView = (TextView) findViewById(R.id.responseView);
                if(eventList != null)
                {
                    respView.setText("Ok");
                } else {
                    respView.setText("Not ok");
                }
            }
        });
    }
}.execute();

答案 2 :(得分:0)

 private class EventsDownloader extends AsyncTask<Void, Void, Void> {
 protected Long doInBackground(Void... params) {
    eventList = new WebService().getEvents()
 }

 protected void onPostExecute(Void result) {
     TextView respView = (TextView) findViewById(R.id.responseView);
     if(eventList != null)
     {
         respView.setText("Ok");
     } else {
         respView.setText("Not ok");
     }
 }

}

这个AsyncTask做你想要的,doInBackground在一个线程上运行,并且&#39; onPostExecute&#39;在UI线程上运行,并且只在doInBackground完成后调用它。这个班级是管理的#34;由操作系统。要运行它,您只需要实例化它并调用&#39;执行&#39;。我建议做这样的事情

你的代码就是线程与代码的其余部分(对setText的调用)同时运行,这意味着当它运行setText时,线程仍在获取事件。