嘿傢伙。我正在開發一個客戶端/服務器程序,客戶端是Android設備。 服務器有一個從輸入流中讀取對象的監聽器類。我爲其他計算機創建了一個客戶端軟件,通過本地網絡發送一個小對象。 電腦到電腦的工作很好,我讀對象並打印內容。然而,代碼移植到android(我重寫它以防萬一)不起作用的代碼。我構造了一個可序列化的對象(ANY對象),並通過ObjectOutputStream發送它。我在計算機上運行的服務器確實連接到設備,但它給了我一個ClassNotFound異常,即使即時打印對象(其中有一個toString)。正如我所說,運行在另一臺計算機上的相同代碼(作爲.jar文件)可以很好地工作。Android Socket + ObjectOutputStream無法正常工作
這是真的很奇怪的部分,如果我發送布爾或字符串(從設備)它的作品....它只是我的「自定義」的對象,不。我認爲這將適用於任何「標準」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();
}
}
}
謝謝!
是的,你說得對。它只適用於原始類型......這將解釋爲什麼它可以與String等一起工作......這實在是愚蠢的。有什麼方法可以輕鬆地將對象(包括原始類型和數組列表)轉換爲我可以發送的格式? – somanys21 2010-10-19 02:52:43
**我發現了這個問題**這很奇怪,但是序列化過程會查看您的原始類是什麼** Package **。它只是打我,它給了我一個ClassNotFoundException。這是爲什麼,假設我的主服務器項目在包「Extra」中包含了類XXXX.java。我的測試客戶端使用名爲「Main」的包。它與XXXX.java類相同,只是一個不同的包。序列化過程實際上會考慮包的位置,然後將其發送。我可以證實這一點,因爲我使我的android應用程序在包管理方面與我的服務器完全相同,並且工作正常! – somanys21 2010-10-19 23:45:20
是的,包名稱包含在完整的類名中。相同的類名可以存在於不同的包中。 – 2010-10-20 22:48:35