我正在开发一个运行检查房间噪音水平的服务的应用程序,活动是一个每250毫秒运行一次的处理程序,但我的问题是,它只在屏幕处于活动状态时运行,根据我的研究,处理程序运行在UI线程,因此很有可能它只在UI线程上运行,这就是为什么它只在我看的时候运行的原因,你能帮我一个方法来运行下面的代码:
handler = new Handler();
final Runnable r = new Runnable() {
int count = 0;
public void run() {
// Get the volume from 0 to 255 in 'int'
double volume = 10 * mSensor.getTheAmplitude() / 32768;
volumeToSend = (int) volume;
volumeVisual = "";
for( int i=0; i<volumeToSend; i++){
volumeVisual += "|";
updateUI();
Log.d("HandlerLooper", "Oscillating :" + count+1);
}
handler.postDelayed(this, 250); // amount of delay between every cycle of volume level detection + sending the data out
}
};
// Is this line necessary? --- YES IT IS, or else the loop never runs
// this tells Java to run "r"
handler.postDelayed(r, 250);
在我的服务中没有在UI线程上运行,只是在我的服务中运行?
这是我的完整服务代码:
public class VolumeListerner extends Service {
private static String volumeVisual = "";
private static int volumeToSend;
private Handler handler;
private SoundMeter mSensor;
/** interface for clients that bind */
IBinder mBinder;
/** indicates whether onRebind should be used */
boolean mAllowRebind;
/** The service is starting, due to a call to startService() */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
soundLevelCheck();
return super.onStartCommand(intent, flags, startId);
}
private void soundLevelCheck()
{
mSensor = new SoundMeter();
try {
mSensor.start();
Toast.makeText(getBaseContext(), "Sound sensor initiated.", Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler = new Handler();
final Runnable r = new Runnable() {
int count = 0;
public void run() {
// Get the volume from 0 to 255 in 'int'
double volume = 10 * mSensor.getTheAmplitude() / 32768;
volumeToSend = (int) volume;
volumeVisual = "";
for( int i=0; i<volumeToSend; i++){
volumeVisual += "|";
updateUI();
Log.d("HandlerLooper", "Oscillating :" + count+1);
}
handler.postDelayed(this, 250); // amount of delay between every cycle of volume level detection + sending the data out
}
};
// Is this line necessary? --- YES IT IS, or else the loop never runs
// this tells Java to run "r"
handler.postDelayed(r, 250);
}
private void updateUI()
{
Intent intent = new Intent( "UI_UPDATER" );
intent.putExtra("VolumeBars", "Volume Bars: " + String.valueOf(volumeVisual));
intent.putExtra("volumeLevel","Volume Levels: " + String.valueOf(volumeToSend));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
所有帮助都将提前感谢您。
答案 0 :(得分:2)
Android Service
将始终在UI线程中运行,但IntentService
除外,它将为您创建工作线程。
因此,当您在服务中创建Handler
时,它将附加到UI线程。
我建议您使用包含可以传递给HandlerThread
的循环器的Handler
。示例如下。
HandlerThread handlerThread = new HandlerThread("NoiceHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
答案 1 :(得分:1)
postDelayed()
不是Service
的绝佳解决方案。如您所知,它与主应用程序线程相关联,通常我们希望服务不在主应用程序线程上工作。
使用其他标准Java计时机制like ScheduledExecutorService
。