7

Hola chicos. Estoy desarrollando un programa cliente/servidor donde el cliente es un dispositivo Android. El servidor tiene una clase de escucha que lee un objeto de la secuencia de entrada. Creé un software de cliente para otra COMPUTADORA que envía un objeto pequeño a través de una red local. Computer to Computer funciona perfectamente bien, leo el objeto e imprimo los contenidos. Sin embargo, el MISMO código portado a android (lo reescribí solo por si acaso) no funciona. Construyo un objeto (CUALQUIER objeto), que es serializable, y lo envío a través de ObjectOutputStream. Mi servidor que se ejecuta en la computadora se conecta al dispositivo, pero me da una excepción ClassNotFound, incluso si imprimo el objeto (que tiene un toString). Como dije, el mismo código que se ejecuta en otra COMPUTADORA (como un archivo .jar) funciona perfectamente bien.Android Socket + ObjectOutputStream no funciona correctamente

Aquí está la parte realmente extraña, si envío un booleano o String (desde el dispositivo) funciona .... son solo mis objetos "personalizados" que no funcionan. Supongo que esto funcionaría para cualquier objeto java "estándar".

Si encuentra un error, tenga en cuenta que el código funciona, pero solo desde otra computadora a mi computadora ... no desde el dispositivo Android a la computadora. Si todavía encuentra otro error evidente, entonces impresionante :)

PROGRAMA DE ANDROID:

package WaitDroid.Main; 

import java.io.ObjectOutputStream; 
import java.net.InetAddress; 
import java.net.Socket; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class main extends Activity { 
/** Called when the activity is first created. */ 
private Button a; 
private TextView x; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    this.a = (Button) this.findViewById(R.id.Send_Order); 
    this.x = (TextView) this.findViewById(R.id.TextView1); 
    this.a.setOnClickListener(new OnClickListener() 
    { 

     @Override 
     public void onClick(View arg0) 
     { 
      sendMenu(); 
     } 
    }); 
} 

private void sendMenu() 
{ 
    try 
    { 
     InetAddress serverAddress = InetAddress.getByName("128.153.180.109"); 
     Socket socket = new Socket(serverAddress, 4322); 
     ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 
     TestObject send = new TestObject("Hi", 32); 
     out.writeObject(send); 
     out.close(); 
     socket.close(); 
     } 
     catch(Exception e) 
     { 
     x.setText(e.getMessage()); 
     } 
    } 
} 

PRUEBA DE OBJETO:

package WaitDroid.Main; 

import java.io.Serializable; 

public class TestObject implements Serializable 
{ 
    private String name; 
    private int number; 

    public TestObject(String a, int b) 
    { 
     name = a; 
     number = b; 
    } 

    public String toString() 
    { 
     return name +" - "+ number; 
    } 
} 

SERVIDOR OYENTE:

package Main; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectInputStream.GetField; 
import java.net.ServerSocket; 
import java.net.Socket; 

import Order.Order; 

public class ServerListener extends Thread 
{ 

    public void run() { 
     try { 
      ServerSocket listen = new ServerSocket(4322); 

      while (true) { 
       Socket socket = listen.accept(); 
       String clientInetAddr = socket.getInetAddress().toString(); 
       ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 

       System.out.println("Connected to: " + clientInetAddr); 

       try 
       { 
        Object a = in.readObject(); 
        System.out.println(a); 
        //RestaurantServerRun.n.server.addOrder(a); 
       } 

       catch(IOException e) 
       { 
        System.err.println(e.getMessage()); 
       } 

       in.close(); 
       socket.close(); 
      } 
     } 
     catch (Exception e) { 
      System.err.println("Error in run()"); 
      e.printStackTrace(); 
     } 

    } 
} 

¡Gracias!

Respuesta

4

Sospecho que el formato de serialización de Android puede no ser compatible con el formato de Java VM. ¿Puedes intentar convertir tus objetos a XML u otro formato de texto?

+0

Sí, tienes razón. Funciona solo para tipos primitivos ... eso explicaría por qué funciona con String, etc. Esto es realmente idiota. ¿Hay alguna manera de convertir fácilmente un objeto (con tipos primitivos y una lista de arrays) a un formato que pueda enviar? – somanys21

+4

** He encontrado el problema ** Es extraño, pero el proceso de serialización mira en qué ** Paquete ** está tu clase original. Simplemente me golpeó, me estaba dando una ClassNotFoundException. Aquí está el por qué, supongamos que mi proyecto de servidor principal tiene clas XXXX.java en el paquete "Extra". Mi cliente de prueba lo tiene en un paquete llamado "Principal". Es la misma clase XXXX.java, solo un paquete diferente. El proceso de serialización realmente tiene en cuenta la ubicación del paquete y luego lo envía a través. Puedo confirmar esto porque hice mi aplicación de Android idéntica a mi servidor en términos de administración de paquetes, ¡y funcionó! – somanys21

+1

Sí, el nombre del paquete está incluido en el nombre completo de la clase. El mismo nombre de clase puede existir en diferentes paquetes. –

Cuestiones relacionadas