惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - duguguiyu

『Android开发精要』推荐 深入Android【七】 —— 资源文件 深入Android 【六】 —— 界面构造 深入Android 【五】 —— 任务和进程 深入Android 【四】 —— 组件调用 深入Android 【三】 —— 组件入门 深入Android 【二】 —— 架构和学习 深入Android 【一】 —— 序及开篇 Symbian手记【五】 —— Symbian的异步框架 Symbian手记【四】 —— Symbian的容器 Symbian手记【三】 —— Symbian的描述符 Symbian手记【二】 —— Symbian对象构造 Symbian手记【一】 —— Symbian命名法 分布式基础学习【二】 —— 分布式计算系统(Map/Reduce) 分布式基础学习【一】 —— 分布式文件系统 Chrome源码剖析 【五】 Chrome源码剖析 【四】 Chrome源码剖析【三】 Chrome源码剖析【二】
深入Android【八】 —— Activity间数据传输
duguguiyu · 2010-05-29 · via 博客园 - duguguiyu

Activity间数据传输

当对Android有一些了解后,不难发现,Android程序UI框架接近于Web页面的概念。每一个用于呈现页面的组件,Activity,都是彼此独立的,它们通过系统核心来调度整合,彼此之间的通过Intent机制来串联。
每一种架构都会有其利弊,Android当然也不能超然脱俗。由于Activity之间的松耦合关系,使得其复用能力特别的出色,Mash-Up方式可以有效的提高开发效率。但另一方面,由于Activity过于的独立,它们之间的数据共享,成为一个麻烦的事情。

基于消息的传输

最标准的Activity之间的数据传输,就是通过Intent的Extra对象。比如,你在A这个Activity上拿到一坨用户输入的文本信息,兴高采烈的想把它放到B这个Activity上展示并发送,一个很可行的方式,是通过Intent的putExtra接口,把用户输入的那些字符信息,按照key/value的形式放进Intent,传输到B这个Activity上。


如上图示,从A到B的传输,看上去是一个直连,但其实,Intent都是要经由系统核心层去分析调度的,这个操作,跨越了进程边界,自然而然,其中的数据,就是需要序列化和反序列化的,而不可以仅通过一个指针就倒腾过去了。

基于这样类消息的传输模式,好处不多说,直接谈问题:

  • 首先,对于大数据,就是一场杯具,不可能一坨上M的数据,也来来回回的传来传去,慢死了谁来负责;
  • 再则,Activity之间,维系的是一种线性关系,当我想把一份数据,从队尾一级级传到队头的话,自己历经磨难不提,会把中间所有的Activity都搭上,他们明明自己可能不需要这份数据,也得拿着搁着,为他人做嫁衣裳,不惆怅都不行;
  • 此外,基于消息的传输,会把同一份数据生成若干个副本,有时候,这样很好,没有副作用,大家自己玩自己的不需要看别人脸色,但还有些时候,你就上杆子需要把这些数据都修改一下,同步起来那就太惨烈了;
  • 最后,写序列化代码实在是太无聊了,稍微复杂点的代码,就要自己写个序列化接口,整个吃力不讨好的活计。

基于外部存储的传输

既然

兽兽

手手相传太幸苦,自然而然的想法就是找个地方,A把数据搁在那里,把地址信息告诉B,B需要的话,按图索骥,自取就好。这个搁东西的地方,可以考虑选择外部存储

在Android中,预设了一些快捷便利类和模块,更好的支持不同类别数据的存取。如果,需要存储的是一些小数据量的配置信息,可以选择Preference,它等同于传统意义上的设置文件。Preference提供了一些基于key/value的存取接口,可以放置一些简单的基本数据或者派生了Parcelable接口的对象。一个很好的应用场景是Cookie的存放。你在登录界面获得了一份Cookie,你可以把它扔进Preference,谁想要谁去拿,再也不要来来回回的折腾了。

Preference适合于小数据、设置信息,如果大数据,你可以考虑使用数据库。在Android中,使用的是Sqlite,相关的类,堆放在android.database名字空间下,自查,无需赘述。

在Android里,数据库是私有的,如果想分享给第三方组件使用,就需要用ContentProvider来封装了。比如你用系统的录音机组件即时搞一段音频信息,它不是返回可能大到恐怖的录音数据,而是会返回给你一个Uri,它标明了这份数据在ContentProvider的地址信息,拿着这个Uri,领取数据就好。

当然当然,如果你足够淡定,也可以用赤果果的File来存储。如果这个文件存在手机私有目录下,那就内部使用,放在SD卡上,那就可以所有应用,一切分享。


基于这样外部存储的数据传输,优缺点显而易见,它解决了困扰Intent的传输路径复杂,不利于传输大批量数据的问题,但同时,它有留下了效率隐患,复杂了编程模型。因为面对外部存储,开发者必须要考虑效率问题,很多时候,多线程就会被提上议程,这样,想不麻烦,都不行鸟。

基于Service的传输

既然存在外部太慢,那么还是在内存级别解决问题好了,这时候,你可能就需要请出Android四大组件之一的Service了。Service设计的本意,就是提供一些后台的服务,数据存取,也可以归于其职责的一部分。

Service是提供了直连机制,调用的Activity,可以通过bindService方法,与目标Service建立一条数据通路,拿到IBinder。这样,通过Android提供的IPC模型,就可以进行远程方法的调用和数据的传输了。 

如上,通过这种模式,可以解决一定问题,但是对于Service来说,实在是太大才小用了,Service的专长,不是在数据,还是在逻辑。对于传数据而言,Service还是重量了一点,不但是有连接耗精力,传输经由IPC,写起来也够费劲。而且作为组件,Service随时可能死掉,你还是要费劲心机的处理数据的持久化,得不偿失。

利用Application传输

好吧,如果你需要在不同页面之间共有某个内存对象,很合适的一种方式是把它们扔到Application里面。Application是Context的一个子类,它会在整个应用任何一个组件起来之前,先起来嘘嘘。它的生命周期会贯穿整个应用所有组件的生命旅途,因此,放在其中的对象,不会被处理掉。

在Activity中,可以通过getApplication接口,随时获得Application对象的引用,用于实现一些全局对象的存储,和处理,真是最合适不过的地方了。

当然,好东西也不要使用过度,可以想象,由于Application存活周期长,其上引用的对象一直缺少被释放的机会,如果你把它当成垃圾场,什么东西都往里扔,污染环境,混乱逻辑不提,单就是滥用内存资源这一项,就够罪孽深重一把了。

因此,如果数据不是真的需要全局使用,不要搁在其中,如果数据太大,不要全部load出来,合理使用数据库等外存储设备,还是必须要的。

结语

还有一些特殊情况,可以考虑用一些特殊的方式。比如子Activity之间,可以通过调用getParent获得父Activity的引用,来访问期间的对象,云云。小众情况,姑且不提。
以上这些概念,我相信所有的coder都了如指掌,如何处理这样的数据,都心如明镜。我只是给它们套上了一件Android的外衣,让初入Android的coder们,能迅速找到心仪的兵器,劈山砍石,攻城拔寨。