2012-11-06 52 views
10

我有一個手寫識別應用程序 - 用戶用手指畫,應用程序識別字符。識別引擎在具有最小可能優先級的工作線程中運行 - Thread.MIN_PRIORITY。這是純粹的CPU /內存算法,無論是什麼I/O。不過,當線程正在工作時,UI變得相當不連貫。手指筆畫顯着延遲。我也注意到觸摸事件迷路了。當工作線程工作時,UI變得不穩定

這不正是線程應該避免的嗎?爲什麼UI線程餓死CPU?如何說服系統把工作線程當作低優先級的後臺線程呢?

它看起來像系統引入(自願或因CPU飢餓)invalidate()onDraw()之間的延遲。我能以某種方式降低延遲嗎?

測試相對較舊的硬件 - HTC Magic與Android 2.1。

回答

4

曾有同樣的問題,所以我做了我的線程:處理工作的一大塊後

  1. Thread.yield()。

  2. 發佈到UI線程的有限更新以最少500毫秒的時間間隔(導致重新繪製較少)。

  3. 使工作人員在優先級數據桶上工作,重點在於更新視圖,用戶當前正在與之交互。

現在整個用戶界面真的很懶,但沒有滯後。

下面是我的工作人員的調度方法看起來像(實際工作是由工藝方法來完成):

//--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(); 
} 
+0

定期收益效果最好。 –

+0

嗨S.D.,你能修正這個代碼塊中的縮進嗎?另外,你可以嘗試添加一個[語言標籤](http://meta.stackexchange.com/a/75019/321006)來防止語法高亮者認爲yield是關鍵字嗎?我認爲自動熒光筆假定這是c#代碼。 – jrh

2

嘗試在字符識別方法添加Thread.sleep(1)在主循環

@Override 
public void run() { 
    while (!recognited) { 

    //do some script 

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

這種睡眠可以讓虛擬機有點早恢復其他線程,往往

+0

它的拼寫是公認的,順便說一句。一個Thread.yield也可以幫助,但我從未注意到它有任何實際效果。 – njzk2

+1

看起來好像收益更好。仍然是+1。 –

1

這可能是您的GUI線程floaded與觸摸事件,如果是的話,那麼解決方案是在UI線程中引入幾個ms等待並提升您的工作線程。更多關於此這裏:

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

也,也許你正在處理的數據過多,就像如果沒有運動實際上happend,或運動不顯著不夠。

+0

討論中的相關建議 - 將觸摸處理移至「dispatchTouchEvent」。 –