[英]How can I update the Main UI with information received from another thread? (While the thread is still running)
我試圖在運行時更新屏幕元素。 但是我無法使它正常工作。
這是一些示例代碼
public static TextView CurrentConnectionAttempt;
CurrentConnectionAttempt = (TextView) findViewById(R.id.CurrentConnectionAttempt);
IntentFilter afilter= new IntentFilter("SomeSortOfFilter");
registerReceiver(SomeReceiver, afilter);
private BroadcastReceiver SomeReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
for (int i = 0; i<100; 1++ )
{
String connectionAttempt = "This is loop Iteration " + i;
CurrentConnectionAttempt.setText(connectionAttempt);
doSomething("Some Parameter");
}
}
};
我想發生的事情是,屏幕Textview將使用“ i”的每個新值進行更新,然后執行一個函數。 我猜這個例子將類似於進度條。
困難的部分是在廣播事件中發現信息。 因此,在主UI線程中找不到該信息。 這就是為什么異步任務和其他多線程選項對我不起作用的原因。 (據我了解)
我研究了這些解決方案。
也許我忽略了一些顯而易見的事情,或者不可能以這種方式影響主UI線程。 任何建議和/或示例均被贊賞。
謝謝!
編輯:我的異步任務是我嘗試過的極其基本的任務。 我什至嘗試了變化。 我認為我的問題可能類似於我剛剛在此博客上閱讀的問題。 異步問題
此處發生的是廣播接收器將在所有循環迭代中運行,並且Async任務中的doInBackground函數將同時觸發,但是在廣播接收器完全完成執行之前,永遠不會觸發onProgressUpdate函數。 然后,onProgressUpdate和onPostExecute將執行多次。 我的猜測是,由於廣播接收器位於與UI不同的線程上,因此它需要在另一個子線程能夠工作之前完全執行。
這是我的代碼,
在我的廣播接收器中:
UpdateDynamicDisplay2 testDisplay= new UpdateDynamicDisplay2();
testDisplay.execute(connectionAttempt );
// This is a sub class in my main class
class UpdateDynamicDisplay2 extends AsyncTask<String, String, String>{
String Testing1;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... aurl) {
publishProgress(aurl[0]);
Testing1 = aurl[0];
MyMainClass.CurrentConnectionAttempt.setText(Testing1);
return Testing1;
}
protected void onProgressUpdate(String... progress) {
MyMainClass.CurrentConnectionAttempt.setText(progress[0]);
}
@Override
protected void onPostExecute(String unused) {
MyMainClass.CurrentConnectionAttempt.setText(unused);
}
}
希望這足以解決。
問題是您試圖通過靜態變量直接從BroadcastReceiver更新UI。 AsyncTask是供活動使用的,而不是由BroadcastReceiver使用的。
更好的方法是讓BroadcastReceiver更新數據源,並讓Activity監視該數據源。
如果您要處理大量數據,那么最好的選擇是創建一個ContentProvider ,然后注冊一個ContentObserver以便在數據更改時獲得通知。
如果只需要對單個值執行此操作,則SharedPreferences可能是一種更簡單的方法。 在這種情況下,您還可以注冊一個偵聽器以進行更改。
最后,您可以創建一個單例並使用數據結構將數據保留在內存中。 您可以實現自己的Observer模式版本,以在數據更改時獲取通知。 這可能不是一個好的長期解決方案,因為Android環境不會對您的內存中對象提供任何長期保證。
這個問題及其答案將使您了解應該去的確切位置! 處理程序有效,但不建議使用。 在Android中,AsycTask更好,更易讀。
編碼愉快!
已編輯
此鏈接包含一些如何更新進度條的源代碼,例如1到100,
http://ketankantilal.blogspot.com/2011/05/how-to-update-progress-bar-using-thread.html
祝好運
最簡單的方法可能是通過處理程序
private Handler handler; //Global Decalration
...
handler = new Handler(); //This is declared in the Main UI thread (onCreate)
然后在正在執行工作的線程中:
handler.post(new Runnable() {
@Override
public void run() {
CurrentConnectionAttempt.setText(ConnectionAttempt);
}
});
希望能奏效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.