Search code examples
androidmultithreadingcocoa-touchui-thread

Accessing UI-Thread from a non-activity object like ([self performSelectorOnMainThread]) in iOS


I've moved from iOS applications development to android so I'm facing some problems finding some functions I used to use before.

Is there a function like [self performSelectorOnMainThread:@selector() withObject: waitUntilDone:]; in android that can be accessed from an instance of any class, knowing that this class is not inheriting from the Activity class.

I've found that there is a function runOnUiThread that does this, but I couldn't use it since I need to call it from a non-activity object, so is there a way to access the current visible activity or should I use another solution.


Solution

  • If you don't have an activity object, you can use handlers. The class "Handler" can update the UI. A handle provides methods for receiving messages and for runnables. To use a handler you have to subclass it and override handleMessage() to process messages. To process runnables, you can use the method post(); You only need one instance of a handler in your activity.

    You thread can post messages via the method sendMessage(Message msg) or sendEmptyMessage.

    Sample example

    1. Handler Example

    In this example we use the class "Handler" to update a ProgressBar in a background thread.

    Create a new Android project "de.vogella.android.handler" with the activity "ProgressTestActivity". Create the following layout "main.xml". This layout contains the ProgressBar and sets its appearance via a style.

    Change your activity to the following:

    package de.vogella.android.handler;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.widget.ProgressBar;
    
    public class ProgressTestActivity extends Activity {
    private Handler handler;
    private ProgressBar progress;
    
    
    /** Called when the activity is first created. */
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progress = (ProgressBar) findViewById(R.id.progressBar1);
        handler = new Handler();
    }
    
    public void startProgress(View view) {
        // Do something long
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 10; i++) {
                    final int value = i;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            progress.setProgress(value);
                        }
                    });
                }
            }
        };
        new Thread(runnable).start();
    }
    }
    

    Run your application. Once you press your button the ProgressBar will get updated from the background thread.

    The sample is from http://www.vogella.de/articles/AndroidPerformance/article.html#concurrency_handler