为什么使用DecodeStream(stream)在一个线程中花费的时间比在主线程中花费的时间长?

时间:2014-10-16 20:47:57

标签: android multithreading sockets image-processing

我正在尝试从Android手机中的桌面接收图像流。当我在我的线程中放入decodeStream()方法,然后将decodestream()放入runOnuiThread()以在imageView中显示,它需要超过7秒。但是当我尝试直接从资产中读取图像,并转换为输入流,然后解码流()时,它可能需要500毫秒,我不知道它为什么会发生。图像是100K。

        Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            SocketConnect = new socketConnect();
            SocketConnect.connectsocket("134.129.125.126", 8080);
            while (true) {
                data = new byte[2048 * 2048];

                try {
                    read = SocketConnect.getInputStream().read(data, 0,
                            data.length);
                    input = SocketConnect.getInputStream();
                    System.out.println("getInputStream()");
                    bitmap = BitmapFactory.decodeStream(input);
                    System.out.println("decodestream()");

                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                    System.out.println(e);
                }
                runOnUiThread(new Runnable() {
                    public void run() {

                        image.setImageBitmap(bitmap);
                        System.out.println("setImage at less than 500");

                    }
                });
            }
        }
    });
    thread.start();

客户端应该发送图像非常5秒。 如果我尝试从资产中读取相同的图像,图像会立即显示。

try {
     inputasset=getAssets().open("good1.jpg");
     Bitmap bit = BitmapFactory.decodeStream(inputasset);    
     image.setImageBitmap(bit);
     } catch (IOException e) {
      TODO Auto-generated catch block
     e.printStackTrace();
     }

socketConnect类

    public class socketConnect {
    private Socket clientSocket;
    private InputStream input;
    private Bitmap bMap;

    public InputStream getInputStream() {
        return input;
    }

    public void connectsocket(String ipString, int port)

    {
        System.out.println("starts");

        try {
            // clientSocket = new Socket("134.129.125.172",8080);
            System.out.println("starts");
            clientSocket = new Socket(ipString, port);

            System.out.println("AsyncTask: Connect to 134.129.125.126");
            input = clientSocket.getInputStream();

            System.out.println("AsyncTask: get the inputStream");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

2 个答案:

答案 0 :(得分:3)

                read = SocketConnect.getInputStream().read(data, 0,
                        data.length);
                input = SocketConnect.getInputStream();
                System.out.println("getInputStream()");
                bitmap = BitmapFactory.decodeStream(input);
                System.out.println("decodestream()");

您从输入流中读取数据,然后要求BitmapFactory从输入流中读取数据。但你已经读过了!删除对read的调用 - 您正在窃取BitmapFactory中的数据。

答案 1 :(得分:0)

我的猜测是服务器端没有正确发出信号已经到达文件末尾的信号。我之前遇到过此问题,因为Web服务器实现可能无法告诉您发送文件的长度。如果它没有设置内容长度,则输入流将继续尝试永久读取。我的猜测是需要几分钟,因为这是默认的套接字超时值。

因此,来自套接字的输入流尽可能多地读取并继续等待更多数据。等待几分钟后(虽然通常是5分钟是默认超时),套接字关闭然后你就会得到你的图像。

我不完全确定内容长度会有所帮助,另一个选择可能是服务器在发送所有数据后关闭连接。

显然,如果您尝试传输新图像,则需要做一些与您不同的事情。也许您的服务器发送读者解释的文件头。此标头可能包括正在发送的数据的长度,然后您写入的客户端在达到此长度后停止读取。在这种情况下,您需要将图像数据读入缓冲区,然后让BitmapFactory读取缓冲区而不是流。

另一种方法是让服务器在为每个映像发送数据后关闭连接,然后客户端将重新连接以获取下一个映像。

底线,并非所有InputStream都是相同的,并且SocketInputStream不知道何时关闭而没有内容长度或套接字被关闭。