簡體   English   中英

如何從Runnable更新UI?

[英]How to update UI from a Runnable?

我需要從runnable更新ui。 我的邏輯如下。 我從片段生命周期的onCreate開始運行。 而可運行實例負責請求網絡。 問題是可運行實例從網絡獲取數據后,我不知道如何更新片段。

在CustomFragment.java中的片段中開始運行的代碼。

public void onCreate(Bundle savedInstanceState) {
    Log.d(DEBUG_TAG, "onCreate");
    super.onCreate(savedInstanceState);

    accountMgr.requestAccountInfo();

}

在AccountManager.java中啟動可運行代碼

/**
 * request Account info from server
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void requestAccountInfo() {
    Account act = getCurrentAccount();
    Thread t = new Thread(new RequestAccountInfoTask(act));
    t.start();
}

/**
 * automatically update Account info, like space usage, total space size, from background.
 */
 class RequestAccountInfoTask implements Runnable {

    private Account account;

    public RequestAccountInfoTask(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        doRequestAccountInfo(account);

    }
}

runOnUiThread()需要Activity參考。 還有其他選擇。 您不需要對Thread Activity引用。 您始終可以通過主循環程序獲取UI處理程序。 傳遞其他參數(例如您的界面)以在任務完成時更新片段。

class RequestAccountInfoTask implements Runnable {

    private Account account;
    private Handler mHandler;
    public RequestAccountInfoTask(Account account) {
        this.account = account;
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void run() {
        doRequestAccountInfo(account);
        //use the handler
    }
}

您在實例化Handler上運行的所有內容都將位於UI線程上。

當然,使用runOnUiThread()是完全合理的。

您可以使用runOnUIThread方法進行活動。

這里的代碼可能會幫助您:

class RequestAccountInfoTask implements Runnable {

    private Account account;

    public RequestAccountInfoTask(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        doRequestAccountInfo(account);
        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // you can update fragment UI at here
                }
            });
        }
    }
}

請看一下AsyncTask以從線程更新UI:

http://developer.android.com/reference/android/os/AsyncTask.html

以下是上述鏈接的重點內容:

類概述AsyncTask支持正確且輕松地使用UI線程。 此類允許執行后台操作並在UI線程上發布結果,而無需操縱線程和/或處理程序。

AsyncTask被設計為圍繞Thread和Handler的幫助器類,並且不構成通用的線程框架。 理想情況下,應將AsyncTasks用於較短的操作(最多幾秒鍾)。如果需要使線程長時間運行,則強烈建議您使用java.util.concurrent包提供的各種API,例如執行程序,ThreadPoolExecutor和FutureTask。

異步任務由在后台線程上運行的計算定義,並且其結果發布在UI線程上。 異步任務由3個通用類型(稱為Params,Progress和Result)以及4個步驟(稱為onPreExecute,doInBackground,onProgressUpdate和onPostExecute)定義。

您無法從可運行狀態更新UI。 您需要用於更新UI的處理程序。 請參閱以獲取更多信息。

用戶界面只能由創建它的線程修改。 在大多數情況下,是通過UI線程進行的。 因此,您需要使用runOnUiThread方法進行更新。 祝好運

我知道答案有點不同。 但我希望您能看到Android注釋。 哪個都很好用。 我僅將它們用於背景和Ui線程。 通過在方法名稱上編寫@Background,在后台線程中執行所有任務。 並在UI線程中進行所有UI更新。 我建議您只檢查一次。 http://androidannotations.org/謝謝,至於您的回答是否值得關注。 您無法從runnable更新UI。 請參閱asyn任務以更新您的Ui。

我建議您使用AsynTask,也可以嘗試使用

getActivity().runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    Toast.makeText(getActivity(), "ON UI Thread", Toast.LENGTH_LONG).show();
                }
            });

您可以使用事件總線來完成它-http://square.github.io/otto/這很簡單。 只需在需要更新UI時從線程發送事件,如下所示:

...
//in the end of your heavy job:
bus.post(new YourEvent());

並在您的Activity創建方法中:

@Subscribe
public void onYourEvent(YourEvent event) {
    //do what you want there
}

順便說一句,您可以通過事件傳遞任何數據,這是您的自定義類! 請閱讀手冊,了解如何設置該庫,注冊總線活動。 這是非常有用且易於使用的

您可以創建一個Runnable,然后將其發布到主線程。 摘自Google關於流程和線程的開發人員頁面

此實現是線程安全的:后台操作是從單獨的線程完成的,而ImageView總是從UI線程進行操作。

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // a potentially  time consuming task
            final Bitmap bitmap =
                    processBitMap("image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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