我正在用声音和视觉闪烁在 android 中构建节拍器,当然这两者都需要同步。问题是音频处理发生在后台线程中,我们都非常清楚“只有创建线程层次结构的线程才能更改它的视图”,因此我需要一种方法来让 UI 线程更改视图。那么如何更新 ui 线程与我正在制作的节拍同步呢?这两件事似乎并不同步。有没有比我在下面描述的方法更好的方法来实现这一点?
这是我拥有的当前代码:
public class MetronomeService extends Service implements Runnable
{
//Thread
private HandlerThread handlerThread;
private Handler backgroundHandler;
private Handler uiHandler
//Interface to the Fragment that owns the views
@Setter
private Listener listener;
//Colour view
private ColourViewManager colour = null;
@Override
public void onCreate()
{
handlerThread = new HandlerThread("PlayerHandlerThread", Process.THREAD_PRIORITY_AUDIO);
handlerThread.start();
//For packages of work in the background
this.backgroundHandler = new Handler(handlerThread.getLooper());
//To send messages to the UI
this.uiHandler = new Handler(Looper.getMainLooper())
{
@Override
public void handleMessage(@NonNull Message msg)
{
switch (msg.what)
{
case 0:
{
listener.resetState();
break;
}
case 1:
{
colour = listener.blink();
break;
}
}
}
};
super.onCreate();
}
@Override
public void run()
{
uiHandler.sendEmptyMessage(0);
audioGenerator.playTrack(bpm);
while (playingState.get() == TimerState.PLAYING)
{
uiHandler.sendEmptyMessage(1);
if (colour == PulsingColourToggleButton.PulsingColour.YELLOW)
{
audioGenerator.writeSound(AudioGenerator.TICKING);
} else if (colour == PulsingColourToggleButton.PulsingColour.RED)
{
audioGenerator.writeSound(AudioGenerator.TOCKING);
}
audioGenerator.writeSound(AudioGenerator.SILENCE);
}
audioGenerator.destroy();
colour = null;
}
public void start()
{
backgroundHandler.post(this);
}
}
然后在 Fragment 类上,我用一个简单的方法调用服务
service.start()