2014-10-16 55 views
0

我想從android手機的桌面接收圖像流。當我在我的線程中放入decodeStream()方法,然後將decodestream()放入runOnuiThread()以顯示在imageView中時,它需要7秒多的時間。但是,當我嘗試直接從資產讀取圖像並轉換爲輸入流,然後decodeStream()時,它可能需要500ms,我不知道它爲什麼會發生。圖像是100K。爲什麼DecodeStream(stream)在線程中比在主線程中花費更長的時間?

 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(); 
     } 
    } 

} 
+0

現在我正在嘗試使轉換不會延遲,爲什麼延遲只發生在線程中。 – user3799770 2014-10-16 20:53:50

回答

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中竊取數據。

+0

另外它看起來像是從遠程服務器下載圖像,而資產文件夾正好在設備上。無論如何,這將需要更長的時間。 – DeeV 2014-10-16 20:55:00

+0

實際上,在刪除read()之後,它將不起作用。 – user3799770 2014-10-16 21:01:20

+0

@ user3799770一次發現一個錯誤。 – 2014-10-16 21:02:03

0

我的猜測是,服務器端不能正常發送文件已達到的結尾。我以前遇到過這種情況,因爲Web服務器實現可能不會告訴您它發送的文件的長度。如果它沒有設置內容長度,那麼輸入流會一直試圖讀取。我的猜測是,它需要幾分鐘,因爲這是默認套接字超時值。

因此,來自套接字的輸入流會盡可能多地讀取數據並持續等待更多數據。等待幾分鐘後(儘管默認超時時間通常是5分鐘),套接字關閉,您將獲得圖像。

我不完全確定內容長度會有幫助,另一種選擇可能是服務器在所有數據發送完畢後關閉連接。

很明顯,如果您嘗試流式傳輸新圖像,則需要做一些與您不同的事情。也許讓你的服務器發送一個讀者解釋的文件頭。此標頭可能包含正在發送的數據的長度,然後您寫入的客戶端在達到此長度後停止讀取。在這種情況下,您需要將圖像數據讀入緩衝區,然後讓BitmapFactory讀取緩衝區而不是流。

另一種方法是讓服務器在爲每個映像發送數據後關閉連接,然後客戶端重新連接以獲取下一個。

底線,並不是所有的InputStreams都是相等的,並且SocketInputStream不知道何時關閉而沒有內容長度或套接字被關閉。

相關問題