2017-01-19 5 views
-2

У меня проблема с преобразованием массива байтов в изображение, но в ImageView.Невозможно преобразовать массив байтов в imageView, который был отправлен сокетом

После того, как я нажал, приложение закрыто, создавая ошибку, вы увидите его там. , поэтому мне нужна помощь.

Я пытаюсь отправить изображение с сервера java на клиент android.
Я проверил, что полученный массив байтов полон байтов, но я действительно не могу его преобразовать.

Вот мой код:

Android-клиент для Android клиент

package com.example.metalheadi.convert2; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 

import java.io.ByteArrayOutputStream; 
import java.io.DataInputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.net.Socket; 

public class MainActivity extends AppCompatActivity { 
    EditText IP, Port, Msg; 
    Button Send; 
    ImageView image; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Send = (Button) findViewById(R.id.send); 
     IP = (EditText) findViewById(R.id.ip_e); 
     Port = (EditText) findViewById(R.id.port_e); 
     image = (ImageView) findViewById(R.id.imageView1); 
//  Msg = (EditText) findViewById(R.id.msg_e); 
     Send.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Thread thread = new Thread(new Runnable() { 
        @Override 
        public void run() { 
         try { 
          Socket socket = new Socket(IP.getText().toString(), Integer.parseInt(Port.getText().toString())); 

          DataInputStream in= new DataInputStream(socket.getInputStream()) ; 
          ByteArrayOutputStream out = new ByteArrayOutputStream(); 
          byte buffer[] = new byte[1024]; 
          try { 
           int count; 
           while ((count = in.read(buffer)) > 0) 
           { 
            out.write(buffer, 0, count); 
           } 
          } catch (IOException e1) { 
           e1.printStackTrace(); 
          } 
          byte[]result= out.toByteArray(); 
          for (int g=0;g<result.length;g++){ 
           System.out.println(g); 
          } 
          System.out.println("here "); 
          Bitmap bmp = BitmapFactory.decodeByteArray(result, 0, result.length); 
          Drawable drawable = new BitmapDrawable(getResources(), bmp); 
          image.setImageDrawable(drawable); 

//       image.setImageBitmap(Bitmap.createScaledBitmap(bmp, image.getWidth(), image.getHeight(), false)); 

//       DataInputStream dIn=new DataInputStream(socket.getInputStream()); 
//       int length = dIn.readInt();     // read length of incoming message 
//       if(length>0) { 
//        byte[] message = new byte[length]; 
//        dIn.readFully(message, 0, message.length); // read the message 
//       } 
////       Toast.makeText(MainActivity.this,"heeeeere",Toast.LENGTH_LONG).show(); 
//       System.out.println("here "); 


///////////////////////////////////////////////////////// 
          socket.close(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
        } 
       }); 
       thread.start(); 
      } 
     }); 
    } 
} 

XML

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.metalheadi.convert2.MainActivity"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="IP" 
     android:id="@+id/ip" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="PORT" 
     android:id="@+id/port" 
     android:layout_below="@+id/ip_e" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" /> 

    <EditText 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/ip_e" 
     android:layout_alignParentTop="true" 
     android:layout_toRightOf="@+id/ip" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentEnd="true" /> 

    <EditText 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/port_e" 
     android:layout_below="@+id/port" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignRight="@+id/ip_e" 
     android:layout_alignEnd="@+id/ip_e" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="SEND" 
     android:id="@+id/send" 
     android:layout_below="@+id/port_e" 
     android:layout_alignRight="@+id/port_e" 
     android:layout_alignEnd="@+id/port_e" /> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/imageView1" 

     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignParentBottom="true" 
     android:layout_below="@+id/send" 
     android:layout_alignRight="@+id/send" 
     android:layout_alignEnd="@+id/send" 
     android:nestedScrollingEnabled="false" /> 
</RelativeLayout> 

сервера JAVA

package convert; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 
import java.net.ServerSocket; 
import java.net.Socket; 

import java.util.Iterator; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.imageio.ImageReadParam; 
import javax.imageio.ImageReader; 
import javax.imageio.stream.ImageInputStream; 
public class Convert { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws FileNotFoundException, IOException { 
     /* 
     * 1. How to convert an image file to byte array? 
     */ 
// RandomAccessFile file1 = new RandomAccessFile("D:\\", "rw"); 
Thread t= new Thread(new Runnable() { 
    @Override 
    public void run() { 
//  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 
try{ 
ServerSocket ss=new ServerSocket(400); 
    while(true){ 
     File file = new File("D:\\PIC\\all pic\\han.jpg"); 

     FileInputStream fis = new FileInputStream(file); 
     //create FileInputStream which obtains input bytes from a file in a file system 
     //FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader. 

     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     byte[] buf = new byte[1024]; 
     try { 
      for (int readNum; (readNum = fis.read(buf)) != -1;) { 
       //Writes to this byte array output stream 
       bos.write(buf, 0, readNum); 
       // System.out.println("read " + readNum + " bytes,"); 
      } 
     } catch (IOException ex) { 
      Logger.getLogger(Convert.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     byte[] bytes = bos.toByteArray(); 
      Socket s=ss.accept(); 
      System.out.println("Accept........"); 
      DataOutputStream dOut = new DataOutputStream(s.getOutputStream()); 
      dOut.writeInt(bytes.length); // write length of the message 
      dOut.write(bytes);   // write the message    
      dOut.close(); 
      s.close(); 
} 
} 
catch (IOException ex) { 
        Logger.getLogger(Convert.class.getName()).log(Level.SEVERE, null, ex); 
       } 

    } 
}); 
    t.start(); 
} 

} 

ошибка Android LogCat

1-19 01:43:43.964 24869-25529/com.example.metalheadi.convert2 E/AndroidRuntime: FATAL EXCEPTION: Thread-11797 

android.view.ViewRootImpl $ CalledFromWrongThreadException: только исходный поток, который создал иерархию вида может коснуться его точки зрения. на android.view.ViewRootImpl.checkThread (ViewRootImpl.java:5498) в android.view.ViewRootImpl.requestLayout (ViewRootImpl.java:1062) в android.view.View.requestLayout (View.java:16375) на android.view.View.requestLayout (View.java:16375) на android.view.View.requestLayout (View.java:16375) на android.view.View.requestLayout (View.java:16375) на android. view.requestLayout (View.java:16375) на android.view.View.requestLayout (View.java:16375) на android.widget.RelativeLayout.requestLayout (RelativeLayout.java:318) на android.view. View.requestLayout (View.java:16375) на android.widget.ImageView.setImageDrawable (ImageView.java:418) на com.example.metalheadi.convert2.MainActivity $ 1 $ 1.Run (MainActivity.java:66) в java.lang.Thread.run (Thread.java:856)

ответ

0

Исключение показывает, что setImageDrawable не работает на поток пользовательского интерфейса. В Android все операции пользовательского интерфейса должны выполняться в основном потоке. Вы можете обернуть вызов в поле ниже:

runOnUiThread(new Runnable() { 
public void run() { 
    // Update UI elements 
}}); 
0

Поскольку вы затягивающие новый поток для чтения из сокета, image.setImageDrawable(drawable); должен вызываться из Ui нити.

Вы можете заменить его:

runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         image.setImageDrawable(drawable); 
        } 
       }); 

Однако с помощью AsyncTask будет лучшим решением вместо остовной своего собственного потока, как это имеет более удобные методы обратного вызова для переключения между Ui и фоновыми потоками.

0

Вы пишете размер изображения перед изображением, но вы его не читаете: вместо этого вы обрабатываете слово длины как часть изображения.

+0

Вы принимаете поток вывода bytearray ?? я прошу прощения, пожалуйста, я могу попросить более конкретно? или что я должен искать? я прошу прощения . i am beginner –

+0

@MohamedHani Я говорю о 'dOut.writeInt (bytes.length);' на сервере, для которого должна быть соответствующая 'int length = dIn.readInt();' на клиенте, или удалить вызов 'writeInt()', поскольку он вам не нужен, потому что вы все равно закрываете соединение после отправки изображения. У вас есть это в коде, который был прокомментирован. – EJP