Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update UI from a Runnable?

I need to update ui from runnable. My logic goes like below. I start the runnable from onCreate of the fragment lifecycle. And the runnable instance is responsible to request network. The problem is I don`t know how to update the fragment after runnable instance fetched the data from network.

code to start runnable in fragment in CustomFragment.java.

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

    accountMgr.requestAccountInfo();

}

code to start runnable in 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);

    }
}
like image 887
Logan Guo Avatar asked Sep 17 '25 11:09

Logan Guo


2 Answers

runOnUiThread() requires Activity reference. There are alternatives. You don't need Activity reference to your Thread. You can always get UI handler with the main looper. Pass other arguments like your interface to update the fragment upon completion of your task.

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
    }
}

Anything you run on the instantiated Handler will be on UI thread.

Of course, using runOnUiThread() is totally reasonable.

like image 121
Nikola Despotoski Avatar answered Sep 19 '25 03:09

Nikola Despotoski


you can use runOnUIThread method of activity.

here's code may be help you:

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
                }
            });
        }
    }
}
like image 45
hungkk Avatar answered Sep 19 '25 01:09

hungkk