【问题标题】:Android: Increase responsiveness of phone screen?Android:提高手机屏幕的响应能力?
【发布时间】:2012-01-05 21:16:14
【问题描述】:

有没有办法提高设备对特定应用程序的响应能力?具体来说,现在我的触摸事件肯定会触发,但它们会延迟几分之一秒。由于我的应用程序是音乐/节奏应用程序,因此任何延迟都非常糟糕。我只是想知道,如果我可以在 Manifest 中做些什么来提高响应能力。或者也许有一些建议可以让代码运行得更快?我还必须在应用程序中创建多个线程来处理多点触控,也许有一种有效的方法可以做到这一点?

最好, 阿尼姆

编辑:

public boolean onTouchEvent(final MotionEvent ev) {
    if(ev.getAction()==ev.ACTION_DOWN||ev.getActionMasked()==ev.ACTION_POINTER_DOWN){                   
        AudioManager mgr = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        int streamVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
        PointF[] touchPoints = new PointF[ev.getPointerCount()];
        for(int i = 0; i < ev.getPointerCount(); i++){
            touchPoints[i] = new PointF(ev.getX(i),ev.getY(i));
        }
        for(final PointF point : touchPoints){
            x = ev.getX(ev.getActionIndex());
            y = ev.getY(ev.getActionIndex());
            int ptx = (int) (x - x%widthIncrement);
            int pty = (int) (y - y%heightIncrement);
            playSound(pointMap.get(new Point(ptx,pty)));
        }
        return true;
    }
    return true;
}

public void playSound(int sound){
    AudioManager mgr = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
    int streamVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
    database.play(sound, streamVolume, streamVolume, 1, 0, 1);
}

【问题讨论】:

  • 我不明白为什么需要多个线程来处理多点触控。你能详细说明一下吗?
  • 所以我的应用程序基本上是一个鼓乐器,我将屏幕分成多个区域,每个区域都有独特的声音。我想要,因为如果我同时按下三个区域,可以同时听到三个声音。我认为使用线程可以解决问题,而不是迭代地进行,并且它可以工作。也许有更好的方法?

标签: android touch screen multi-touch


【解决方案1】:

如果您的 UI 反应迟缓,则说明您在响应 UI 事件时做了大量工作。如果您必须执行任何重要的操作(加载声音文件等)来响应 UI 事件,那么您应该将这些工作打包到 AsyncTask 或其他类型的工作线程中。然后,UI 响应方法应该只是启动线程来完成繁重的工作,更新 UI,然后返回。

文章Painless Threading 有更多关于如何做这一切的细节。

【讨论】:

  • 好吧,我实际上在“onMeasure”方法期间将所有声音加载到 SoundPool 中,我认为该方法是在构造视图时运行的。然后我散列指向 SoundPool 中的声音,以便在发生触摸事件时,我使用坐标从散列图中检索声音。你认为如果使用 I AsyncTask 从哈希图中检索声音会有所帮助吗? (我认为从 hashmap 获取已经优化)
  • @Aneem - 听起来你做事的方式是正确的。没错,从哈希映射中检索足够快,可以在 UI 线程上完成。现在的问题是,罪魁祸首是您的代码还是 SoundPool 中的一些滞后。作为一个实验,你能不能在调用SoundPool.play(或者你做任何事情告诉系统播放声音)后立即在 UI 中弹出一些东西?
  • 感谢您的提示!我做了图像测试,看起来图像比声音反应灵敏得多。我认为归根结底,可能只是设备上的声音较慢,但以防万一您好奇,我在原始查询中发布了一些代码。
  • @Aneem - 不幸的是,Android 存在已知的音频延迟问题(请参阅臭名昭著的 issue 3434。尽管已经 2.5 岁,但它仍然是一个悬而未决的问题。
  • 啊,非常感谢!希望这个问题在不久的将来得到解决!
【解决方案2】:

您应该在接收触摸事件的 UI 线程上处理触摸事件。您不需要使用多个线程来处理多个接触点。所有活动接触点的数据都将包含在您收到的单个 MotionEvent 对象中。

如果您遇到一些时间问题,您可能会发现 MotionEvent 提供的事件时间值很有用。您可以获取 MotionEvent 表示的最新事件以及已批处理到其中的任何历史事件的事件发生时间。您可以在处理事件时将事件时间与当前时间进行比较,从而允许您检查“回到时间”以正确确定事件是否以您正在寻找的节奏发生。 (这里使用的刻度中的当前时间可以从SystemClock.uptimeMillis()获取。)

相关方法: MotionEvent#getEventTime() MotionEvent#getHistoricalEventTime(int)

正如 Ted Hopp 所说,您还应该尝试将任何重量级处理移出 UI 线程。响应 UI 事件的速度越快,队列中待处理的触摸事件就越快。

【讨论】:

  • "有关所有活动接触点的数据将包含在您收到的单个 MotionEvent 对象中。"但是我如何才能同时播放所有接触点声音呢?不是必须有某种并发性吗?
  • 另外,我需要实时播放声音,不及时检查是否违背了这样做的目的?抱歉,我是新手!
  • 您可以使用相同的偏移量开始播放正在进行的声音。至于混音,您不需要使用线程一次播放多个声音。某些 Android 设备具有非常高的音频延迟(发出播放命令和听到音频之间的时间) - 即使按时处理触摸事件,您也可能会遇到这种情况。
  • 摆脱了线程的东西,它现在确实工作得更好了。我正在发布一些代码,以便您了解到目前为止我是如何编写它的。您能否给我一个提示,告诉我如何合并与时间相关的方法,例如 getEventTime() ?
猜你喜欢
  • 1970-01-01
  • 2019-06-07
  • 2014-09-04
  • 2019-12-15
  • 2012-08-31
  • 2016-04-03
  • 2011-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多