【转】对Android开发者有益的40条优化建议

下面是开始Android编程的好方法:java

  •  找一些与你想作事情相似的代码
  •  调整它,尝试让它作你像作的事情
  •  经历问题
  •  使用StackOverflow解决问题

  对每一个你像添加的特征重复上述过程。这种方法可以激励你,由于你在保持不断迭代,不经意中你学到了不少。然而,当你发布应用时你还要作一些更深刻的事情。android

  从一些可正常工做的代码到一个可怕的应用程序是一个巨大的跳跃,相比iOS平台Android更是如此 。当在iOS上发布应用时只是在一个设备上跳跃–你的手机–对不少设备而言都很类似–一样大小的屏幕,都有很好的硬件,95%上运行相同版本的操做系统。在Android应用中你不会遇到这种状况。web

  你的程序必须可以处理一切:从屏幕,处理器,定制的操做系统,API层级以及任何其余的特定设备。编程

  这是我对使Android应用舒服起来的我的建议。api

 目标屏幕尺寸及解决方法

  在Android世界里目前有超过100种的不一样屏幕尺寸,但解决方法也很丰富。为使你的应用适应不一样的屏幕配置有两件事情你须要肯定:网络

  1. 你对不一样的屏幕尺寸有一个好的布局和结构
  2. 你的图像在不一样分辨率下工做良好

  这些都是独立的任务,你可能有一个超级的tablet布局,但上面的图形看起来很糟糕。咱们会依次讨论他们。app

 为不一样的屏幕而设计

  1.一般会用ScrollView 和 ListView 轻松搞定

  当咱们有一系列不一样尺寸的大屏手机时,它们之间最大的不一样就是屏幕的高度。所以ScrollView和ListView一般但是有效的工做,虽然有时它们并不能彻底覆盖所有屏幕。在OpenSignal中的Dashboard标签下咱们能够看到全部部件一鼓作气,不存在滑动、对于许多高级类型标签中,滑动展现并不见得是一件坏事。若是你可以为你全部的设计匹配到各类屏幕上面去,那么最好不过。不然,这两个控件会让你用最小的开发代价来保证你的软件在大多数屏幕上正常展现。编辑器

opensignal_dashboard1

  Dashboard style 的设计不须要scroll

  2: 使用文件夹. Android 的资源文件夹结构很是强大, 它容许开发者将不一样的图片、字符串、布局文件、外形、颜色这些资源,在api、代码、屏幕尺寸等部分. 下面是一个例子,展现了在资源文件夹下你能够怎样作:ide

Screen Shot 2013-07-29 at 10.32.18

  在 values-small 文件夹中存放了一个 bools.xml 文件, 文件中有以下几行代码:工具

123 <resources><bool name="small_screen">true</bool></resources>

  在代码中我可这样引用:

123 if(getResources().getBoolean(R.bool.small_screen)){getSupportActionBar().hide();}

  在小尺寸设备中boolean值将置为true 我此时将所以ActionBar来节省空间. 这段代码正是非凡的ActionBarSherlock 扩展库中的一部分,稍后再详细介绍. 在values-sw360dp文件夹中,存放对应屏幕宽于360dp的资源文件。与上面相同的位置,有以下代码

123 <resources><bool name="small_screen">false</bool></resources>

  对于大屏幕而言,ActionBar就置为了显示状态.

  我不须要将 bools.xml 文件放入 values-sw400dp文件夹中, 由于操做系统会自动按相应路径搜索. 例如一个设备宽 600dp (600/160=3.75 英寸, 这就是咱们一般所说的7片装) 操做系统会在values-sw600dp 和其包含的的文件夹中搜索 bools.xml 文件, 若没有找到则搜索 values-sw400dp 文件夹,在搜索 values-sw360dp 文件夹以此类推.

  建议3:160dp = 1英寸。320 dp = 2英寸。dp = dip

  建议4:你能够用这些目录结构技巧来应付全部资源类型,好比你的XML布局用指定的系统目录名称

  来解决这个问题,如:layout-sw360dp目录能够匹配目标宽是360dp的机器。若是你也要支持横竖屏布局切换的话,能够用以下目录:

  layout-sw360dp-land

  layout-sw360dp-port

  别急,你有一半的用户是说阿拉伯语的?那就将布局名称改成下面的样子吧:

  layout-sw360dp-land

  layout-sw360dp-port

  layout-sw360dp-land-ar

  layout-sw360dp-port-ar

  前两个能够适用于全部语言,-ar表明阿拉伯语。

  建议5:资源规则简介:

  XXX //例子:没有添加目录名:默认-适用于Nexus One,Droid 2,S2

  XXX-sw360dp // 比较大的手机 – Galaxy Nexus, S3, S4

  XXX-sw600dp // 7〃 平板

  XXX-sw720dp // 10” 平板

  在Kindle设备有些不一样,以下:

  XXX-large-mdpi // kindle fire 7〃

  XXX-large-hdpi // kindle fire 7〃 HD

  建议6:若是你不想裁剪全部的布局文件,你能够用dimens.xml文件。你要是留心我上面的文章,你就会注意到在个人values目录里有不少dimens.xml,这样是由于我更喜欢在一个layout.xml里设置值,在每个布局文件里我喜欢这样作:

12345678910111213 <ImageViewandroid:layout_centerHorizontal="true"android:layout_marginTop="@dimen/small_margin"android:layout_width="@dimen/dashBoardWidth"android:layout_height="@dimen/dashBoardHeight"android:id="@+id/dashboard"/> small_margin是在dimen.xml文件里定义的: <resources> <dimen name="small_margin">4dp</dimen></resources>

  这个4dp变量在全部dimen文件里。我有个Excel文件,里面建立了全部不一样的基于不一样因素所需的尺寸定义。也许你会问:为何不让android OS来处理全部尺寸的问题?为何不呢,为何不用一个values目录和一个布局目录来代替全部写死的数值呢?那固然是能够的,若是设置得当,都会获得全部的尺寸,可是对于有些元素看起来就不是那么好计算尺寸了。

  建议7:让空白空间大于图像空间。让图像空间大于按钮的大小。若是将按钮,多选框,切换控件放大后是很丑陋的。一个100dip(0.63")大小的按钮是不想在平板上显示为原来两倍宽度200dip(1.25")的.缘由是屏幕变大了,这不是说平板是给巨人用的。咱们能够这样作,在按钮增长的空间和图片扩展的空间里添加空白。

  建议8:用GraphicalLayout工具快速预览。GraphicalLayout是WYSIWG XML编辑器。我喜欢直接编写元素-而不是拖,丢弃的可见编程方式,但在添加一些元素以后,能够在GraphicalLayout的下拉选择菜单里选择不一样屏幕尺寸进行测试。

 

  这里有不少选项供你选择。

 图片缩放

  建议9:不要把全部的图片都缩放了。用布局文件来适应不一样屏幕尺寸的方法只是成功的一半,布局里的元素(如:图片)也要能在高分辨率的屏幕下良好工做。在概念上比较简单的方式就是建立一套完整的图片目录并将它们与不少drawable目录匹配起来。

  drawable-sw600dp-ldpi
  drawable-sw600dp-mdpi
  drawable-sw600dp-hdpi
  drawable-sw600dp-xhdpi
  drawable-sw600dp-xxhdpi
  ...其它的相似。

  不要这样作:

  你不要太尽信书了。

  通常来讲有drawble-ldpi, drawable-hdpi等目录就足够了,不须要将全部的状况都加上。

  建议10:避免使用位图(jpg,png)。对于一些图标来讲,用位图是个不错的选择,由于它们使用简单。可是若是能够避免使用位图,你能够节省不少空间。但用不一样的方法也能够达到很好的结果。

  建议11:用XML绘图。位图均可以用XML绘图来代替的。XML绘图不是万能的,可是它的方便性仍是使我感到惊讶。Android开发文档中有详细的介绍,这里有个简单的例子:

1234567891011121314151617 <shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle" ><cornersandroid:bottomRightRadius="14dp"android:bottomLeftRadius="14dp"android:topLeftRadius="14dp"android:topRightRadius="14dp"/><gradientandroid:startColor="@color/off_white"android:endColor="@color/pale_yellow"android:angle="270"android:type="linear"/><strokeandroid:width="4dp"android:color="@color/osm_darkerblue"/></shape>

  这里是定义了一个圆角矩形,一个有渐变的边(深蓝)。你能够在布局文件的任何地方来引用,并且它能够适应于任何屏幕。用它能够作出理想的按钮。

  建议12:用更多的XML绘图。再来介绍一个用XML绘图制做出能更加让你兴奋的例子,下面的雷达背景看起来是否是更加的复杂:

  不用位图对你的UI是没有坏处的(除过图标)。

  建议13:仍然用更多的XML绘图(若是必须,就用位图)。那咱们怎样为天气信号构建一个超酷的图标-让灯泡动态的依据光的强度来进行自动填充,以及怎么点击指针后让其旋转呢?这里咱们用位图和XML结合起来作个例子:

  灯泡咱们用PNG图:icon_magnitude_min(一个空的灯泡)和icon_magnitude_max(充满光的灯泡),而后咱们动态的裁剪后者。为了实现这个目标我是这样作的:

123456789101112 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:drawable="@drawable/icon_magnitude_min"/><item ><clipandroid:clipOrientation="vertical"android:drawable="@drawable/icon_magnitude_max"android:gravity="top"/></item></layer-list>

  在java程序中我将获得回形针的引用,而后能够用它来控制光的强度。

  建议14: 为何要用9-patch (当你能够用XML drawables的时候)? Android具备使用9-patches 来定义drawables的选择,有些教程阐述了怎样用它们来作一个按钮,这样能够在伸展的时候保持几个角不变 (而且避免了像素处理)。若是你已经知道怎样使用9-patches,多是从web设计中学会的,那么它们或许值得一用。若是你对9-patches并不熟悉,我建议你维持原样。若是你想适应什么东西——例如拐角的圆弧或者颜色,建立9个小块要比建立位图更多被涉及,这就像回到了图像编辑器的时代。许多用9-patches得到的效果也能够经过XML得到。

 建议15: 经过覆盖onDraw()建立自定义views. 有些事情XML并不十分在行,咱们在OpenSignal和WeatherSignal中画过许多图像,为此有许多的库,可是咱们要为自定义图像本身编写代码。这颇有趣。或许你永远也不须要作这个,但为了使图像高度动态并自定义,这常常是惟一可行的办法。

  建议16:在不能使用XML的地方使用SVG. 有时候覆盖onDraw()并勤勤恳恳的为自定义view编写代码画出须要的线条与弧线是过于技术化了。毕竟有一种矢量图像语言,它称做…Scalable Vector Graphics(可扩展矢量图形)。它也是史上最酷的Android应用之一—Androidify的动力来源。事实上他们建立这个库就是为了那款应用,他们将它发布在这里:SVG for Android  。这也就是咱们在OpenSignal中画仪表盘所用到的。

  建议17: 对SVG文件GZip压缩. 将它们变得更小它们就会处理的更快。

  建议18: SVG库并非支持一切. 在一些特定的alpha通道中彷佛不能正常工做,你甚至不得不在代码中将它们剔除。

 达到在android全部版本里表示展示一致的目标

  建议19:在一些android系统里(如TouchWhizz/HTC Sense/MotoBlur等等),默认的buttons和其余UI组件会跟原生系统里的看起来差异很大。我但愿这不是真的,但事实倒是如此。

  建议20:自定义你的UI组件。为了肯定你的app在全部的设备里看起来是一致的,你将须要自定义全部的东西。这其实没有你想象中那么难,只要你作到了,你将能更加好地把握到你的app的展现外观。

  建议21:Selectors是建立buttons的利器。咱们在上面提到了如何在XML里定义button的背景,可是你将如何建立一个当按下去会改变的button呢?很简单:像下面那样在xml文件里定义背景。该xml文件将接收到button当前状态而且在外观上作出相应的改变。

123456 <?xml version="1.0" encoding="utf-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:state_pressed="true" android:drawable="@drawable/btn_bg_selected" /><item android:state_focused="true" android:drawable="@drawable/btn_bg" /><itemandroid:drawable="@drawable/btn_bg" /> <!-- default --></selector>

  建议22:在Honeycomb以前的版本里时不存在ActionBar跟不少 animation  样式的,因此可使用ActionBarSherlock 跟NineOldAndroids来代替。Jake Wharton写的Android开源 组件都是往下兼容的精心杰做。更为惊喜的是,ABS 拥有强大的功能用来定义ActionBar。

  把速度做为目标

  建议23:在运行慢的手机上测试。你将在运行慢的手机上发现不少问题,同时它让你抓狂,没人会喜欢运行慢的程序。

  建议24:尽可能减小XML布局层次。更多的层次意味着系统将为解析你的代码付出更多的工做,这将会让图像渲染的更慢。

  建议25:用Android Lint。在工程目录上右键选择Eclipse>Android Tools>Run Lint。它将会获得程序的一些信息,并能提升程序的运行速度,或者它能让你得代码更加清爽。

  建议26:Android Lint能够获得错误信息。它能够给你的代码提供很详细的信息,并在你出错以前就能够给作出提示。

  建议27:用<merge>能够帮助你减小视图层次结构。这是一种简单的方式来去除多余的层次。好的文章都对此有所解释,并且在 Android Developer中它也显得不同凡响。

  建议28:用HierarchyViewer能够直观的看到你布局的层次。这个智能的工具能够显示布局中有多少层次,并且能够提示出那些可让程序变慢。

  建议29:若是能够尽可能用RelativeLayoutAbsoluteLayout已通过期了,就不要用了。你常常会遇到在RelativeLayout和LinearLayout中作出选择的状况,那就直接用RelativeLayouot吧,由于它可让你减小视图层次。好比,你想实现一个以下视图:

  盒子 A 在屏幕左半边 |盒子 B在屏幕右半边

  你首先会想到这么作:

12345678910111213141516171819202122232425262728293031323334353637383940414243 <LinearLayoutandroid:layout_width=”match_parent”android:layout_height=”wrap_content”android:orientation=”horizontal”><TextViewandroid:text=”Box A takes up left half of the screen”android:layout_width=”0dip”android:layout_height=”wrap_content”android:layout_weight=”1″/><TextViewandroid:text=”Box B takes up left half of the screen”android:layout_width=”0dip”android:layout_height=”wrap_content”android:layout_weight=”1″/></LinearLayout>That works just fine, but you could also use:<RelativeLayoutandroid:layout_width=”match_parent”android:layout_height=”wrap_content”android:orientation=”horizontal”><TextViewandroid:text=”Box A takes up left half of the screen”android:layout_width=”match_parent”android:layout_height=”wrap_content”android:layout_toLeftOf=”@+id/dummy_center”/><Viewandroid:id=”@+id/dummy_center”android:layout_width=”0dip”android:layout_height=”0dip”android:layout_gravity=”center”/><TextViewandroid:text=”Box B takes up left half of the screen”android:layout_width=”match_parent”android:layout_height=”wrap_content”android:layout_toRightOf=”@+id/dummy_center”/></RelativeLayout>

  第二个表单比第一个难看的多,事实上是至关的糟糕:咱们已经介绍过一个完整的新元素了。可是假如咱们要给每一个盒子里加入一个图片,通常的咱们将这样作:

  盒子 A 在屏幕左半边 图片|盒子 B在屏幕右半边 图片

  用第一中方法,你得建立一个有两个层次的LinearLayout,若是用第二种方法,你能够直接在同一个RelativeLayout中加入图片,好比要指定第一个图片必须在“dummy_center”的左边,并且一个TextView A必须也在其左侧。那么你就得用7个元素3个视图层次了(LinearLayout 方式),而(RelativeLayout方式)只用6个元素2个层次,这样全部的工做添加完成。

  建议30:用一些扩展工具如DDMS。这能够帮助你发现一些没必要要的网络调用、查看电池使用量、垃圾回收信息,状态变化(例子:当回调onStop和onDestroy时)等。LittleEye是我目前比较喜欢的工具。

  建议31:用AsyncTasks。Anroid工程团队受够了人们常常在UI线程里面实现网络调用(译注:耗时操做,容易阻塞UI刷新),因此他们实现了一些可产生编译级错误信息的API。可是仍然在不少app中的一些工做会拖垮UI线程,咱们要考虑到UI布局要快以及提升UI的响应性。

  目标机器空间小

  建议32:一些Aandroid设备有100mb空间大小的限制。如今状况已有变化了,可是仍然有不少用户还会担忧5Mb大小的app会浪费空间。若是你能够选择将app装入SD卡的话,这就不是问题了,但若是你的app须要在onBoot里启动的话你就不能装入SD卡了(例子:如一些窗体小部件).甚至对于一些新的设备,若是能很快的下载一个小的APK的话,用户仍是很高兴的。

  建议33:用XML资源(我发誓上次我已经提醒过了),这将比PNG资源节省不少空间,当你仅仅须要一个能够知足不少屏幕大小的配置时,一个XML文件会比能实现一样功能的PNG省空间。

  建议34:若是要用PNG,最好优化一下(用PNGCrush或ImageOptim)
 

  目标bugs

  建议35:在Android开发者控制台里检查全部被自动检测出来的bugs. 

  建议36: ProGuard如今是默认启动着的. Proguard太好用了 (提升你app的速度和下降文件大小),但这也让StackTraces 很是难以处理。你将须要从新追踪你的StackTraces,所以你将须要继续保留在每次构建中建立的Proguard的映射文件。我把它们都放到以代码版本号命名的文件夹里。

  建议37: 为了显示StackTraces里的行数,你须要修改ProGuard的配置。确认你的proguard.cfg拥有下面这句话:
-keepattributes SourceFile,LineNumberTable

  建议38:使用staged rollouts。测试5%的基础用户,而且观察bug报告。

  建议39:使用真实设备测试平台。Device Anywhere and Perfecto Mobile提供了虚拟测试平台,在那里,你可使用真正的移动设备。我发现他们有一些笨拙,加入接二连三地进行测试的话,会致使有一些糟糕的状况。若是你在联合办公的环境里工做,或者有一些Android开发的好友,那么去启动一个“设备池”吧。

  建议40: 多写代码少写博客。其实不是的, 分享就是关爱, 我只是想不出第40条写什么是了。

相关文章
相关标签/搜索