Android Socket + ObjectOutputStream не работи правилно

Разработвам програма клиент/сървър, където клиентът е устройство с Android.

Сървърът има клас слушател, който чете обект от входния поток. Създадох клиентски софтуер за друг КОМПЮТЪР, който изпраща малък обект през локална мрежа. Компютър към компютър работи перфектно, прочетох обекта и отпечатах съдържанието. Обаче СЪЩИЯТ код, пренесен към android (пренаписах го за всеки случай) не работи. Създавам обект (ВСЕКИ обект), който може да се сериализира, и го изпращам чрез ObjectOutputStream. Моят сървър, работещ на компютъра, се свързва с устройството, но ми дава изключение ClassNotFound, дори ако отпечатам обекта (който има toString). Както казах, същият код, работещ на друг КОМПЮТЪР (като .jar файл), работи перфектно.

Ето наистина странната част, ако изпратя булева стойност или низ (от устройството), тя работи... това са само моите персонализирани обекти, които не работят. Предполагам, че това ще работи за всеки стандартен Java обект.

Ако откриете грешка, моля, имайте предвид, че кодът работи, но само от друг компютър към моя компютър...не от устройството с Android към компютъра. Ако все пак намерите друга явна грешка, тогава страхотно :)

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

ТЕСТОВ ОБЕКТ:

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

ПРИСЛУШВАТЕЛ НА СЪРВЪР:

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

Благодаря!!


person somanys21    schedule 19.10.2010    source източник


Отговори (1)


Подозирам, че форматът за сериализиране на Android може да не е съвместим с формата на Java VM. Можете ли да опитате да конвертирате вашите обекти в XML или някакъв друг текстов формат?

person Purush Rudrakshala    schedule 19.10.2010
comment
Да, прав си. Работи само за примитивни типове...това би обяснило защо работи с String и т.н...това е наистина идиотско. Има ли някакъв начин лесно да преобразувам обект (с примитивни типове и arraylist) във формат, който мога да изпратя? - person somanys21; 19.10.2010
comment
Открих проблема Странно е, но процесът на сериализация разглежда в какъв пакет е вашият оригинален клас. Току-що ме удари, дава ми ClassNotFoundException. Ето защо, да предположим, че проектът ми за основен сървър има клас XXXX.java в пакет Extra. Моят тестов клиент го има в пакет, наречен Main. Това е същият клас XXXX.java, просто различен пакет. Процесът на сериализиране всъщност взема предвид местоположението на пакета и след това го изпраща. Мога да потвърдя това, защото направих моето приложение за Android идентично със сървъра ми по отношение на управлението на пакети и то проработи!! - person somanys21; 20.10.2010
comment
Да, името на пакета е включено в пълното име на класа. Едно и също име на клас може да съществува в различни пакети. - person Purush Rudrakshala; 21.10.2010
comment
Невъзможно е да разберете защо сте маркирали този отговор като правилен. Не е. Вашият действителен проблем беше промяната на името на пакета, което щеше да ви ухапе както в Java, така и в Android. - person user207421; 02.11.2020