2013-05-12 81 views
2

我想顯示圖像,我從服務器端使用screenCapture但在客戶端(Android模擬器)不顯示任何圖像,運行一段時間後通過異常「OutOfMemoryException」 。所以我需要一些幫助。這是代碼。OutOfMemoryException當試圖連續顯示圖像

服務器

public class Server 
{ 
    private Connection con; 
    private ScreenCapture sp; 
    private Socket soc; 
    private DataOutputStream out; 
    private DataInputStream in; 

public Server() throws IOException, AWTException 
{ 
    con = new Connection(); 
    sp = new ScreenCapture(); 
} 

public void init() throws IOException, AWTException 

{ 
    con.setPort(3838); 
    ServerSocket serversocket = new ServerSocket(3838); 
    soc = serversocket.accept(); 
    System.out.println("Accepted"); 
    out = new DataOutputStream(soc.getOutputStream()); 
    in = new DataInputStream(soc.getInputStream()); 
    while(true) 
    { 
    sp.CreateScreenCapture(); 
    out.write(sp.getScreenCapture()); 
    } 

} 

public void closeConnection() throws IOException 
{ 
    soc.close(); 
} 

public static void main(String[] arg) 
{ 

     Server server = null; 

    while(true) 
    { 
     try 
     { 
      server = new Server(); 
      server.init(); 

     } 
     catch (IOException ex) 
     { 
      Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); 

     } 
     catch (AWTException ex) 
     { 
      Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     finally 
     { 
      try 
      { 
       server.closeConnection(); 
      } 
      catch (IOException ex) 
      { 
       Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

    } 


} 

}

客戶

public class UpdateScreen extends View 
{ 

private DataInputStream input; 
private DataOutputStream output; 
private Socket soc; 
private Bitmap image; 



public UpdateScreen(Context context) throws UnknownHostException, IOException 
    { 
    super(context); 
    // TODO Auto-generated constructor stub 
    this.setFocusable(true); 
    this.setFocusableInTouchMode(true); 
    init(); 
} 

public void init() throws UnknownHostException, IOException 
{ 

    soc = new Socket(InetAddress.getByName("10.0.2.2"), 3838); 
    input = new DataInputStream(soc.getInputStream()); 
    while(true) 
    { 
    byte[] img = this.getByteArrayFromStream(); 
    image = BitmapFactory.decodeByteArray(img, 0, img.length); 

    } 

} 


protected void onSizeChanged(int w, int h, int oldw, int oldh) 
    { 
    // TODO Auto-generated method stub 

    image = Bitmap.createScaledBitmap(image, w, h, false); 

    } 


public byte[] getByteArrayFromStream() throws IOException 
{ 
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
    int nread; 
    byte[] data = new byte[1042]; 
    while((nread = input.read(data, 0, data.length)) != -1) 
    { 
     buffer.write(data, 0, nread);  
    } 

    return buffer.toByteArray(); 
} 


@Override 
protected void onDraw(Canvas canvas) 
{ 
    // TODO Auto-generated method stub 
    invalidate(); 
    super.onDraw(canvas); 
    canvas.drawBitmap(image, 0, 0, null); 

} 

}

回答

0

服務器連續發送的圖像和客戶端嘗試在它之前接收到所有的數據(一個無限量)甚至會開始畫畫。

更好的是例如一種輪詢方式,這意味着客戶端請求一個新的鏡像,服務器提供一個鏡像。

還有一些問題:服務器必須發送圖像數據的長度(或每個圖像後關閉連接),以便客戶端知道應該何時停止等待數據並開始處理,並且onDraw()不應該調用invalidate() ),因爲這可能導致對onDraw()的調用過於頻繁或很少(如果它可以工作的話)。

0

如果您使用ImageView來顯示圖像,您可能不需要服務器發送的巨大圖像。

你也許可以做兩件事情:

  1. 使用像Aquery庫及其ImageLoading到您的視圖
  2. 聯想自己做艱苦的工作 - 是指Android的文檔 - 顯示位圖有效
+0

我沒有使用圖像視圖我直接在畫布上使用 – umerk44 2013-05-12 11:57:54

+0

如果服務器在你的控制下,那麼你可以在那裏縮放它,如果沒有,其他東西/指針(1)縮放圖像,而其仍然在InputStream lev (2)ARGB_XXXX的位圖非常繁重(3)如果你無法做到這一點,並希望迅速關閉它,請嘗試使用webview和相冊插件添加效果可能會更簡單(4)如何改變UI模式有點像先顯示用戶較小的版本,然後是較大的版本(5)如果全部失敗並且您仍然需要它... – 2013-05-12 14:26:15

+0

..嘗試探索渲染腳本的計算,沒有太多的文檔,它可以變得棘手(6)我希望你已經設置你的清單使用LARGE_HEAP – 2013-05-12 14:29:47