mgulan
mgulan

Reputation: 795

Handler not receiving message

I'm trying to do some work in background thread and after that go to next activity. After the work is done I'm notifying the main thread, but handler never receives this notification.
Here is the code:

public class OnStart extends Activity {

    private static boolean done = false;


    private static Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {              
            Bundle bundle = msg.getData();
            String resultDelivery = bundle.getString("key");
            if (resultDelivery.equals("continue"))
                done = true;
        };
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.on_start);


        Runnable databaseCreator = new Runnable() {
            public void run() {             
                Message msg = handler.obtainMessage();              
                //read database values - this takes 300ms
                Bundle bundle = new Bundle();
                bundle.putString("key", "continue");
                msg.setData(bundle);
                handler.sendMessage(msg);
            }
        };
        Thread mythread = new Thread(databaseCreator);
        mythread.start();


        Runnable runnable = new Runnable() {
            @Override
            public void run() {
               try {
                   while (!done) {
                        //I'M IN THIS LOOP BEFORE MESSAGE FROM PREVIOUS RUNNABLE IS SENT TO HANDLER
                        //CAN'T GET OUT OF THIS LOOP (MESSAGE NEVER RECEIVED)
                        Thread.sleep(50);
                   }
                   Intent i = new Intent(OnStart.this, Main.class);
                   startActivity(i);
               } catch (Exception e) {}
            }
        };
        handler.postDelayed(runnable, 10);

    }

}

Also, I would like to know does this code have memory leak?

Upvotes: 0

Views: 1132

Answers (1)

nKn
nKn

Reputation: 13761

I'd change your implementation using a CountDownLatch(1), so it acts like a semaphore. In your case, try this:

1) Define a CountDownLatch latch = new CountDownLatch(1); as classwide.

2) You don't even need your "runnable" Runnable, so replace it by latch.await() and immediately after call the startActivity() method.

    latch.await();
    Intent i = new Intent(OnStart.this, Main.class);
    startActivity(i);

3) Do the work you need within your databaseCreator implementation. Once you're done, call latch.countDown(); method.

This will do the following: It will execute your code line by line until it reaches the await() call. This will "block" further code execution until it's unblocked. You unblock it just once you got all your database created, and you do it calling countDown(). This will make the CountDownLatch reach 0 count and unblock code execution, so the next statement to run is the startActivity() code.

Regarding yo the leak question - As far as this snipped you've posted goes, it doesn't seem to me to have a leak, but detecting and even more solving Memory Leaks are probably one of the hardest parts of programming, so you'll probably need some additional tools to know if you have or not a leak. I recommend you reading this, it's one of the best articles I've found so far about it and it helped me debugging lots of my apps.

Upvotes: 1

Related Questions