2

screenCapture を使用してサーバー側から取得した画像を表示しようとしていますが、クライアント側 (Android エミュレーター) では、例外「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);

}

}

4

2 に答える 2

0

画像を表示するために ImageView を使用している場合、サーバーが送信しているままの巨大な画像はおそらく必要ありません。

おそらくいくつかのことができます:

  1. Aquery のようなライブラリを使用し、その ImageLoading をビューに関連付けます
  2. 面倒な作業は自分で行ってください - Android ドキュメントを参照してください - ビットマップを効率的に表示する
于 2013-05-12T11:06:12.533 に答える
0

サーバーは画像を継続的に送信し、クライアントは描画を開始する前にすべてのデータ (無限の量) を受信しようとします。

たとえば、クライアントが新しいイメージを要求し、サーバーが単一のイメージを配信することを意味するポーリング アプローチの方が適しています。

まだいくつかの問題が残っています: サーバーは画像データの長さを送信する (または各画像の後に接続を閉じる) 必要があります。これにより、クライアントはいつデータの待機を停止して処理を開始する必要があるかを認識し、onDraw() は invalidate() を呼び出すべきではありません。さらに onDraw() を呼び出す回数が多すぎる、またはめったにありません (まったく機能する場合)。

于 2013-05-12T10:55:21.163 に答える