当工作线程工作时,UI变得不连贯

时间:2012-11-06 16:02:46

标签: android multithreading user-interface touch

我有一个手写识别应用程序 - 用户用手指绘制,应用程序识别字符。识别引擎在具有最小可能优先级的工作线程中运行 - Thread.MIN_PRIORITY。这是一个纯粹的CPU /内存算法,没有任何I / O.但是,当线程正在运行时,UI变得相当不稳定。手指笔划会出现明显的延迟。我也注意到触摸事件迷失了。

这究竟是什么线程应该有助于避免?为什么UI线程缺乏CPU?如何说服系统将工作线程视为低优先级后台线程?

看起来系统正在引入(自愿或因为CPU饥饿)invalidate()onDraw()之间的延迟。我可以以某种方式降低延迟吗?

测试相对较旧的硬件 - 使用Android 2.1的HTC Magic。

3 个答案:

答案 0 :(得分:4)

有同样的问题,所以我做了我的话:

  1. 处理了大量工作后的Thread.yield()。

  2. 有限更新发布到UI线程,间隔最小为500毫秒(导致重新绘制的次数少得多)。

  3. 让工作人员处理优先级数据桶,重点是更新视图,用户当前正在与之交互。

  4. 现在整个用户界面真的很懒,但没有滞后。

    以下是我的工作人员的调度方法(实际工作由Process方法完成):

    //--low priority
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
    
    //--as long as there's more work to do, and not cancelled--
    while (mPriorityBuffer.hasNext() && !isCancelled()) {
    
        //--get the work with highest priority--
        Work next = mPriorityBuffer.getNext();
    
        //--do work--
        Update u = mProcessor.process(next);
    
        // collect updates for main thread
        mUpdates.push(u);
    
        long timeNow = Calendar.getInstance().getTimeInMillis();
        if(timeNow - timeLast > 500){
            //--its been quite a while now, update ui--
            postUpdatesToMainThread();
            timeLast = timeNow;
        }
    
        //--let UI thread work on updates--
        Thread.yield();
    }
    

答案 1 :(得分:2)

尝试在字符识别方法

中的主循环中添加Thread.sleep(1)
@Override
public void run() {
  while (!recognited) {

    //do some script

    try {
      Thread.sleep(1);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

这个睡眠让虚拟机能够及早恢复其他线程

答案 2 :(得分:1)

你的GUI线程可能会出现触摸事件,如果是这样,那么解决方案是在UI线程上引入几秒ms等待并提升你的工作线程。更多相关信息:

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/Oe6k1_bm38o

另外,也许你正在处理过多的数据,比如没有实际发生的移动,或者移动不够重要。