簡體   English   中英

如何使用從另一個線程收到的信息更新主UI? (雖然線程仍在運行)

[英]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線程中找不到該信息。 這就是為什么異步任務和其他多線程選項對我不起作用的原因。 (據我了解)

我研究了這些解決方案。

  1. 創建一個可運行的
  2. 我試過AyncTask
  3. 創建第二個廣播接收器

也許我忽略了一些顯而易見的事情,或者不可能以這種方式影響主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更好,更易讀。

如何讓Asynctask以不同方式更新UI

編碼愉快!

已編輯

此鏈接包含一些如何更新進度條的源代碼,例如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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM