編集:重複としてマークされていますが、私の状況は他の状況と同じではありません。シリアル化されたオブジェクトは、入力ストリームと出力ストリームの両方で同じパッケージ名を必要とすることがわかりました。パッケージ名の不一致が私の問題でした。
Java サーバーとクライアントがあります。それらはソケットを介して接続し、ObjectInputStream と ObjectOutputStream を使用してオブジェクト Packet を前後に送信できます。クライアントを Android に実装しようとしました。Android クライアントは接続しますが、ストリームを使用できません。
私の現在の実装では、Android クライアントは、サーバーが実行されている PC と同じネットワーク上にある必要があります。私の PC にも 192.168.1.3 の静的 IP があります。私が得るエラーは
java.io.StreamCorruptedException: 無効な型コード: AC。
デスクトップ サーバーとクライアントのコードを投稿したいのですが、文字数が足りません。ここからコードを取得しました。クライアントが接続するときに文字列が不要になるように、そのコードを変更しました。ユーザーが ChatMessage (または私が名前を変更した Packet) を送信し、メッセージの内容が ClientThread に保存されます。クライアントは最後に送信したメッセージを要求でき、サーバーはそれを返します。
Android クライアントでオブジェクト ストリームを正しく使用するにはどうすればよいですか?
主な活動:
package com.example.androidclient;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
Button btnGetLastMessage, btnSend, btnLogout;
TextView textStatus;
EditText textMessage;
NetworkTask networktask;
private Socket nsocket; // Network Socket
private ObjectInputStream nis; // Network Input Stream
private ObjectOutputStream nos; // Network Output Stream
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnGetLastMessage = (Button) findViewById(R.id.btnGetLastMessage);
btnSend = (Button) findViewById(R.id.btnSend);
btnLogout = (Button) findViewById(R.id.btnLogout);
textStatus = (TextView) findViewById(R.id.textStatus);
textMessage = (EditText) findViewById(R.id.textMessage);
btnGetLastMessage.setOnClickListener(btnGetLastMessageListener);
btnSend.setOnClickListener(btnSendListener);
btnLogout.setOnClickListener(btnLogoutListener);
networktask = new NetworkTask();
networktask.execute();
}
private OnClickListener btnLogoutListener = new OnClickListener() {
public void onClick(View v) {
networktask.SendDataToNetwork(new Packet(
Packet.GET_LAST_MESSAGE));
}
};
private OnClickListener btnGetLastMessageListener = new OnClickListener() {
public void onClick(View v) {
Packet msg = new Packet(Packet.GET_LAST_MESSAGE);
networktask.SendDataToNetwork(msg);
}
};
private OnClickListener btnSendListener = new OnClickListener() {
public void onClick(View v) {
textStatus.setText("Sending Message to AsyncTask.");
Packet msg = new Packet(Packet.SEND_MESSAGE,
textMessage.getText().toString());
networktask.SendDataToNetwork(msg);
}
};
public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
@Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecute");
}
@Override
protected Boolean doInBackground(Void... params) { // This runs on a
// different thread
boolean result = false;
try {
Log.i("AsyncTask", "doInBackground: Creating socket");
SocketAddress sockaddr = new InetSocketAddress("192.168.1.3",
15000);
nsocket = new Socket();
nsocket.connect(sockaddr); // 10 second connection timeout
if (nsocket.isConnected()) {
// Creating both Data Stream
try {
nis = new ObjectInputStream(nsocket.getInputStream());
nos = new ObjectOutputStream(nsocket.getOutputStream());
} catch (IOException eIO) {
Log.i("AsyncTask",
"doInBackground: Exception creating new Input/output Streams: "
+ eIO);
eIO.printStackTrace();
return false;
}
// creates the Thread to listen from the server
Log.i("AsyncTask",
"doInBackground: Socket created, streams assigned, listening from server");
while (true) {
Log.i("AsyncTask",
"doInBackground: Waiting for data from the server...");
try {
Packet messageFromServer = (Packet) nis
.readObject();
Log.i("ListenFromServer", "messageFromServer: "
+ messageFromServer.getMessage());
textStatus.setText("Last message: "
+ messageFromServer.getMessage());
} catch (IOException e) {
Log.i("ListenFromServer",
"Server has close the connection: " + e);
e.printStackTrace();
break;
} catch (ClassNotFoundException e2) {
// Do nothing
} catch (Exception e) {
Log.i("ListenFromServer", "Generic exception: " + e);
e.printStackTrace();
break;
}
}
}
} catch (IOException e) {
Log.i("AsyncTask", "doInBackground: IOException");
e.printStackTrace();
result = true;
} catch (Exception e) {
Log.i("AsyncTask", "doInBackground: Exception");
e.printStackTrace();
result = true;
} finally {
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("AsyncTask", "doInBackground: Finished");
}
return result;
}
public void disconnect() {
try {
nis.close();
nos.close();
nsocket.close();
} catch (Exception e) {
Log.i("AsyncTask", "disconnect: Exception: " + e);
e.printStackTrace();
}
}
public void SendDataToNetwork(Packet msg) { // You run this from
// the
// main thread.
try {
if (nsocket.isConnected()) {
Log.i("AsyncTask",
"SendDataToNetwork: Writing received message to socket");
try {
nos.writeObject(msg);
nos.flush();
} catch (IOException eIO) {
Log.i("AsyncTask",
"doInBackground: Exception during login: "
+ eIO);
eIO.printStackTrace();
nis.close();
nos.close();
nsocket.close();
}
} else {
Log.i("AsyncTask",
"SendDataToNetwork: Cannot send message. Socket is closed");
}
} catch (Exception e) {
Log.i("AsyncTask",
"SendDataToNetwork: Message send failed. Caught an exception");
e.printStackTrace();
}
}
@Override
protected void onProgressUpdate(byte[]... values) {
if (values.length > 0) {
Log.i("AsyncTask", "onProgressUpdate: " + values[0].length
+ " bytes received.");
textStatus.setText(new String(values[0]));
}
}
@Override
protected void onCancelled() {
Log.i("AsyncTask", "Cancelled.");
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
Log.i("AsyncTask", "onPostExecute: Completed with an Error.");
textStatus.setText("There was a connection error.");
} else {
Log.i("AsyncTask", "onPostExecute: Completed.");
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
networktask.cancel(true); // In case the task is currently running
}
}
activity_layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/textMessage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="24sp" />
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Message" >
</Button>
<Button
android:id="@+id/btnGetLastMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Last Message" >
</Button>
<Button
android:id="@+id/btnLogout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Logout" >
</Button>
<TextView
android:id="@+id/textStatus"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Status Goes Here"
android:textSize="24sp" />
</LinearLayout>
アンドロイド マニフェスト:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<application
android:allowBackup="true"
android:debuggable="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidclient.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>