不用序列化Activity间传值

深入底层 | 字节Android高级岗: Activity间传递对象为什么要序列化?序列化有哪几种方式?它们有什么区别? 前言 我们都知道进行Android 开发的时候,跳转到Activity和Fragment的时候,传递对象是通过Intent或者bundle 进行传递。当这个对象没有实现序列化的时候 当你通过Inetnt传递的时候会报红,系统会提示你将这个对象实现序列化。 不同 Activity 之间传输数据可以通过 Intent 对象的 putExtra 方法传递,对于 java 的八大基本数据类型(char int float double long short boolean byte)传递是没有问题的,但是如果传递. 阅读详情

    在两个Activity间传递Java Object 对象时,需要进行序列化,实现Serializable 或者Parcelable 接口,

作为一个JavaWeb转过来的程序员,我比较有强迫症,一看到序列化,我马上联想到JAVA RMI。心里很不情愿实现这些接口,


为什么我同一个程序的在两个对象间传递对象要这么繁琐呢。。。。。。。


然后发现,Android的设计把四个组件的启动,调用全部用Intent来完成,这种封装对使用者来说有着统一的调用传参方式,使用起来很简单,代码简洁,更容易接受。但是在内部组织的时候存在个问题,那就是不同的组件可能是不同进程中的,比如Activity和Service,他们存在在不同进程中。


同一个进程间的不同线程可以共享内存,直接调用对象就可以了,但是不同进程间无法直接调用,这就需要进程间通信。其实我们使用http协议发送请求也是不同进程间通信的一个方式,这种通信是基于Socket的。只不过http发送的是文本参数。


不同进程间的对象参数传递,android要求java对象序列化。而且在Intent启动不同组件的时候保持一致,不管是不是同一进程的组件,android都要进行序列化,然后传递。


如果我们的程序在不同Activity间传递java对象,那么它们属于同一个进程,在同一个进程间调用,我实在是不想序列化了。我们可以借助全局对象Application,把参数值保存在Application中,我们在get得到参数后要把对象及时删除,防止内存泄露。


但是我们对所有参数都在Application中加入一个成员变量,每个变量加一个set get方法,这样的话代码看起来有点糟糕了,难于维护。


   我们考虑使用HashMap,存储的参数对象作为值value,key键我们可以随意定,这个时候我们可以借鉴一下ThreadLocal的设计


用ThreadLocal对象的一个实例作为一个key键,ThreadLocal提供set(T value)方法,

把this实例对象作为key ,T value作为值,存储在Thread的hashmap中,ThreadLocal提供get()方法,

得到Thread 的hashmap中ThreadLocal.this实例的value值。


    这种设计的好处就是完全隐藏hashmap.put(key,value),hashmap.get(key),使用的时候


ThreadLocal key = new  ThreadLocal();

key.put(object);


   我们只要保持key的引用,通过key.get()就可以得到对应的参数了。


仿照ThreadLocal,我写了ActivityLocal对象,其实应该分别叫做ThreadLocalVariable  和ActivityLocalVariable

代码如下:

public class ActivityLocal {
    private Context context = null;


    public ActivityLocal(Context context){
        this.context = context;
    }
    
    public <T> T get(){
        Iapplication application = (Iapplication) ((Activity)this.context).getApplication();
        Intent intent = (Intent)((Activity)this.context).getIntent();
        String key = intent.getExtras().getString("activitylocal");
        ActivityLocal local = application.get(key);
        return  (T) application.get(local);
    }
    
    public <T> void set(T value){
        Iapplication application = (Iapplication) ((Activity)this.context).getApplication();
        application.set(this, value);
        application.set(String.valueOf(this.hashCode()), this);
    }
}


因为我们要在两个Activity间得到同一个key即同一个ActivityLocal实例,我们把ActivityLocal实例也保存在Application中,用固定字符串"activitylocal"作为key,Iapplication的实现代码如下:

public class Iapplication extends Application{

    private HashMap<String,ActivityLocal> localMap = new HashMap<String,ActivityLocal>();
    private HashMap<ActivityLocal,Object> activityMap = new HashMap<ActivityLocal,Object>();

    public ActivityLocal get(String key){
        return this.localMap.remove(key);
    }
    
    public void set(String key,ActivityLocal activityLocal){
        this.localMap.put(key, activityLocal);
    }
    
    public Object get(ActivityLocal activityLocal){
        return this.activityMap.remove(activityLocal);
    }
    
    public void set(ActivityLocal activityLocal,Object value){
        this.activityMap.put(activityLocal, value);
    }
}



具体传递的时候

Intent intent = new Intent(ActivityA.this, lActivityB.class);

        ActivityLocal al = new ActivityLocal(this);

Object value = new Object();
       
 al.set(value );

  Bundle bundle = new Bundle();
        bundle.putString("activitylocal",String.valueOf(al.hashCode()));

        intent.putExtras(bundle);
        this.startActivity(intent);


这样就把参数对象value传递了

在另一个Activity中获取就很简单了:

ActivityLocal local = new ActivityLocal(this);
        Obejct value = local.get();


开始的时候我想把Intent的实例作为key,来存储ActivityLocal的实例,但是调试发现Intent内容会变化,就是equals不相等,没有找到更好的办法,就把ActivityLocal的hashCode传递到ActivityB中,通过这个hashCode,在Application中得到刚才的ActicityLocal实例,进一步得到参数Object。


因为涉及到了在不同Activity来传递ActivityLocal对象实例,所以这个方式的缺点就是只能传递一个ActivityLocal对象实例,也就是说不同Activity间的参数也只能传递一个,但是大多数情况下也足够了,不行的话,可以用hashmap或者list存储,然后作为整个的参数传递过去。

深入底层---字节Android高级岗:-Activity间传递对象为什么要序列化?序列化有哪几种方式?它们有什么区别? 我们都知道进行Android 开发的时候,跳转到Activity和Fragment的时候,传递对象是通过Intent或者bundle 进行传递。当这个对象没有实现序列化的时候 当你通过Inetnt传递的时候会报红,系统会提示你将这个对象实现序列化。不同 Activity 之间传输数据可以通过Intent对象的putExtra。 阅读详情

相关推荐

Ubutntu下使用realsense d435i(二):获取某二维像素点的三维坐标

00 准备工作 准备工作包括安装驱动以及pyrealsense2,具体可参考上一篇: Ubutntu下使用realsense d435i(一):准备工作以及安装pyrealsense2 https://blog.youkuaiyun.com/gyxx1998/article/details/121461293 01 通过二维像素点获得物体三维坐标 这个在上一篇已经介绍了代码: realsense d435i获取某像素点三维坐标(计算深度和点云两种方法) https://blog.youkuaiyun.com/gyxx1998/

gyxx1998的博客 9943

Flutter 页面间数据传递(共享)的几种常用方式

前言 在Android中,我们常遇到的场景就是在页面跳转(Frament,Activity)时候,要将当前的部分数据携带到另外一个页面中,供另外页面使用。这时候我们常用的就是使用Intent, Bundle等携带数据。 那么在Flutter的开发过程中,页面之间的数据传递也是必不可少的,又是怎么把一个页面的数据传递(共享)给另外一个页面,或者关闭当前页面并把当前页面的数据带给前一...

weixin_30516243的博客 2465

睿尔曼超轻量仿人机械臂--医疗工作站运行Demo(Python)

开发环境系统:win10Python版本:python 3.11.2由于机械臂相关软件版本不定期更新,如果你使用的软件接口或协议与本文有出入,请联系官方技术人员及时更新。

realman_Rop的博客 1093

Android 最全 Intent 传递数据姿势

点击上面蓝色字体关注“IT大飞说” 置顶公众号(ID:ITBigFly)第一时间收到推送 作为一个 Android 开发人员,我们都是用过 Intent,用它来在组件之间传递数据,所以说 Intent 是组件之间通信的使者,一般情况下,我们传递的都是一些比较简单的数据,并且都是基本的数据类型,写法也比较简单,今天我在这里说的是如何使用 Intent 传递对象及集合,我们知道Inten...

「程序员飞飞」的博客 5618

MIPI CSI-2 协议解析

CSI-2标准协议前言一、Overview of CSI-2二、CSI-2 layer Definitions三、 Camera Control Interface(CCI)3.1 数据传输协议(Data Transfer Protocol)3.1.1 消息类型(Message Type)3.1.2 读写操作(Read/Write Operations)3.1.2.1 随机位置单次读3.1.2.2 当前位置单次读3.1.2.3 随机位置连续读3.1.2.4 当前位置连续读3.1.2.5 随机位置单次写3.1

Lucky 3万+

Jetpack Compose Navigation实战:从基础到高级导航模式

本文全面解析Jetpack Compose Navigation在Android开发中的应用,从基础导航实现到高级模式(如单任务/单顶模式),涵盖参数传递、嵌套导航、深层链接等核心功能。通过实战代码示例展示如何优化导航性能,并与ViewModel、Hilt等架构组件整合,为开发者提供高效的Compose导航解决方案。

pz890123456的博客 372

为什么Android开发向Service传递消息需要序列化

独立进程:在Android中,Service可以在与Activity不同的进程中运行。为了让不同进程之间能够通信,需要使用进程间通信(IPC)机制。内存独立:由于每个进程都有自己的独立内存空间,因此简单的内存引用传递在不同进程之间是不可行的。

xj-up的博客 544

国产安路FPGA(二)-TD软件时序约束与硬件调试实战

本文深入探讨了国产安路FPGA开发中TD软件时序约束的实战应用。文章详细解析了SDC文件的核心语法,包括基础时钟、生成时钟及输入输出延迟约束的编写方法,并针对硬件调试中常见的时序问题提供了解决方案。通过一个图像处理流水线的优化案例,阐述了如何结合代码修改与约束设置,实现设计从“能跑”到“跑得稳”的关键提升,是掌握FPGA可靠设计的实用指南。

weixin_29183637的博客 377

无需序列化,复杂数据传递也如此简单,intent及进程间通信简化

我们在做intent之间及IPC,跨进程,aidl等等进行复杂数据传递的时候,一般需要将数据转换为对象,并且使用Serializable或者Parcelable。 本文介绍一种更加简单的思路,实现复杂数据传递。 过程如下: 发送端:将数据转化为map数组,map数组存于list中,将list转化为String进行传递, 接收端:将String转化为list,取出map属性。 本质:将复杂

zhan10001的博客 662

手把手教你搭建幽冥传奇手游:从环境配置到常见Bug修复(附完整避坑指南)

本文详细指导如何从零搭建幽冥传奇手游,涵盖服务器选型、数据库部署、双区架构配置等关键步骤,并提供通天塔闪退、技能显示异常等常见Bug的修复方案。附完整避坑指南,帮助开发者高效解决90%的典型问题,确保游戏稳定运行。

weixin_29232121的博客 242

Midscene.js(2):代码集成 + 桥接模式(Bridge Mode)的使用「喂饭教程」

本文将手把手教你从零开始搭建一个 Node.js 项目,集成 Midscene.js,并利用其桥接模式实现对 Chrome 浏览器的自动化操作。我们将通过具体的实例,来展示 Midscene.js 的便捷性与 AI 能力的结合。

blues_C的博客 1844

android 序列化传参数,android 传值 序列化

Activity之间传数据时,为了避免麻烦,往往会将一些值封装成对象,然后将整个对象传递过去。传对象的时候有两种情况,一种是实现Parcelable接口,一种是实现Serializable接口。0、解释两种接口:1)实现Serializable接口是JavaSE本身就支持的。2)Parcelable是Android特有的功能,效率比实现Serializable接口高,像用于Intent数据传递也都...

weixin_42515024的博客 330

基于传感器数据实现火灾报警预测分析

火警 系统当检测到烟雾、火灾、一氧化碳或其他与火灾有关或一般通知的紧急情况时,向人们发出警告

DT程序员的博客 722

Activity间传值方式总结

Activity页面跳转传值 第一种方法:(Intent) 发送方: Intent intent = new Intent(); intent.putExtra("name", "诸葛亮"); intent.putExtra("age", 50); intent.putExtra("IQ", 200.0f); intent.setClass(MainActivity.this, Secon...

qq_14914623的博客 197

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

android 通知栏点击跳转传值,android Activity简单的跳转传值方法(wings6)

普通的跳转方法startActivity(new Intent(IndexActivity.this, BasicNaviActivity.class));Fragment跳转ActivityIntent intent = new Intent(getActivity(), NaviStartActivity.class);startActivity(intent);所有传值 都尽量在 onCre...

weixin_35869861的博客 255

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Android之路——第二步:Activity之间传值(Intent、onActivityResult)

我的博客:http://blog.youkuaiyun.com/name_cjf前言上一篇博客中我们了解了如何切换Activity,然而一个真实的app中,不仅需要可以切换Activity,还需要使Activity之间可以通信。所以今天就讲讲Activity的传值。 传值方法简介关于Activity传值,其实是很灵活的,其中大概有以下几类传值方法: Intent传值:这是Android中最普通的传值方式,Int

NAME_CJF的博客 663

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Activity的传值的几种方式

开发过程中页面和页面之间传递数据示最长遇到的。下面我们来研究下activity之间传递数据的几种方式. 1、通过application实现传递数据 2、activity之间的回传值(startActivityForResult()) 3、用intent进行传值 一、通过application实现传递数据 BaseApplication中 public class BaseAppli

fang410103的博客 1525

Android ARouter 传值 传bean 失效问题解决

最近在用阿里巴巴的路由 ARouter的时候,遇到传递多个值和bean的过程中,无法把bean 传递过去, 当时检查的时候,没有发现问题,但是为什么就是传值不过去,后来 发现 当你传递多个值,特别是bean的时候,这个bean首先要序列化,然后,要有一个空参构造,这样传值过去,才可以 例如以下代码; ARouter.getInstance().build(ARouterPath.XXX_...

wolfking0608的博客 4025

Android Activity传值 回传

简单介绍 在Android中,如果我们要通过一个Activity来启动另一个Activity,可以使用 startActivity(Intent intent)方法来传入一个Intent对象,这个Intent对象我们可以精确的指定我们需要跳转的Activity上,或者通过Intent对象来指定我们要完成的一个action操作,同时我们可以通过intent来携带一些值,进而来Activity见跳...

林清溯 1175

Android 两个activity之间传值

使用Inten的putExtra传递 第一个Activity中 //创建意图对象 Intent intent = new Intent(this,MainActivity2.class); //设置传递键值对 intent.putExtra("name","花花"); //激活意图 startActivity(intent); 第二个Activity中 // 获取意图对象 Intent intent = getIntent(); //获取传递的值 String name= inte

afufufufu的博客 2584

activity之间传值,解决:Parcelable encountered IOException writing serializable object异常

今天写代码的时候遇到了两个activity之间需要传数据,本来是一件非常简单的事情 平常都是使用 intent.putExtra(type,value);就没问题了。 传对象的话就需要实现序列化接口了就行了。 为什么要实现序列化接口,你可以当这个是android的一个机制,就是得这么办,不这么办不行。 实际上实现序列化接口就是为了让数据能变成一种可存储或可传输的状态,可以传输到网络,也可以

德超a的博客 2万+

android 多个activity传值,Android中activity传值的两种方式

第一种:第一个Activity/***通过这个方法跳转到activity2界面*/publicvoidgotoActivity2(Viewv){//创建一个意图Intentintent=newIntent(this,MainActivity2.class);//第一种传值方式Bundlebundle=newBundle();bundle.putString("name","zhan...

weixin_35304361的博客 591

两个Activity之间传list值

序列化bean为了两个Activity之间list传值

qvaep的博客 531

Android四大组件之Activity(跳转与传值)

一、跳转 a,三种显式跳转 1,Intent intent = new Intent(本Activity.this,要跳转的Activity.class);(常用) 2,Intend intent =new Intent();    intent.setClassName(本Activiy.this,"包名.类名.class"); 3,ComponentName componetNam

u014321386的博客 551
上一篇: Handler 动态注入
下一篇: ReactNative 学习笔记Component 和createClass区别
mapsong
博客等级 码龄12年 0粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值