我最近进入了Android编码,我认为我可以制作的前几个应用程序之一是一个计数器应用程序。用户只需按下屏幕底部的按钮,TextView就会计数,每个数字出现100毫秒。另外,每次数字变化时,我也会在后台播放滴答声。然而,问题是有时候反击滞后。每隔一段时间它会跳过1或2个数字,但咔哒响声仍然响起。以下是按下按钮的相关代码:
public void onRedButtonPress(View view) {
count = 0;
limit = 40;
final TextView counter = (TextView) findViewById(R.id.Counter);
final AudioManager audioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
final float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
new Thread(new Runnable() {
public void run() {
while (count < limit) {
try {
Thread.sleep(100);
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
soundPool.play(soundID, volume, volume, 1, 0, 1f);
} catch (InterruptedException ie) {
}
counter.post(new Runnable() {
@Override
public void run() {
counter.setText("" + count);
}
});
count++;
}
}
}).start();
}
这是activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:orientation="vertical" >
<TextView
android:id="@+id/Counter"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textSize="50sp"
android:text="0"/>
<ImageButton
android:src="@drawable/selector"
android:background="@null"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:onClick="onRedButtonPress" />
</LinearLayout>
&#34; @可绘制/选择&#34;只是一个xml,它在按下的按钮和普通按钮的两个图像之间切换。
我尝试更改&#34;新线程(...)&#34; to&#34; runOnUiThread(...)&#34;但后来它只显示0和40而且之间没有数字。我使用AudioManager获取设备上的声音设置,并使用SoundPool实际播放声音。声音存储为.wav文件。有没有办法让它不滞后或只是增加每个数字的持续时间?如果重要的话,我会使用Android Studio。
编辑:我尝试从计算机上拔下设备,因为我认为每次更改号码时我的手机都会发送LogCat信息。它没有第一次滞后,但随后又开始滞后。
答案 0 :(得分:2)
这可能是因为你在线程中睡了100毫秒。如果该睡眠的目标是以100秒的间隔执行您的代码,请尝试使用Handler对象。阅读它。你可以创建一个这样的:
Handler mHandler = new Handler(Looper.getMainLooper());
这会点击Android OS中主线程的消息队列。如果你想要每100毫秒发生一次,你可以这样做:
mHandler.post(new Runnable() {
@Override
public void run() {
// Do your work in here
// Update the TextView
// If you want to run this again in 100 ms?
mHandler.postDelayed(this, 100);
// If not then by not reposting this Runnable won't get called anymore
// In your case if you hit your limit, don't run this again
}
}
我认为您不需要线程来发出声音通知。还要记住,创建一个新线程是一个昂贵的过程。你绝对需要一个,在Java中查看ThreadPoolExecutors。这将为您管理线程创建和Runnables的执行。
您可以做的另一件事是将引用缓存到TextView,AudioManager和max volume,而不是每次按下按钮时都提取引用。这些变量不会在代码中发生变化,因此只需将它们作为成员进行一次实例化并重复使用它们。