Android Socket + ObjectOutputStream 无法正常工作

Posted

技术标签:

【中文标题】Android Socket + ObjectOutputStream 无法正常工作【英文标题】:Android Socket + ObjectOutputStream not working correctly 【发布时间】:2011-04-27 06:07:04 【问题描述】:

我正在开发一个客户端是安卓设备的客户端/服务器程序。

服务器有一个从输入流中读取对象的监听器类。我为另一台计算机创建了一个客户端软件,该软件通过本地网络发送一个小对象。 计算机到计算机工作得非常好,我阅读了对象并打印了内容。但是,移植到 androidSAME 代码(我重写它以防万一)不起作用。我构造了一个可序列化的对象(ANY 对象),并通过 ObjectOutputStream 发送它。我在计算机上运行的服务器确实连接到设备,但它给了我一个 ClassNotFound 异常,即使我正在打印对象(它有一个 toString)。正如我所说,在另一台计算机上运行的相同代码(作为 .jar 文件)运行良好。

这是真正奇怪的部分,如果我发送一个布尔值或字符串(从设备)它可以工作....它只是我的“自定义”对象不。我认为这适用于任何“标准”java 对象。

如果您确实发现错误,请记住该代码确实有效,但只能从另一台计算机到我的计算机……而不是从 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();
        
        
    

谢谢!!

【问题讨论】:

【参考方案1】:

我怀疑 Android 的序列化格式可能与 Java VM 的格式不兼容。您可以尝试将您的对象转换为 XML 或其他文本格式吗?

【讨论】:

是的,你是对的。它仅适用于原始类型......这可以解释为什么它适用于 String 等......这真的很愚蠢。有什么方法可以轻松地将对象(具有原始类型和数组列表)转换为我可以发送的格式? 我找到了问题 很奇怪,但是序列化过程看的是你原来的类在什么Package。这让我很受打击,它给了我一个 ClassNotFoundException。这就是为什么,假设我的主服务器项目在包“Extra”中有类 XXXX.java。我的测试客户端将它放在一个名为“Main”的包中。它是同一个 XXXX.java 类,只是一个不同的包。序列化过程实际上考虑了包的位置,然后将其发送过去。我可以确认这一点,因为我在包管理方面使我的 android 应用程序与我的服务器相同,并且它有效! 是的,包名包含在完整的类名中。同一个类名可以存在于不同的包中。 无法理解您为什么将此答案标记为正确。它不是。您的实际问题是包名称的更改,这会在 Java 和 Android 中对您造成影响。

以上是关于Android Socket + ObjectOutputStream 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

序列化集合

android开发系列之socket编程

Android Socket 通信

Android网络应用之Socket

在 android 上解析 socket.io 数据。 (Gottox Socket.IO)

从android与socket.io通信