从主线程冻结app调用工作线程中的方法

时间:2014-01-24 11:27:04

标签: java android multithreading

我的主线程正在创建一个新线程的实例。这个新线程创建了一个节拍器的实例。如果我尝试通过按钮点击主线程调用节拍器play()方法,那么节拍器开始但整个应用程序冻结。

主要活动代码:

public class HomeScreen extends Activity {

MetroThread metronome;


/*** onCreate ***/  

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

metronome = new MetroThread();
metronome.start();
}

/*** button clicks ***/

public void st44BtnClick(View v)
{
if(metronome.myMetronome==null)
{
    metronome.playMetronome();
}
else if(metronome.myMetronome!=null)
{
    metronome.stopMetronome();
}
}

和节拍器线程代码:

public class MetroThread extends Thread
{   
//create instance of the metronome
public Metro myMetronome;

public void run()
{
System.out.println("metroThread started");
}

/*** play metronome ***/
public void playMetronome()
{
myMetronome = new Metro();
myMetronome.bpm = 200;
myMetronome.beat = 7;
myMetronome.beatSound = 2000;
myMetronome.sound = 2600;
myMetronome.play();
}
/*** stop metronome ***/
public void stopMetronome()
{
    myMetronome.stop();
myMetronome = null;
}

}

如果不是使用按钮点击调用playMetronome方法,我只需从节拍器线程中的run()调用该方法,它工作正常并且不会锁定应用程序。

3 个答案:

答案 0 :(得分:0)

那是对的。这些方法在实际调用Thread的Thread中执行。由于您是从UI线程调用它们,因此这些是在UI线程中执行的。尝试从playMetronome方法

调用run()

答案 1 :(得分:0)

仅仅因为方法与线程对象相关联并不意味着它在该特定线程上运行。事实上,在这种情况下,您的Metronome线程实际上已立即退出,一旦您从run()方法返回,它就会结束。

当您调用playMetronome方法时,实际上是通过按钮单击线程调用它。

你需要做的是向Metronome线程发送一个信号,然后让它开始播放...或创建一个新的Metronome并在按下按钮时启动线程并拥有线程总是播放声音。

答案 2 :(得分:0)

只有来自您的工作线程的run()调用的代码才能真正在单独的线程中运行。现在你正在创建第二个线程,但是在主线程中进行所有操作(因为你从它调用play()

你可以:

1)在第二个线程中添加布尔标志isPlaying并从mainThread更改它的值

2)在第二个帖子run()中启动无限循环,有时会在这里检查此标志。