2014-03-27 82 views
0

這裏還有一個問題要問你:)安卓:在循環解碼JPG格式:隨機凍結

基本上我做了一個實時流媒體服務,發送多個JPEG文件到我的Android應用程序,讓我們從他接受他們儘快對其進行解碼。

// dIn is DataInputStream 
// videoFeed is an ImageView 
// bitmap is Bitmap 
// hand is an Handler of the main thread 

//CODE EXECUTED IN ANOTHER THERAD 
byte[] inBuff = new byte[8]; 
byte[] imgBuff; 
String inMsg; 
while(socket.isConnected()) { 
    dIn.readFully(inBuff); 
    inMsg = new String(inBuff, "ASCII").trim(); 
    int size = Integer.parseInt(inMsg); 
    imgBuff = new byte[size]; 
    dIn.readFully(imgBuff); 
    out.write("SEND-NEXT-JPEG".getBytes("ASCII")); 
    bitmap = BitmapFactory.decodeByteArray(imgBuff, 0, size); 
    hand.post(setImage); 
    } 
} 

private Runnable setImage = new Runnable() { 
    @Override 
    public void run() { 
     videoFeed.setImageBitmap(bitmap); 
    } 
}; 

的問題是,經過大約10或20的JPEG文件實時解碼完美,應用程序凍結了400毫秒左右,然後繼續在另一個之前凍結其他10/20 JPEG文件解碼...

我知道發送多個jpeg不是流式視頻的好方法,但我只能更改客戶端(android應用程序),而不是服務器。

您對獲得流暢視頻並避免死機有任何想法嗎?謝謝!

+1

我的猜測是你因垃圾收集而被凍結。檢查LogCat以查看哪些消息出現在那裏,並使用Traceview確定您在哪裏花費時間。 – CommonsWare

+0

@CommonsWare感謝您的回覆,我無法看到任何GCC登錄logcat ... – Suxsem

+0

@CommonsWare無論如何,我認爲你是對的,你知道一種方式來重新使用相同的資源,而無需爲每個decodeByteArray調用分配其他空間嗎? – Suxsem

回答

0

現在,您正在使用decodeByteArray()的三參數版本。相反,切換到四參數版本,傳入BitmapFactory.Options作爲最後一個值。在那裏,set inBitmap成爲可以重複使用的Bitmap對象。

這需要您維護一個小的Bitmap對象池。它可以像兩個Bitmap實例一樣簡單:當前正在顯示的實例和正在爲視頻的下一個「幀」準備的實例。

值得注意的是,對於API Level 18及以下版本,Bitmap需要具有相同的分辨率(以像素爲單位的高度和寬度)。在你的情況下,這可能不是問題,因爲我可以想象每個位圖都具有相同的分辨率。

+0

非常感謝您的回答,我試過了,它的工作!無論如何,一段時間後resoultion實際上會改變......如何處理這種情況? – Suxsem

+0

@ user2104749:您需要爲每個分辨率的位圖分別創建對象池。 – CommonsWare