线程冻结屏幕

时间:2014-08-11 20:05:25

标签: java android multithreading

所有这些都在同一个类和onCreate方法中:

String arrayExtra[] = {"1"};
for(int x = 0; x < arrayExtra.length; x++){
Thread thread = new Thread(new Runnable(){
    @Override
    public void run(){
        try{
            final EditText etAbun = (EditText) findViewById(R.id.etIsoAbunNum);
            synchronized(this){
                wait();
                allExtraiso.add(etAbun.getText().toString());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
});

Thread thread2 = new Thread(new Runnable(){

    @Override
    public void run(){
        try{
            synchronized(this){
                Thread.sleep(1000);
                final Button bNext = (Button) findViewById(R.id.bIsoAbunSave);
                bNext.setOnClickListener(new OnClickListener(){

                    @Override
                    public void onClick(View arg0){
                        notify();
                    }
                });
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
});

thread.start();
thread2.start();
try{
    thread.join();
}catch(InterruptedException e){
    e.printStackTrace();
}
try{
    thread2.join();
}catch(InterruptedException e){
    e.printStackTrace();
}
}

这段代码应该做的是创建2个线程,等待按钮单击,然后单击按钮时,执行notify(),然后继续剩下的代码。这样做只是冻结屏幕。 for循环不应该永远运行,但我不确定。

2 个答案:

答案 0 :(得分:1)

您正在启动单独的线程并立即调用它们的join()。调用join()由主线程执行(因为你在onCreate中)。这个方法的作用是告诉你当前的线程等到另一个线程完成。所以你的主线程被阻塞,直到另一个线程死掉。

但你的线程正在等待用户点击按钮。用户事件由UI线程处理,该线程当前在join()中被阻止。因此,不处理单击,永远不会调用事件处理程序,并且您有死锁情况。

应尽可能避免使用多线程,因为它会给您的程序增加很多复杂性,并且通常不会增加任何好处。在android中做一些耗时的事情是必要的,你不想用这个任务来阻止UI线程。

您应该删除线程并找到其他方法来实现您想要的目标。

<强>更新

您的代码实际上存在另一个问题,这也会阻止它工作:您正在同步,等待和通知不同的对象。因此,即使处理了click事件,对notify()的调用也永远不会到达wait()中的线程。

答案 1 :(得分:0)

你似乎在主线程(UI线程)中做了大部分工作我不认为你想在这里使用join。如果你想保留这个机制,那么带有Condition对象的可重入锁可能就是你正在寻找的。有了这个,你可以在你想要阻止的时候await内部阻塞对象,按下按钮时可以signal

http://developer.android.com/reference/java/util/concurrent/locks/ReentrantLock.html

但除非你想在按下按钮之前进行处理,否则在动作发生时懒洋洋地创建线程可能是一个好方法。 AsyncTask也可能非常好看。