- 浏览: 148084 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
louisliao:
你好请问你有遇到 repo upload 每次都要求输入用户名 ...
碰到的Git/Repo问题及其解决方法 -
viptmd:
谢谢 lz的解释。。受教了,正在搞dmc
开篇:Java Net & DLNA -
chxiaowu:
楼主,可不可以共享代码啊。 看代码才能理解啊
ActiveObject模式的一个java实现 -
aigyoo:
很有兴趣就是不知道怎么做
jUpload字符集设置 -
enlangs:
学习了。。
开篇:Java Net & DLNA
Roman Guy的Android Trick系列文章笔记
- 博客分类:
- Android
Roman Guy是Android Framework的核心开发人员,从2009年开始,他在他的博客上发表多篇如何更好的开发android软件的文章(需要爬墙)。我的笔记的目的是把他这个系列的文章的核心内容总结起来。
第一篇.Faster Screen Orientation Change with Android
由于Android运行在很多个硬件上不同的设备上,并且的它们的硬件配置在运行时是可以的。例如,你推开手机的键盘,那么屏幕就会从portrait切换到landscape。为了让Android应用开发更容易一些,Android OS自动处理了配置的变化并且用新的配置重启了当前的activity。这是一个默认行为。如果你不了解Android如何处理资源,强烈推荐你看官方说明。
最好不要自行处理这些变化,否则不能保证你的代码在以后的更多的设备中运行。
文章介绍了一个很有用的Activity的api: onRetainNonConfigurationInstance(). This method can be used to pass an arbitrary object your future self and Android is smart enough to call this method only when needed.
他给出了两个代码片段:
@Override public Object onRetainNonConfigurationInstance() { final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos]; keepPhotos(list); return list; }
然后在新创建的activity里用getLastNonConfigurationInstance()把你保存的object拿回来:
private void loadPhotos() { final Object data = getLastNonConfigurationInstance(); // The activity is starting for the first time, load the photos from Flickr if (data == null) { mTask = new GetPhotoListTask().execute(mCurrentPage); } else { // The activity was destroyed/created automatically, populate the grid // of photos with the images loaded by the previous activity final LoadedPhoto[] photos = (LoadedPhoto[]) data; for (LoadedPhoto photo : photos) { addPhoto(photo); } } }
最后需要注意的是:
Be very careful with the object you pass through onRetainNonConfigurationChange()
though. If the object you pass is for some reason tied to the Activity/Context, you will leak
all the views and resources of the activity. This means you should
never pass a View, a Drawable, an Adapter, etc. Photostream for instance
extracts the bitmaps from the drawables and pass the bitmaps only, not
the drawables. Finally, remember that onRetainNonConfigurationChange()
should be used only to retain data that is expensive to load. Otherwise, keep it simple and let Android do everything.
也就是说,不要把跟Context/Activity绑定的东西传递过去,这样会导致memory leak。
示例程序有一个有意思的地方是,图片不是水平放置的,我开始以为ImageView什么的可以支持旋转,后来在源码中找了找,发现了如下的一个工具方法:
/** * Rotate specified Bitmap by a random angle. The angle is either negative or positive, * and ranges, in degrees, from 2.5 to 8. After rotation a frame is overlaid on top * of the rotated image. * * This method is not thread safe. * * @param bitmap The Bitmap to rotate and apply a frame onto. * * @return A new Bitmap whose dimension are different from the original bitmap. */ static Bitmap rotateAndFrame(Bitmap bitmap) { final boolean positive = sRandom.nextFloat() >= 0.5f; final float angle = (ROTATION_ANGLE_MIN + sRandom.nextFloat() * ROTATION_ANGLE_EXTRA) * (positive ? 1.0f : -1.0f); final double radAngle = Math.toRadians(angle); final int bitmapWidth = bitmap.getWidth(); final int bitmapHeight = bitmap.getHeight(); final double cosAngle = Math.abs(Math.cos(radAngle)); final double sinAngle = Math.abs(Math.sin(radAngle)); final int strokedWidth = (int) (bitmapWidth + 2 * PHOTO_BORDER_WIDTH); final int strokedHeight = (int) (bitmapHeight + 2 * PHOTO_BORDER_WIDTH); // 宽高都是通过计算放大过的 final int width = (int) (strokedHeight * sinAngle + strokedWidth * cosAngle); final int height = (int) (strokedWidth * sinAngle + strokedHeight * cosAngle); final float x = (width - bitmapWidth) / 2.0f; final float y = (height - bitmapHeight) / 2.0f; final Bitmap decored = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(decored); // 最终的生成一个包含原有图片并且该图片之外的地方都是透明的的图片 canvas.rotate(angle, width / 2.0f, height / 2.0f); canvas.drawBitmap(bitmap, x, y, sPaint); canvas.drawRect(x, y, x + bitmapWidth, y + bitmapHeight, sStrokePaint); return decored; }
这篇文章主要以一个例子来说明Layout使用不当而导致的浪费。
这个例子是以LinearLayout为例的。我们只要对比一下用RelativeLayout代替示例场景中的LinearLayout后,view tree中产生的变化,如图:
很明显,后者节省了一个LinearLayout,如果这个是一个ListView的item的layout的话,那么这个节省就更加可观。
另外他提到:
The layout pass can be especially expensive when you nest several LinearLayout that use the weight parameter, which requires the child to be measured twice.
的确,在LinearLayout的源码中有相应的证明,参看LinearLayout#onMeasure(int widthMeasureSpec, int heightMeasureSpec)部分:如果child view的weight大于0,那么这个child view就会额外onMeasure一次。
总结语:UI是组织结构,配置的改变很容易引起连锁效应,我想Roman也是想告诉人们,要简单化你的UI,包括该文章后面的评论的一个例子:有人说他写了一个很棒的AbsouluteLayout,然后Roman回复说:
I don’t understand why it was so complicated for you to do this. Just a simple FrameLayout with margins would work fine.
所以对于UI乃至任何事情,复杂永远都是要避免的,否则你可能很轻易的被掉到沟里(试想你并不知道LinearLayout会怎么处理weight参数,而你写了一个有复杂LinearLayout嵌套的view,然后你发现你的view怎么这么慢,而你并不知道android正在努力的onMeasure啊)。
我自己的一个例子是,我之前写了一个组件,自定义UI,自己写了一个view,自己onMeasure,自己onLayout,结果后来,另外一个同事接受我的这个组建,然后他直接给改掉了,所有东西都用android自己的。不管效率问题,首先我这段代码在别人看来,是不好的,至少不易理解。如果我有足够的理由和数据来证明我的实现是OK的,那么我可以保证我的代码有更长的生命周期。
3. Android Layout Trick #2: Include to Reuse
Android带来了各种各样的widget(small visual construction blocks you can glue together to present the users with complex and useful interfaces)。尽管application经常需要更高级的可视化组件。一个组件可被看作是由多个简单的既有的wdget组成的复杂widget。譬如你可以重用一个包含一个滚动条和一个button的panel,等等。。
In Android XML layout files, each tag is mapped to an actual class instance (the class is always a subclass of View.) The UI toolkit lets you also use three special tags that are not mapped to a View instance: <requestFocus />, <merge /> and <include />. The latter, <include />, can be used to create pure XML visual components.
在这篇文章的评论处,有人提到使用include的文件和被include的文件之间引用ID的问题,他认为:
问题在于,included的views的id在include它们的文件里是不可见的,这种情况在多个included文件也存在。
Roman答道:
不,它们是可见的。
然后他又问道:
既然如此,那么为什么我引用included views的ID后,在编译的时候会出现:“Unknown resource”。
Roman答道:
IDs的声明和使用必须有正确的顺序。这跟你没有使用include是一样的。如果你要引用included layout里面的ID,那么你要使用@+id或者把把id声明在values/目录内。引用一个included layout外部的id,同样要使用@+id
总之include标签可以让layout得到重用,它的一些细节可以用到的时候再仔细看。
4. Android Layout Tricks #3: Optimize, Part 1
The <merge />
was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees. 文章通过一个示例来解释这个标记的功能。
尽管merge标记很有用,但是它仍然受到一些限制:
a)<merge />只能被用作XML layout的root标记。
b)如果你通过Inflater来创建layout的话,你必须指定一个ViewGroup并且必须设置attachToRoot为true(详见inflate())
发表评论
-
Android客户端数据采集工具包设计
2012-03-06 23:19 7450最近在做一款采集Android应用数据的工具包,类似友盟、fl ... -
[Android游戏开发]基于libgdx的一个简单游戏demo
2012-01-10 14:33 5090最近在利用业余时间自学游戏开发,在看《Begining And ... -
Something about vm gc
2011-10-20 11:06 933It works something like this ... -
图像处理的Dither和Banding
2011-10-12 17:21 13056由于前面的文章涉及到了这两个概念,而我又对图像处理一窍不通,所 ... -
Roman Guy的Android Trick系列文章笔记(三)
2011-10-12 16:08 3267以下所涉及的所有文章都被墙了。。 1.Android ... -
Roman Guy的Android Trick系列文章笔记(二)
2011-10-10 17:43 17315.Speed up your Android UI ... -
Android开发闲言碎语
2011-08-29 10:52 10401. Android,任何app的生命都是短暂的,所以开发ap ... -
Android开发中的一些经验总结
2011-05-11 10:55 5010计划用这篇文章把目前我在Android领域的一些看到的、用到的 ... -
Android Contacts知识学习
2011-05-10 16:17 0最近接受Contacts这一块的工作,在这里把看到的想到的一些 ... -
Multithreading For Performance
2011-03-17 16:48 0... However, a ListView-specifi ... -
Saving data safely
2011-03-16 22:45 1118我们知道,在Android平台中,保存数据有3种方式:loca ... -
一个代码复用实例
2011-03-14 09:43 1127大概看了一下这篇文章: 新浪微博布局学习——妙用TabHost ... -
Source share: SharedPreferencesCompat.java
2011-03-10 09:39 1733Firstly look at the code: /** ... -
New Gingerbread API: StrictMode阅读笔记
2011-03-09 17:14 1143原文:New Gingerbread API: StrictM ... -
Android Memory Leaks
2011-03-08 23:20 1892前一阵子,有一个bug是关于monkey测试到的memory ... -
AndroidUI学习
2011-02-23 22:43 1888没搞过swing,也没丰富经验的j2me ui,ios的ui也 ... -
Android消息处理框架:Looper,Handler,MessageQueue ...
2011-02-23 22:34 2883看过冷冰的Android核心分析第十一篇:Android GW ... -
Android Service Framework分析
2011-02-23 22:14 4538当我在为fetion client工作 ... -
新的开始
2010-11-01 15:54 820要去做android,很高兴。关注这个平台很久,现在终 ...
相关推荐
Trick
Hattrick球场上座率概算 Hattrick球场上座率概算
机器学习中为什么需要 Kernel Trick 以及 Kernel Trick 的证明。
arp_trick.tar.gz
linux shell trick
Python-trick,上传的事pdf文档
神经网络训练Trick,帮助炼丹!!!!
Hat Trick是Unity官方商店提供的5.5.0版本以上的一款游戏Demo。
重修 Slope Trick(看这篇绝对够!).doc
db_trick.sql
NIO trick and trap NIO,编写高性能Java NIO网络框架
zoj 2247 Magic Trick.md
由NASA约翰逊航天中心开发的Trick仿真环境是一个功能强大的仿真开发框架,使用户能够为航天器开发的所有阶段构建应用程序。 特里克(Trick)加快了仿真的创建过程,以进行早期飞行器设计,性能评估,飞行软件开发,...
python_trick_中文版.pdf
java协议的一些trick.pdf
dev分支是Trick插件的主要开发分支。 从dev克隆以创建功能/主题分支是首选方法。 为插件做贡献 插件源代码托管在。 新功能建议和错误修复应作为提交。 在GitHub上克隆存储库,准备对本地存储库的更改,然后提交拉取...
Hattrick Economy (haec) 是一种用于分析和预测 Hattrick 在线足球经理 (www.hattrick.org) 的经济数据的工具。
支持向量机之Kernel Trick.pdf
Hattrick排名是在线游戏Hattrick的CHPP批准的应用程序。 该应用程序允许您创建排名以比较Hattrick团队列表。