关于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
登录窗体登录后传递内容
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在同一个 进程当中为什么还要这么麻烦呢,只要把需要传递的对象的引用传递过去就可以了。
下面提供一个例子供大家参考:
首先创建了一个 ApplicationUtil 类继承自 Application,其中定义了Socket和输入输出流,以及各个成员变量的getter和setter方法。接下来就非常简单了,除了要在 AndroidMainifest.xml 添加必须的权限,然后只需要给Application标签增加个name属性把自己的Application的名字定入即可
由于Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。我们只需在需要用到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(); }
相关文章推荐
- Android ListView实现上拉到底部的时候自动刷新数据
- Android动态加载基础 ClassLoader工作机制
- Qt for Android环境搭建浅谈
- Android BottomNavigationBar的使用
- Java加密解密工具(适用于JavaSE/JavaEE/Android)
- Android 编码规范
- Android_基础知识掌握
- android listview 执行notifyDataSetChanged 不更新数据的原因
- Android 软键盘弹出时布局内指定内容上移实现及问题解决
- 这家Android培训机构 备受学员关注
- Android进阶学习-一般动画(使用Animation封装特效工具类1)
- Android进阶学习-一般动画(使用Animation封装特效工具类2)
- Android进阶学习-属性动画(使用Animator封装特效工具类1)
- Android进阶学习-属性动画(使用Animator封装特效工具类2)
- 使用Android Studio对代码进行重构
- Android移动View的几种方式
- 给Android开发者的Rxjava详解
- 【Android】如何写一个JsBridge
- Android动画效果-更新中
- Android 自定义RecyclerView布局(一)