Jason
Jason

Reputation: 49

Struggling with upating my UI from Thread

I have tried AsyncTask, Handler, and a simple Thread to achieve what I am trying to do but I just cannot get any of them to work, below is the logic that I need to use to update my UI...

public class GameProcessor extends Thread {

@Override
public void run() {

    for (Integer integer : sequence) {

        //set button state to pressed
        Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //set button state to un-pressed

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    try {
        sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


}

}

Please do not respond with, you cannot update the UI from anywhere but the main thread, I already know this and need a solution on how to loop through some values from the backend while updating the UI at the same time. From what I can tell, AsyncTask and Handler will not help much.

Any help will be very appreciated!

Upvotes: 0

Views: 87

Answers (5)

Luc
Luc

Reputation: 2805

Did you try?

instanceOfActivity.runOnUiThread(new Runnable(){
    @Override
    public void run() {
        Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);
    }
});

But in this case, I don't suggest you use an activity in another object.

Please using interface like above:

public interface INotifyChange {
     void notify(object value); // Example: void notify(int progress);
}

In your activity where invoke GameProcessor

INotifychange mNotifier;

mNotifier = new INotifyChange() {
    @Override
    public void notify(object value) {
        runOnUiThread(new Runnable(){
            @Override
            public void run() {
                //You can update your UI here.
            }
        });
    }
};

// And your GameProcessor

private INotifyChange mNotifier;
public GameProcessor(INotifyChange aNotifier) {
    mNotifier = aNotifier;
}

// Where you want to update UI, please invoke

mNotifier.notify(value);

Upvotes: 0

Milan
Milan

Reputation: 1875

In order to update your UI thread you can use the handler. Here's a simple example of using AsyncTask and Handler:

    private static final String MESSAGE_KEY = "com.example.mypackage.MSGKEY";
    private static final int MESSAGE_AUTHENTICATING = 0;
    private static final int MESSAGE_AUTHENTICATED = 1;

    /**
     * This handler will update UI 
     * 
     */
    private final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.getData().getInt(MESSAGE_KEY)) {
            case MESSAGE_AUTHENTICATING:
                hashstream_stream.setVisibility(View.GONE);
                hashstream_progress.setVisibility(View.VISIBLE);
                break;
            case MESSAGE_AUTHENTICATED:
                hashstream_stream.setVisibility(View.VISIBLE);
                hashstream_progress.setVisibility(View.GONE);
                break;
            default:
                break;

            }
        }
    };

    /**
    * This method should be used to update UI thread.
    * 
    * @param value
    */
    private void postMessage(int value) {
        Message msgObj = handler.obtainMessage();
        Bundle bundle = new Bundle();
        bundle.putInt(MESSAGE_KEY, value);
        msgObj.setData(bundle);
        handler.sendMessage(msgObj);
    }

    /**
     * AsyncTask Helper class as network op
     * 
     * 
     */
    private class StreamHashTagTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            //Do actual operation in here

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            postMessage(MESSAGE_AUTHENTICATED);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            postMessage(MESSAGE_AUTHENTICATING);
        }

        /**
         * If you need to update progress override onProgressUpdate() method.
         * Since I am indeterminate using progress bar as authentication time
         * cannot be calculated , I don't need update here
         */

    }

Upvotes: 0

Sushil
Sushil

Reputation: 8478

    If you want to loop through some valuse, while updating the UI at the same time, then you may consider using AsyncTask and may use this feature:

    protected void onProgressUpdate(Integer... progress) {
             setProgressPercent(progress[0]);
         }

    And from :
    protected Long doInBackground(URL... urls) {
                 calculate value
                 publishProgress(value);
              return totalSize;
         }

    This will keep on updating UI thread with intermediate values you send.

    In case you already know this and have tried and it does not solve your purpose, am sorry :)

or you can try this:

public void run() {

        Console.post(new Runnable() {
            public void run() {
                Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);
            }
        });
    }

Upvotes: 0

Waza_Be
Waza_Be

Reputation: 39538

If you know about the UI thread, why don't you:

runOnUiThread(new Runnable() {
    public void run() {
        //set button state to un-pressed or pressed.. or whatever you want..
    }
});

I don't understand your problem

Upvotes: 3

Tenfour04
Tenfour04

Reputation: 93511

Create a member Handler object in your Activity (mHandler). Whenever you want to update your UI from the other thread, call

mHandler.post(new Runnable(){
    public void run(){
        //update the button state
    }
});

The Handler will call this run() method in the UI thread for you.

This is simplified. You will probably want to create your Runnables as member variables so your aren't recreating the same Runnables over and over.

Upvotes: 0

Related Questions