您的位置:首页 > 移动开发 > Android开发

关于Android中Activity之间socket传递的问题

2016-04-13 00:50 316 查看
众所周知,一个Android程序如果需要和服务器建立socket通信的话,在每个activity中都新建socket与服务器连接是非常不便的,那么我们就需要在各个activity之间传递socket,这样只需要和服务器建立一次连接就可以了。下面博主将自己学习的过程和走过的弯路分享出来供大家参考。

一、通过Intent传递类对象

首先声明,该方法是不能实现socket传递的,下面会介绍原因。

Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。

要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。

Intent中传递这2种对象的方法:

Bundle.putSerializable(Key,Object); //实现Serializable接口的对象

Bundle.putParcelable(Key, Object); //实现Parcelable接口的对象

以下以最常用的Serializable方式为例 :

假设由登录界面(Login)跳转到主界面(MainActivity)传递的对象为登录的用户信息 User类

首先创建一个序列化类:User

import java.io.Serializable;

public class User implements Serializable {
  private int ID;
private String UserName;
private String PWD;
public final void setID(int value)
{
ID = value;
}
public final int getID()
{
return ID;
}
public final void setUserName(String value)
{
UserName = value;
}
public final String getUserName()
{
return UserName;
}
public final void setPWD(String value)
{
PWD = value;
}

public final String getPWD()
{
return PWD;
}

}


登录窗体登录后传递内容

Intent intent = new Intent();

intent.setClass(Login.this, MainActivity.class);

Bundle bundle = new Bundle();

bundle.putSerializable(“user”, user);

intent.putExtras(bundle);

this.startActivity(intent);

接收端

Intent intent = this.getIntent();

user=(User)intent.getSerializableExtra(“user”);

以上就可以实现对象的传递。

补充:

如果传递的是List,可以把list强转成Serializable类型,而且object类型也必须实现了Serializable接口

Intent.putExtras(key, (Serializable)list)

接收

(List)getIntent().getSerializable(key)

但是,很遗憾,Socket类并没有实现Serializable及Parcelable接口,所以不能使用这种方法。

二、利用Application对象

首先简单介绍一下Application对象:

What is Application

  Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己 的Application,也很简单创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。

  Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享 等,数据缓存等操作。

Data passing between components using Application

  假如有一个Activity A, 跳转到 Activity B ,并需要推荐一些数据,通常的作法是Intent.putExtra() 让Intent携带,或者有一个Bundle把信息加入Bundle让Intent推荐Bundle对象,实现传递。但这样作有一个问题在 于,Intent和Bundle所能携带的数据类型都是一些基本的数据类型,如果想实现复杂的数据传递就比较麻烦了,通常需要实现 Serializable或者Parcellable接口。这其实是Android的一种IPC数据传递的方法。如果我们的两个Activity在同一个 进程当中为什么还要这么麻烦呢,只要把需要传递的对象的引用传递过去就可以了。

下面提供一个例子供大家参考:

import android.app.Application;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class ApplicationUtil extends Application {

public static final String ADDRESS = "192.168.1.163";
public static final int PORT = 4869;

private Socket socket;
private DataOutputStream dos = null;
private DataInputStream dis = null;

public void init() throws IOException, Exception {
new Thread(new Runnable() {
@Override
public void run() {
//与服务器建立连接
try {
socket = new Socket(ADDRESS, PORT);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();

}

public Socket getSocket() {
return socket;
}

public void setSocket(Socket socket) {
this.socket = socket;
}

public DataOutputStream getDos() {
return dos;
}

public void setDos(DataOutputStream dos) {
this.dos = dos;
}

public DataInputStream getDis() {
return dis;
}

public void setDis(DataInputStream dis) {
this.dis = dis;
}

}


首先创建了一个 ApplicationUtil 类继承自 Application,其中定义了Socket和输入输出流,以及各个成员变量的getter和setter方法。接下来就非常简单了,除了要在 AndroidMainifest.xml 添加必须的权限,然后只需要给Application标签增加个name属性把自己的Application的名字定入即可

<application
android:name=".ApplicationUtil"


由于Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。我们只需在需要用到socket的activity中编写如下代码,便可实现socket在多个界面切换时保持链接。

ApplicationUtil appUtil =  (ApplicationUtil) Login.this.getApplication();
try {
appUtil.init();
Socket socket = appUtil.getSocket();
dos = appUtil.getDos();
dis = appUtil.getDis();

} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: