线程冻结屏幕



所有这些都在同一个类和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循环不应该永远运行,但我不确定。

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

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

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

你可能应该删除线程并找到其他方法来实现你想要的。

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

你似乎在主线程(UI线程)内做你的工作的主要部分,我不认为你想在这里使用连接。如果你想保留这一机制,那么带有条件对象的可重入锁可能就是你所需要的。有了这个,当你想要阻塞时,你将能够在你的线程对象内await,当按钮被按下时,signal

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

但是,除非您想在按钮被按下之前进行处理,否则在操作发生时惰性地创建线程可能是一种好方法。AsyncTask可能也很好看

最新更新