简体   繁体   中英

How can I modify a variable declared in the UI Thread, from an other thread?

I'm currently working on my first Android application.

The application accesses a database to get some informations that I want to print on the screen. To send requests and get answers on the network, I need to use a new thread (I'll name it "N thread"), different from the UI Thread. This part is ok.

Now, I want to modify the variable eventList to get the values stored in a collection, in the N thread.

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

    ...
}

The problem is : eventList is not modified. How can modify this variable and print it from the UI thread ? Thank you for your help.

You can use runOnUiThread function or Handler to update UI from other thread. I suggest you reading the below tutorial first: AndroidBackgroundProcessing

Try this

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

}

This AsyncTask does what you want, the doInBackground runs on a thread and the 'onPostExecute' runs on the UI thread, and it's only called after the doInBackground finishes. This class is "managed" by the OS. To run it you just need to instantiate it and call 'execute'. I recommend doing something like this

The thing with your code is that the thread runs at the same time as the rest of your code (the calls to the setText), this means when it runs the setText the Thread is still getting the events.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM