Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过套接字传输Android对象?_Android_Sockets_Object - Fatal编程技术网

如何通过套接字传输Android对象?

如何通过套接字传输Android对象?,android,sockets,object,Android,Sockets,Object,我想通过一个低开销的套接字传输一个Android对象。 我应该使用标准java.io.Serializable还是android.os.Parcel 谢谢大家! 通过套接字传输对象在很大程度上取决于接收对象的内容。通常,这种传输依赖于基于文本的序列化,如XML或JSON 都不是 Parcel是为IPC设计的,其他用途虽然可以说是高效的,但也是危险的。文件上说 Parcel不是通用的序列化机制。此类(以及用于将任意对象放入地块的相应Parcelable API)设计为高性能IPC传输。因此,不适合

我想通过一个低开销的套接字传输一个Android对象。 我应该使用标准java.io.Serializable还是android.os.Parcel


谢谢大家!

通过套接字传输对象在很大程度上取决于接收对象的内容。通常,这种传输依赖于基于文本的序列化,如XML或JSON

都不是

Parcel是为IPC设计的,其他用途虽然可以说是高效的,但也是危险的。文件上说

Parcel不是通用的序列化机制。此类(以及用于将任意对象放入地块的相应Parcelable API)设计为高性能IPC传输。因此,不适合将任何地块数据放入永久性存储:地块中任何数据的底层实现中的更改都可能导致旧数据无法读取

这也意味着您需要确保远程端拥有完全相同版本的Android和您的代码,以确保其工作正常

Serializable也有类似的问题,在(android)DCumeration中甚至有一个解决方案的提示:

警告:此接口限制其实现类将来的更改方式。通过实现Serializable,您可以将灵活的内存中实现细节作为严格的二进制表示公开。当更改的类可序列化时,简单的代码更改(如重命名私有字段)是不安全的

[……]

推荐的替代方案:JSON简洁、易读且高效。Android包括一个流API和一个树API来读取和写入JSON。使用像GSON这样的绑定库直接读写Java对象

如果您想将数据从一个设备移动到另一个设备,我认为您最好为数据创建一个协议,将其发送过来,并用该数据填充远程对象。JSON可能是一个很好的起点


祝你好运

如果您的信息更长、更复杂或需要更高的效率,我建议您尝试使用。它们允许进行一些合理的修改,比如添加新字段,或者删除以前可选的字段,或者添加一个全新的结构作为字段。然而,您也将拥有带有真正setter和getter的真正类(可以是不可变版本,也可以是可变构建器,您希望如何)。对你所做的事情进行更严格的控制并不像看上去那么糟糕

考虑XML,但是更小、更快、更简单

序列化对象的主要缺点是不是,即以后无法更改协议详细信息。不同的是,如果引入版本号,您可以进行许多兼容的更改,如果希望旧客户端查找该属性,您也不能在JSON中重命名属性名称


但是序列化对象是java特定的,例如,如果您在将来做出决定,则无法拥有更高效的C++服务器客户端或使用Python进行原型开发。协议缓冲区与语言无关。

首先,定义要发送的对象。例如,我们可以定义一个名为Message的类来封装我们的通信:

 public class Message implements Serializable {
    private static final long serialVersionUID = 1L; // Your version number

    private int    senderID;
    private String messageText;

    public Message(int id, String text) {
        senderID    = id;
        messageText = text;
    }
    public String getText() {
        return messageText;
    }
}
接下来,实例化对象,将套接字的流包装在对象流中,然后通过套接字发送消息:

Message sayhey = new Message("123456789", "Hello");

Socket socket = new Socket(host, port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

out.writeObject(sayhey);
在套接字的另一端,可以通过调用返回对象上的方法来检索和使用消息:

ObjectInputStream in  = new ObjectInputStream(socket.getInputStream());
Message messageObject = (Message) in.readObject();
String messageText = messageObject.getText();

您可以实现Serializable。

谢谢您的回答。如果我的接收设备也是Android设备,我可以使用带有ObjectOutputStream/ObjectInputStream的包裹在接收端重建对象吗?谢谢你的回答。您的意思是,如果接收方也运行Android,我可以使用带有ObjectOutputStream/ObjectInputStream的Parcel来重建对象吗?不,相反。要让parcel在这两台设备上工作,您需要有完全相同的android版本和完全相同的代码版本。一旦出现任何偏差,就会出现无法恢复的虚假错误。如果您创建自己的协议,您将能够对其进行分析,以便更新它并保持向后兼容性。将serialVersionUID添加到类中,这将在您进行添加或删除新字段甚至公共方法等更改后保持其兼容性。