Android中传送序列化对象出现的ClassNotFoundException解决办法 博客分类: Android AndroidClassNotFoundException序列化
最近在做课程设计,老师要求是基于Android上的wifi通信的,之前没事的时候写过一个套接字编程的,完成了一个类似于聊天工具的功能。于是就想着改改,凑合着用用交上去。没想到在写的时候发现了一个很让人摸不着头脑的异常:ClassNotFoundException。
先说一下编码之前的思路,我想在PC上做服务端,在Android上做客户端,同时,在两端封装了RequestObject,ResponseObject等序列化的对象,用于在服务端和客户端之前传递请求和响应对象(通过ObjectInputStream和ObjectOutputStream),如下项目结构,可是在传送对象的时候发现了RequestObject出现了ClassNotFoundException,然后就直接无语中,明明服务端和客户端的RequestObject等用于传递进对象流的对象都是一模一样的,没道理找不到类啊。
经过一番尝试未果,索性把两个.java文件中唯一不一样的一行改掉,即为import xxx.xxx.xxx,我将两个项目中有关传递信息的model包的包名改为一样的。果然测试通过了,可能识别这种对象的时候,包名也是一个必要的因素吧。
问题虽然解决了,但是总觉得不方便,因为如果服务端这边的序列化对象要更改信息,势必客户端这边的对象也要改,同一次修改缺要改两遍信息,而且还很容易混淆,于是我又做了如下处理:新建了一个项目,用于保存有关任何需要传递的序列化对象,将这个项目导出.jar文件,再作为外部jar文件导入至客户端和服务端的项目里,这样就省去了很多工作,在正式往项目里添加操作之前,做了一个demo测试。
建立3个项目,分别是Android客户端,需要传递的数据,PC的服务端。分别编写好各个代码
/** * 2012-5-15 * By WayneHu */ package pc.test; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; import object.RequestObject; public class MyServer { public static void main(String[] args) { try { ServerSocket server = new ServerSocket(10000); while (true) { System.out.println("Server is waiting..."); Socket socket = server.accept(); InputStream is; is = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(is); RequestObject request = (RequestObject) ois.readObject(); System.out.println(request.getRequestClass()); ois.close(); is.close(); socket.close(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package android.test; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import object.RequestObject; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class AndroidClientActivity extends Activity { /** Called when the activity is first created. */ private EditText et_input; private String input; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); et_input = (EditText) findViewById(R.id.input); } public void onClick_send(View view) { input = et_input.getText().toString(); RequestObject request = new RequestObject(1, input, null); try { Socket socket = new Socket("10.0.2.2", 10000); OutputStream os = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(request); oos.close(); os.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
这里多说一句,在模拟器上的客户端,给PC上的服务端建立连接的时候,IP应为10.0.2.2
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <EditText android:id="@+id/input" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="onClick_send" android:text="SEND" /> </LinearLayout>
/** * 2012-5-15 * By WayneHu */ package object; import java.io.Serializable; public class RequestObject implements Serializable { public static final int LOGIN_REQUEST = 1; public static final int REGIST_REQUEST = 2; public static final int CHAT_REQUEST = 3; private int requestType; private String requestClass; private Object requestBody; /** * @param requestType 请求类型 * @param requestClass 请求类名 * @param requestBody 请求对象 */ public RequestObject(int requestType, String requestClass, Object requestBody) { super(); this.requestType = requestType; this.requestClass = requestClass; this.requestBody = requestBody; } /** * @return the requestType */ public int getRequestType() { return requestType; } /** * @param requestType the requestType to set */ public void setRequestType(int requestType) { this.requestType = requestType; } /** * @return the requestClass */ public String getRequestClass() { return requestClass; } /** * @param requestClass the requestClass to set */ public void setRequestClass(String requestClass) { this.requestClass = requestClass; } /** * @return the requestBody */ public Object getRequestBody() { return requestBody; } /** * @param requestBody the requestBody to set */ public void setRequestBody(Object requestBody) { this.requestBody = requestBody; } }
然后在保存传递对象的项目那里导出JAR文件,如下图,然后分别在客户端项目和服务端项目右键选择构建路径-配置构建路径-添加外部JAR,选择之前导出的JAR文件,即可。
测试效果如下:
第一次写这么长的博客,用来记录自己学习路程的同时,也希望能帮助遇到同样问题的朋友。写的不好的地方欢迎朋友们提意见,写的有错的地方也希望各位大神能够不吝赐教。还是那句话,文明看帖,欢迎轻拍。
欢迎转载,转载请注明出处: