2016-06-06 45 views
0

我目前正在研究我的第一個Android應用程序。如何修改UI線程中聲明的變量,從其他線程?

應用程序訪問數據庫以獲取我想要在屏幕上打印的一些信息。要發送請求並在網絡上獲得答案,我需要使用與UI線程不同的新線程(我將其命名爲「N線程」)。這部分是好的。

現在,我想修改變量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

變量不屬於任何線程。你不應該做你所做的事,而應該看看https://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask(ps:它*是*修改過,但是這種改變沒有發生了) – zapl

回答

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(); 
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運行在一個線程和「onPostExecute」在UI線程上運行,並且它只是叫在doInBackground完成後。這個類是由操作系統「管理」的。要運行它,你只需要實例化它並調用'execute'。我推薦做這樣的事情

你的代碼的事情是線程與你的代碼的其餘部分(對setText的調用)同時運行,這意味着當它運行setText時線程仍然得到事件。