处理程序没有收到消息

时间:2014-02-02 19:30:42

标签: android multithreading memory-leaks handler message-queue

我正在尝试在后台线程中做一些工作,之后转到下一个活动。工作完成后,我通知主线程,但处理程序从未收到此通知 这是代码:

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);

    }

}

另外,我想知道这段代码是否有内存泄漏?

1 个答案:

答案 0 :(得分:1)

我会使用CountDownLatch(1)更改您的实现,因此它就像一个信号量。在你的情况下,试试这个:

1)将CountDownLatch latch = new CountDownLatch(1);定义为全班。

2)您甚至不需要“runnable”Runnable,因此请在调用latch.await()方法后立即将其替换为startActivity()

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

3)在databaseCreator实施中完成所需的工作。完成后,请调用latch.countDown();方法。

这将执行以下操作:它将逐行执行您的代码,直到它到达await()调用。这将“阻止”进一步的代码执行,直到它被解除阻塞。只要创建了所有数据库,就可以取消阻止它,然后调用countDown()。这将使CountDownLatch达到0计数并取消阻止代码执行,因此下一个要运行的语句是startActivity()代码。

关于你的漏洞问题 - 至于你发布的信息,我觉得我没有泄漏,但检测甚至更多解决内存泄漏可能是编程中最困难的部分之一,所以你可能需要一些额外的工具来知道你是否有泄漏。我建议你阅读this,这是我迄今为止发现的最好的文章之一,它帮助我调试了很多我的应用程序。