- 浏览: 237070 次
- 性别:
- 来自: 湖南
最新评论
-
yuxuejun1123:
为什么没有powerPC,个人觉得这篇文章把mips和powe ...
ARM MIPS PowerPC比较 -
yy232:
我刚学这个,有点疑问,希望你能为我解答 你说 “任何人只 ...
centos的用户、组权限、添加删除用户等操作的详细操作命令 -
wstxdz1023:
就那么几句代码,全是问题
socket 心跳
有了framework后,我们不用面对赤裸裸的OS API,做一些重复而繁杂的事情。但天下没有免费的午餐,我们还是需要学会高效正确的使用不同的framework,很多处理某一特定问题的手法在不同的framework中,用起来都会有所不同的。
在Android中,下层是Linux的核,但上层的java做的framework把这一切封装的密不透风。以消息处理为例,在MFC中,我 们可以用PreTranslateMessage等东东自由处理消息,在C#中,Anders Hejlsberg老大说了,他为我们通向底层开了一扇“救生窗”,但很遗憾,在Android中,这扇窗户也被关闭了(至少我现在没发现...)。
在Android中,你想处理一些消息(比如:Keydown之类的...),你必须寻找Activity为你提供的一些重载函数(比如 onKeyDown之类的...)或者是各式各样的listener(比如OnKeyDownListner之类的...)。这样做的好处是显而易见的, 越多的自由就会有越多的危险和越多的晦涩,条条框框画好了,用起来省心看起来省脑,这是一个设计良好的framework应该提供的享受。对于我目前的工 程而言,我没有什么BT的需求在当前API下做不到的,google的设计ms还是很nice的。
但世界是残酷的,有的时候我们还是必须有机制提供消息的分发和处理的,因为有的工作是不能通过直接调用来同步处理的,同时也不能通过 Activity中内嵌的消息分发和接口设定来做到,比如说事件的定时触法,异步的循环事件的处理,高耗时的工作等等。在Android中,它提供了一些 蛮有意思的方式来做这件事情(不好意思,我见不多识不广,我没见过类似玩法,有见过的提个醒 && 嘴下超生^_^),它有一个android.os.Handler的类,这个类接受一个Looper参数,顾名思义,这是一个封装过的,表征消息循环的 类。默认情况下,Handler接受的是当前线程下的消息循环实例,也就是说一个消息循环可以被当前线程中的多个对象来分发,来处理(在UI线程中,系统 已经有一个Activity来处理了,你可以再起若干个Handler来处理...)。在实例化一个 handlerInstance之后,你可以通过sendMessage等消息发送机制来发送消息,通过重载handleMessage等函数来分发消 息。但是!该handlerInstance能够接受到的消息,只有通过handlerInstance.obtainMessage构造出来的消息(这 种说法是不确切的,你也可以手动new一个Message,然后配置成该handlerInstance可以处理的,我没有跟进去分析其识别机制,有兴趣 的自己玩吧^_^)。也就是说A, B, C, D都可以来处理同一线程内的消息分发,但各自都只能处理属于自己的那一份消息,这抹杀了B想偷偷进入A领地,越俎代庖做一些非份之事的可能(从理论上 看,B还是有可能把消息伪装的和A他们家的一样,我没有尝试挑战一下google的智商,有BT需求的自行研究^_^)。这样做,不但兼顾了灵活性,也确 保了安全 性,用起来也会简单,我的地盘我做主,不用当心伤及无辜,左拥右抱是一件很开心的事情。。。
很显然,消息发送者不局限于自己线程,否者只能做一些定时,延时之类的事情,岂不十分无趣。在实例化Handler的时候,Looper可以是 任意线程的,只要有Handler的指针,任何线程也都可以sendMessage(这种构造方式也很有意思,你可以在A线程里面传B线程的Looper 来构造 Handler,也可以在B线程里构造,这给内存 管 理的方法带来很大的变数...)。但有条规则肯定是不能破坏的,就是非UI线程,是不能触碰UI类的。在不同平台上有很多解决方式(如果你有多的不能再多 的兴趣,可以看一下很久很久以前我写的一个,不SB不要钱)。我特意好好跟了一下android中的AsyncQueryHandler类,来了解 google官方的解决方案。
AsyncQueryHandler是Handler的子类,文档上说,如果处理ContentProvider相关的内容,不用需要自行定义 一套东西,而可以简单的使用async方式。我想指代的就应该是AsyncQueryHandler类。该类是一个典型的模板类,为 ContentProvider 的增删改查提供了很好的接口,提供了一个解决架构,final了一些方法,置空了一些方法。通过派生,实例化一些方法(不是每个对 ContentProvider的处理多需要全部做增删改查,我想这也是该类默认置空一些方法而不是抽象一些方法的原因),来达到这个目的。在内部,该类 隐藏了多线程处理的细节,当你使用时,你会感觉异常便利。以query为例,你可以这么来用:
// 定义一个handler,采用的是匿名类的方式,只处理query,因此只重写了onQueryComplete函数: queryHandler = new AsyncQueryHandler( this .getContentResolver()){// 传入的是一个ContentResolver实例,所以必须在OnCreate后实例化该Handler类 @Override protected void onQueryComplete( int token, Object cookie, Cursor cursor) { // 在这里你可以获得一个cursor和你传入的附加的token和cookie。 // 该方法在当前线程下(如果传入的是默认的Looper话),可以自由设定UI信息 } }; // 调用时只需要调用startQuery(int token, Object cookie, ContentURI uri,String[] projection, String selection, String[] selectionArgs, String sortOrder)函数即可: queryHandler.startQuery(token, cookie, uri, projection, selection, selectionArgs, sortBy);
可见,该类的使用是多么简单(其实现可不会很容易,因为我尝试做了一次造车轮的工作*_*),比直接用Handler简单无数倍。但让我倍感孤 独的是,不知道是没人做异步的ContentProvider访问,还是这个类使用太过于弱智(这个使用方法可是我摸索了半天的啊,难道我真的如此的弱 @_@),抑或是大家都各有高招,从SDK到网上,没有任何关于该类的有点用的说明。而我又恰巧悲伤的发现,这个类其实有很多的问题,比如他吃掉异常,有 错误时只是简单的返回null指针(这个其实不能怪他,你可以看看这里...);当你传一个null的ContentResolver进去的时候,没有任 何异常,只是莫名其妙的丢弃所有消息,使你陷入苦苦的等待而不知其因;更愤慨的是,他的token传递竟然有Bug(难道还是我使用不 对&_&),从startXX传入的token,到了onXXComplete里面一律变成1,而文档上明明写着两个是一个东西(我的解 决方法是用cookie做token,这个不会丢*_*)。不过我暂时还没有遗弃它的打算,虽然没人理睬,虽然有一堆问题,虽然我按图索骥造了个新轮子, 但为了节省剩下的一些无聊的工作,我决定苟且偷生了。。。
还是习惯性跑题了,其实,我是想通过我对这个类的无数次Debugger跟进,说说它的多线程异步处理的解决策略的。他的基本策略如下:
1. 当你实例化一个AsyncQueryHandler类时(包括其子类...),它会单件构造一个线程(后面会详述...),这个线程里面会构建一个消息循环。
2. 获得该消息循环的指针,用它做参数实例化另一个Handler类,该类为内部类。至此,就有了两个线程,各自有一个Handler来处理消息。
3. 当调用onXXX的时候,在XXX函数内部会将请求封装成一个内部的参数类,将其作为消息的参数,将此消息发送至另一个线程。
4. 在该线程的Handler中,接受该消息,并分析传入的参数,用初始化时传入的ContentResolver进行XXX操作,并返回Cursor或其他返回值。
5. 构造一个消息,将上述返回值以及其他相关内容绑定在该消息上,发送回主线程。
6. 主线程默认的AsyncQueryHandler类的handleMessage方法(可自定义,但由于都是内部类,基本没有意义...)会分析该消息,并转发给对应的onXXXComplete方法。
7. 用户重写的onXXXComplete方法开始工作。
这就是它偷偷摸摸做过的事情,基本还是很好理解的。我唯一好奇的是它的线程管理方式,我猜测他是用的单件模式。第一个 AsyncQueryHandler的实例化会导致创建一个线程,从此该线程成为不死老处男,所有的ContentResolver相关的工作,都由该线 程统一完成。个人觉得这种解决方式很赞。本来这个线程的生命周期就很难估量,并且,当你有一个ContentProvider的请求的时候,判断你会做更 多的类似操作并不过分。就算错了,花费的也只是一个不死的线程(与进程同生死共存亡...),换来的却是简单的生命周期管理和无数次线程生死开销的节约。 同时另外一个很重要的问题,他并会涉及到单件中数据同步的问题,每个类都有各自的Handler类,彼此互不干扰,分发可以分别进行。当多个数据请求的时 候,在同一个ContentResolver上进行的可能微乎其微,这就避免了堵塞。总而言之,这套解决办法和Android的整体设计算是天作之合了。
所以建议,如果你有什么非ContentProvider操作,却需要异步多线程执行的话,模拟一套,是个不错的策略,当然,具体情况具体分析,生搬硬套是学不好马列主义的。。。
发表评论
-
Linux x86 编译 Android 遭遇 gnu/stubs-64.h
2011-08-19 10:43 1858这两天心血来潮,执行完 repo sync 后,顺手来了一下 ... -
使用Cygwin下载Android代码树
2011-03-16 20:45 1578--官方说明-- To set up y ... -
Cygwin在win下下载android源代码
2011-03-16 20:43 1072首先下载cygwin,cygwin是一个类linux平台。即在 ... -
Android NDK 环境搭建 - 安装配置 Cygwin
2011-03-16 20:40 29561. NDK 下载 最新版 Android NDK 开发工具包 ... -
Android-触感反馈和声音反馈的效果实现
2011-03-15 12:07 29451)只有系统设置中打开触感反馈选项,方法performHa ... -
socket的服务端框架
2011-03-07 14:17 2700最近查了不少java下面nio ... -
android UI 优化系列之 创建RGB565的缓存
2011-03-05 16:42 1891关于如何优化activity的 ... -
SocketChannel 和 DatagramChannel
2011-03-05 16:19 1922SocketChannel 叫套接字通道,面向流,就是通 ... -
Android 调试工具集
2011-03-05 13:25 12511.TraceView1)功能:用于热点分析和性 ... -
Android 中文API (33) —— Checkable
2011-03-03 17:45 1110声明 欢迎转载,但请保留文章原始出处:) ... -
Toast 和 Looper
2011-03-03 09:02 1136Toast 和 Looper,一个属于 android.w ... -
Activity 与 Main Loope
2011-03-03 08:59 1024上文抛出了一个疑问:UI 线程是在哪里绑定 Looper ... -
Class loading in Android : Begin with PathClassLoader
2011-03-03 08:56 1175Google 在 Android 文档里的《What is ... -
Linux x86 编译 Android 遭遇 gnu/stubs-64.h
2011-03-03 08:54 1253这两天心血来潮,执行完 repo sync 后,顺手来了一 ... -
读《Multitasking the Android Way》(一)
2011-03-03 08:50 1167Android Developers Blog 发表了一篇 ... -
从 Remote Service Binding 学习 AIDL 与 IPC
2011-03-03 08:47 1550默认情况下,一个应用不管有多少个 Activity、Ser ... -
Android SDK Add-on Configure, Compile and Release
2011-03-03 08:44 1900SDK Add-on 是一个比较小众的话题,一是通常厂商不 ... -
Activity Task 与 Intent Filter Flag
2011-03-03 08:42 1247接触 Android 以来,一直觉得对 task、affi ... -
android的原理,不需要太多的剩余内存
2011-03-02 16:05 924不用在意剩余内存的大 ... -
Android IPC框架分析 Binder,Service,Service manager
2011-03-02 15:19 1375我首先从宏观的角度 ...
相关推荐
TR 36.885 V2.0.0 (2016-05) Study on LTE-based V2X Services.doc
TR 38.885 V1.0.2 (2019-02) NR Study on Vehicle-to-Everything.doc
总的来说,《3GPP TP36885 Study on LTE-based Services》是理解V2X服务在现有LTE网络中实施的关键资源,对于移动通信行业的研究人员、开发者以及政策制定者来说,都是不可或缺的学习材料。通过这份报告,我们可以...
对于像《2008_Study on Searching-retrieving Behaviour in Designers' Ideation Process》这样的研究项目而言,NII 电子图书馆服务能够为其提供必要的文献资料支持,有助于深化对该主题的理解和探讨。 - **未来展望...
【标题】"Study01Android"揭示了这是一个与Android编程学习相关的项目,很可能是初学者入门教程或示例代码集合。在Android开发中,新手通常会通过一系列简单易懂的实例来逐步理解平台的工作原理和编程语法。 【描述...
FortiGate_Infrastructure_7.0_Study_Guide-Online安全基础架构学习手册
FortiGate_Security_7.0_Study_Guide-Online安全学习指南在线
A study on low-refractive-index SiO2 antireflective (AR) coatings by a sol-gel method is reported. Variations in the properties of the coatings are related to the molar ratios of ammonia to deionized ...
【标题】"study-jam-android-2019-文件" 涉及的是一个关于Android开发的学习资源集合,很可能是Google在2019年举办的一次学习活动"Study Jam"的相关材料。"Study Jam"是Google组织的全球性免费编程学习活动,旨在...
304不锈钢在室温和高温下的蠕变-棘轮-疲劳交互作用的实验研究,张娟,康国政,对304不锈钢在室温、100℃和300℃时在单轴非对称应变循环下的蠕变行为、棘轮行为、疲劳失效以及它们之间的交互作用进行了实验研究,
可以使用AsyncTask、Handler、Thread、ExecutorService或现代库如Retrofit、Volley的内置异步机制。 3. 缓存策略: 对于静态资源,可以考虑缓存响应,减少不必要的网络请求。Android提供了`DiskLruCache`或`Cache`...
Experimental study of needle-tissue interaction forces: effect of needle geometries, insertion methods and tissue characteristics. it used to study the needle insertion force and the influence of ...
一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:// 自动将你的构建代码切割成多个包,这些包// 会通过 Aj
FortiGate_Infrastructure_7.0_Study_Guide-Online基础设施研究指南
STUDY ON ANDROID EMULATOR • To understand important details of emulator. • To get familiar with recent upstream changes and possibly ongoing plans. • To evaluate upstream contribution process (for ...
6. **多线程与线程池**:线程用于并发执行任务,线程池则能有效管理多个线程,提高系统效率。 7. **性能优化**:包括内存优化、渲染优化、启动速度优化等,提升应用的整体质量。 8. **单元测试与Mock测试**:JUnit...
We evaluate these models on two different fronts: firstly, we discuss which properties of the original rough set model can be maintained and secondly, we examine how robust they are against both ...
标题中的"1602display-study-study-hard.zip_UP"指的是一个关于1602液晶显示屏学习项目,其中包含了“study study hard!day day up!”的字样,这可能是一个激励学习者的标语或显示示例。这个项目是基于89C52微控制...
Android-Study-Jams-Resources Android Study Jams:通过预先设计的课程和 Google 认证,学习使用 Kotlin 构建 Android 应用程序 主要网站 Android Study Jam 时间表:2020 年 11 月 25 日 - 2021 年 1 月 25 日