Android - TextView在拥有快速计数器时会丢失

时间:2015-01-14 22:29:26

标签: android textview counter lag

我最近进入了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信息。它没有第一次滞后,但随后又开始滞后。

1 个答案:

答案 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,而不是每次按下按钮时都提取引用。这些变量不会在代码中发生变化,因此只需将它们作为成员进行一次实例化并重复使用它们。