当工作线程的工作原理,用户界面​​变得波涛汹涌波涛汹涌、线程、工作原理、用户界面

2023-09-06 02:11:04 作者:我爱你就行了

我有一个手写识别的应用程序 - 用户绘画用他们的手指,该应用程序可识别的字符。该识别引擎的工作线程具有最小可能的优先级运行 - 从Thread.MIN_PRIORITY 。这是一个纯粹的CPU /内存算法,没有I / O任何责任。尽管如此,当线程正积极时,UI变得相当不稳定。手指招取一个明显的延迟出现。我也注意到触摸事件迷路。

I have a handwriting recognition app - the user draws with their finger, the app recognizes characters. The recognition engine runs in a worker thread that has the the minimal possible priority - Thread.MIN_PRIORITY. It's a purely CPU/memory algorithm, no I/O whatsoever. Still, when the thread is actively working, the UI becomes rather choppy. The finger strokes take a noticeable delay to appear. I also notice touch events getting lost.

这不正是线程应该避免?为什么UI线程饥饿CPU?如何说服该系统处理工作线程的,还有,一个低优先级后台线程?

Isn't that exactly what threading was supposed to help avoid? Why is the UI thread starved for CPU? How do convince the system to treat the worker thread as, well, a low-priority background thread?

它看起来像系统介绍(自愿或因CPU饥饿))之间的延迟无效(的OnDraw()。我能以某种方式降低了延迟?

It looks like the system is introducing (willingly or because of CPU starvation) a delay between invalidate() and onDraw(). Can I somehow lower that delay?

测试在相对较老的硬件 - 的HTC Magic采用Android 2.1

Testing on relatively old hardware - HTC Magic with Android 2.1.

推荐答案

假如同样的问题,所以我做了我的线程:

Had same problem, so I made my thread:

经常听取当用户触碰意见,并使它屈服,然后睡了很短的时间(50毫秒)。

Constantly listen when user touched Views and made it yield and then sleep for short times (50 ms).

发布到UI线程以分钟500毫秒间隔有限公司更新(导致少得多的重画)。

Limited updates posted to UI thread with a min 500 ms interval (causing much less re-draw).

就资料的优先桶工人的工作,这个重点是更新的意见,用户当前与之交互。

Made the worker work on prioritized buckets of data, this focuses on updating the views, user is currently interacting with.

现在,整个用户界面是真懒,但无滞后的。

Now the whole UI is really lazy, but free of lag.

下面是我的工人sheduling方法看起来像(实际工作是由工艺方法完成):

Here's what my worker's sheduling method looks like (actual work is done by Process method):

 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();

                //---user busy with touchscreen ? take some rest-----
                while (mDetector.isTouching()) {
                   Thread.sleep(50);
                }

                //----do work---
                mProcessor.process(next);


                long timeNow = Calendar.getInstance().getTimeInMillis();
                if(timeNow - timeLast > 500){
                   //---its been quite a while now, update ui--
                   postUpdates();
                   timeLast = timeNow;
                }

                //----let UI thread work on updates----
                Thread.yield();   
           }

更多的调整:

More tweaking:

请过一段时间后触摸探测器放弃,当用户仍然触摸下来。这将prevent工作线程永久睡觉。

Make the touch-detector give up after some time, when user is still touching down. This will prevent worker thread permanently sleeping.

触摸检测器模块UI事件,一会儿,就下来了检测触摸。这将prevent UI线程挤破头触摸事件。

touch-detector blocks UI events, for a while, on detecting touch down. This will prevent UI thread getting overloaded with touch events.