2013-08-26 29 views
3

我正在實施自定義相機,並且我在onPreviewFrame()中使用實時fx。主效應(fx1)是可運行的,並且似乎可以,需要時丟幀。
第二個簡單的fx(fx2)在fx1關閉時運行。
當fx2在主線程上運行時沒問題(它運行在2毫秒內),但有時我看到一個ANR,所以我決定將它移動到第二個可運行狀態,但現在導致應用程序凍結。在將代碼移入可運行代碼後,Android應用程序凍結而無ANR

class FX2Runnable implements Runnable { 
    private byte[] data; 
    FX2Runnable(byte[] _data) { 
     data = _data; 
    } 

    public void run() { 
     hview.FX2(data); 

     hview.post(new Runnable() { 
      public void run() { 
       hview.postInvalidate(); 
       //.invalidate(); caused ANR!! 
      } 
     }); 
     FLAG_FX2_PROCESSING = false; 
    } 
} 

這是我如何稱呼它

private PreviewCallback previewCallback=new PreviewCallback() { 
    public void onPreviewFrame(byte[] data, Camera cam) { 
     if(FX==1) { 
      // FX1 
      if(FLAG_FX1_PROCESSING) { 
       //skip 
      } else { 
       FLAG_FX1_PROCESSING = true; 
       FX1Thread = new Thread(new FX1Runnable()); 
       FX1Thread.start(); 
      } 
     } else { 
      // FX2 
      if(FLAG_FX2_PROCESSING) { 
       //skip 
      } else { 
       FLAG_FX2_PROCESSING = true; 
       FX2Thread = new Thread(new FX2Runnable(data)); 
       FX2Thread.start(); 
      } 
      /* this was the old code and was working fine 
       but i needed to solve some spare ANR 
      //hview.FX2(data); 
      //hview.invalidate(); 
      */ 
     } 
    } 
} 

我在做什麼錯!?

順便說一下,它似乎我不能凍結模擬器上的應用程序,但只能在我的設備上。

編輯

與runOnUiThread(Runnable接口),而不是hview.post(Runnable接口)嘗試,它似乎工作,但我不得不等待幾分鐘,看看再次冷凍的應用程序!它發生在後面,但它又發生了!

下面是一個logcat的

08-26 17:32:13.398: I/ActivityManager(250): Displayed it.jcsoft.abbracadabbra/.EnhancedCameraPreviewActivity: +3s576ms 
08-26 17:32:13.414: W/IInputConnectionWrapper(459): showStatusIcon on inactive InputConnection 
08-26 17:32:13.441: I/GPS(9149): new network location: Location[mProvider=network,mTime=1377531132668,mLatitude=44.1459721,mLongitude=12.4545174,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=43.887,mExtras=Bundle[mParcelledData.dataSize=212]] 
08-26 17:32:15.441: D/dalvikvm(250): WAIT_FOR_CONCURRENT_GC blocked 0ms 
08-26 17:32:15.867: D/dalvikvm(250): GC_EXPLICIT freed 1300K, 23% free 16030K/20615K, paused 3ms+41ms, total 428ms 
08-26 17:32:37.707: D/dalvikvm(250): GC_CONCURRENT freed 1878K, 22% free 16105K/20615K, paused 4ms+110ms, total 888ms 
08-26 17:32:37.855: D/dalvikvm(9149): null clazz in OP_INSTANCE_OF, single-stepping 
08-26 17:32:49.375: D/dalvikvm(834): GC_CONCURRENT freed 512K, 9% free 9179K/9991K, paused 336ms+218ms, total 4454ms 
08-26 17:32:49.375: D/dalvikvm(834): WAIT_FOR_CONCURRENT_GC blocked 1740ms 
08-26 17:32:58.605: D/dalvikvm(250): GC_CONCURRENT freed 1934K, 22% free 16098K/20615K, paused 5ms+32ms, total 284ms 
08-26 17:33:00.070: D/SizeAdaptiveLayout(335): [email protected] view [email protected] measured out of bounds at 95px clamped to 96px 
08-26 17:33:00.093: D/SizeAdaptiveLayout(335): [email protected] view [email protected] measured out of bounds at 95px clamped to 96px 
08-26 17:33:10.257: D/dalvikvm(9149): GC_CONCURRENT freed 455K, 4% free 14709K/15303K, paused 3ms+4ms, total 78ms 
08-26 17:33:20.082: D/dalvikvm(250): GC_CONCURRENT freed 1933K, 22% free 16091K/20615K, paused 5ms+30ms, total 282ms 
08-26 17:33:23.379: I/InputDispatcher(250): Application is not responding: Window{425f23b0 it.jcsoft.abbracadabbra/it.jcsoft.abbracadabbra.EnhancedCameraPreviewActivity paused=false}. It has been 5002.6ms since event, 5002.5ms since wait started. Reason: Waiting because the touched window has not finished processing the input events that were previously delivered to it. 
08-26 17:33:23.379: I/WindowManager(250): Input event dispatching timed out sending to it.jcsoft.abbracadabbra/it.jcsoft.abbracadabbra.EnhancedCameraPreviewActivity 
08-26 17:33:28.437: I/InputDispatcher(250): Dropped event because it is stale. 

請幫助!

+0

而不是使用'hview.post ...',請嘗試使用'runOnUiThread(新的Runnable()...' –

回答

0

你應該真的使用Handler來處理這種操作。

讓runnable發佈一條消息,一旦完成它的操作,然後執行hview.postInvalidate();方法調用。

有大量的指南如何做到這一點。

一些環節:包括 http://developer.android.com/reference/android/os/Handler.html

http://androidexample.com/Thread_With_Handlers_-_Android_Example/index.php?view=article_discription&aid=58&aaid=83

http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

+0

謝謝!當然我不記得我是如何解決這個問題的,無論如何,我認爲處理程序是正確的方式。可能我做了類似的: Thread fx2 = new Thread(new Runnable(){ public void run(){ hview.fx2(data); updateUIHandler.post(new Runnable(){ public void run(){hview.invalidate();} }); } }); fx2.start(); 這是正確的嗎? –

+0

從看評論代碼看起來相當不錯。除非你不必在處理程序上做一個.post。 –

+0

那麼,如何使用處理程序!?我會使用updateUIHandler來更新UIthread中的hview,怎麼做? –

1

而不是使用hview.post...的,請嘗試使用runOnUiThread(new Runnable()...

在Android文檔下面的話在那裏。

在UI線程上運行指定的操作。如果當前線程是UI線程,那麼該動作立即執行。如果當前線程不是UI線程,則該操作將被髮布到UI線程的事件隊列中。

因此,無論何時您想要更新您的視圖從您的主題,您需要使用runOnUiThread

所有視圖都在UIThread上呈現。如果你不這樣做,它會崩潰,因爲後臺線程不同於UIThread。

+0

我正在使用View.Post,「導致Runnable被添加到消息隊列中,runnable將在用戶界面線程上運行」。有什麼區別? –

+0

@ j.c UI表示用戶界面。您正在查看的屏幕正在UI線程上運行。相機也使用畫布爲我們服務。所以它也是一種UI視圖。你不能在後臺修改它。 UI線程做更新小部件,視圖,事件處理等任務。 –

+0

@ j.c,Upvote和接受將會非常高興。這將使未來的Google員工幫助找到有效的答案。 :) –

相關問題