Android开发最佳实践


前段时间,Google公布了Android开发最佳实践的一系列课程,涉及到一些平时开发过程中应该保持的良好习惯以及如何使用最新的Android Design Support Library来快速实现官方推荐的Material Design样式的应用。下面是个人的学习摘要总结,不对的地方请多多交流指点,谢谢!
1)注意对隐式Intent的运行时检查保护
类似打开相机,发送图片等隐式Intent,是并不一定能够在所有的Android设备上都正常运行。例如打开相机的隐式Intent,如果系统相机应用被关闭或者不存在相机应用,又或者是相机应用的某些权限被关闭等等情况都可能导致这个隐式的Intent无法正常工作。一旦发生隐式Intent找不到合适的调用组件的情况,系统就会抛出ActivityNotFoundException
的异常,如果我们的应用没有对这个异常做任何处理,那应用就会发生Crash。
预防这个问题的最佳解决方案是在发出这个隐式Intent之前调用resolveActivity
做检查,关于这个API的解释以及用法如下:
android_dev_patterns_implicit_intent

然后这个API的使用范例如下:

Intent intent = new Intent(Intent.ACTION_XXX);
ComponentName componentName = intent.resolveActivity(getPackageManager());
if(componentName != null) { String className = componentName.getClassName();}```

2)使用NotificationCompat兼容包来处理消息通知
为了解决Android系统版本差异导致的Notification兼容性问题,Android官方提供了NotificationCompat
兼容类来帮助开发实现体验统一的Notification。通常来说,建立一个Notification至少会有三种元素:图标,标题,文本。我们通常会使用如下的代码来实现一个基础的Notification功能:
![](http://upload-images.jianshu.io/upload_images/1228374-bab23a2e331e5bba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
上面那段代码,运行时候的效果应该如下所示:
![](http://upload-images.jianshu.io/upload_images/1228374-f07abf60d2525fc3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
为了给上面的Notification添加点击之后的响应效果,我们还需要构造一个PendingIntent
作为contentIntent,例如:

PendingIntent intent = xxx;builder.setContentIntent(intent);```

为了使得Notification更加的具有辨识度,我们还有可能做如下的设置:

android_dev_patterns_notification_set_large

从Android 4.1开始,Notification可以支持展开显示的模式,这样一来,Notification就演变出了下面4种不同的风格样式:

Notification还提供了快捷操作的功能,如下图所示:

除了显示在手机上的Notification,我们还可以给Notification分别设置在Wearable,Auto上的不同表现行为,例如针对可穿戴设备上显示Notification,我们可以如下的设置:

关于更多的Wearable上的Notification相关的知识,还可以参考Pages of ContentStackable Notifications
3)Android 6.0 Marshmallow的运行时权限
Android 6.0开始引入了新的运行时权限检查授权机制,替代了之前安装应用的时候对权限进行授权的方案。为了避免6.0及以上的机器运行发生运行时异常,我们需要做到至少以下5个步骤:
检查系统版本号:针对6.0以下的系统版本,默认权限在安装的时候已经获取到了,对于6.0开始的版本,才需要做运行时的权限检查。
检查申请的权限:在使用某个权限之前,需要检查权限是否已经获取到了。
解释申请的权限:在权限没有获取到的情况下,需要通过shouldShowRequestPermissionRationable()
的判断来决定如何给用户进行提示。
执行申请权限操作:前面判断没有获取到权限,为了能够让功能顺利执行,我们会需要在代码里面再次执行申请此权限的操作。


处理权限申请的结果:申请权限之后,我们需要处理申请的响应结果,分别处理权限申请成功与失败的情况


4)使用MediaSessionCompat操作音乐的播放
MediaSessionCompat来自Android官方的兼容包,通过它可以告诉Android系统与其他的应用,自己正在播放的内容是什么以及自己支持哪些类型的播放控制:

在Android的官方培训课程中有介绍过关于Media Button Receiver的概念,Android系统会把来自蓝牙控制器或者是耳机等其他设备的操作事件转换成Media Button事件传递出来,如果我们的应用程序需要监听这些事件并做出相应的响应,就需要注册MEDIA_BUTTON的action,接收到这些事件之后,再传递给音乐播放模块进行控制处理。

基于上面的认知,我们现在演示如何使用MediaSessionCompat,下面演示了如何构造一个MediaSessionCompat以及构造完之后通常需要做的三件事情:设置合理的flag,设置回调(在5.0开始会响应onPlay,onPause等等回调),设置激活。
android_dev_patterns_media_usage

搭建好了MediaSessionCompat之后,还需要通过MediaMetadataCompat
来传递播放的资料信息,通过PlaybackStateCompat
来传递播放的状态信息。

做了上面那些操作之后,MediaSessionCompat的任务就算是完成了。

5)使用Toolbar替代ActionBar
自从MaterialDesign开始,Android官方就开始使用Toolbar替代了原来的ActionBar,现在Toolbar已经加入Support兼容包。Toolbar是一个相比起ActionBar更加丰富,更加灵活的组件,另外它的布局本身还是View Hierarchy的一部分,这就意味着可以对Toolbar执行动画操作,增加点击滑动事件等等,甚至我们还可以在一个页面里面加入两个Toolbar。
为了启用Toolbar,首先要做的事情就是关闭当前Activity的ActionBar。我们可以通过使得Activity的主题继承Theme.AppCompat.NoActionBar
,然后在对应的XML布局文件中,添加类似下面的toolbar布局信息:

<!--Toolbar-->
<android.support.v7.widget.Toolbar 
android:id="@+id/toolbar_layout" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:layout_alignParentTop="true"
 android:minHeight="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>```

在布局文件中添加Toolbar的信息之后,需要启动Toolbar替代ActionBar,需要像下面一样做设置:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
setSupportActionBar(toolbar);
}```

关于更多Toolbar的细节,请参考官方文档https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
6)使用AppBarLayout并处理滑动手势
AppBarLayout是一个在android.support.design兼容包(这里有关于该兼容包的官方博客介绍http://android-developers.blogspot.com/2015/05/android-design-support-library.html)里面的新推出的组件,它是一个垂直方向的LinearLayout,包装了很多Material Design的设计元素,例如滑动手势的处理。我们可以使用app:layout_scrollFlags
这样的标签来设置滑动的行为表现。关于App Bar,官方还有这样一段描述:


使用AppBarLayout需要注意下面几个要点:
首先,AppBarLayout必须作为CoordinatorLayout
的直接子View
其次,在AppBarLayout里面必须包含一个ToolBar
最后,在CoordinatorLayout里面可以添加那些可以滑动的组件,例如RecyclerView

一个标准的布局文件应该是类似下面结构的:



我们需要注意,在Toolbar里面设置的layout_scrollFlags会影响到滑动之后的显示效果,请看下面的具体解释:


android_dev_patterns_appbar_scroll_flag

7)使用SearchView来实现搜索功能
关于在使用搜索的时候及时显示给用户的候选词,会需要根据数据的类型以及具体的情况做不同的处理,这里先暂时不讨论那一块的内容。

android_dev_patterns_searchview_tips

上面的图示已经清楚的演示了使用SearchView处理搜索的通常情况,关于如何实现这个功能,需要做到以下几个步骤:
在Menu的XML文件中,声明使用SearchView

在onCreateOptionsMenu的回调函数里面获取到SearchView,并设置监听(请注意使用MenuItemCompat的那行代码,否则会出现很多兼容性问题,获取不到这个View等等奇怪的BUG),在监听回调里面处理业务逻辑


至此,其实就已经实现了一个基础的搜索功能。但是,如果为了能够让自己的应用的某些功能被Android系统的Search功能检索到,我们就需要做更进一步的操作,例如定义Searchable,实现一个SearchableActivity,响应系统的Search行为等等。国内的应用很少会去关注这个功能,这里就不展开了,感兴趣点击下面的链接进一步学习:https://developer.android.com/guide/topics/search/index.html
8)Navigation Drawer, DrawerLayout, NavigationView
Navigation Drawer是Material Design当中很重要的一种设计元素,为了能够快速的实现这种设计,Android在新的design support包里面为我们提供了DrawerLayout与NavigationView。

实现这样的一个功能,我们需要在XML中写下类似下面的布局文件

在NavigationView中有两个重要的标签,app:headerLayout与app:menu,分别代表了拉出菜单的顶部布局与下面的菜单项列表。创建菜单项列表,可以使用类似下面的MenuItem文件:

android:checked
表示当前选中的Item,会被系统Highlight出来。除了上面简单的平铺的菜单,还可以使用菜单嵌套的方式实现多级的菜单。关于点击具体某个菜单的时候的监听与响应,需要做如下的设置:

除了点击菜单事件,我们还需要处理整个侧滑菜单的打开与关闭事件,当我们给DrawerLayout设置了setDrawerListener之后,可以得到下面两个回调:

大多数时候,侧滑菜单都是从左到右滑出的,但是我们也可以做到从右往左滑出,只需要在DrawerLayout的菜单布局LinearLayout里面修改一下margin的相关属性即可:

9)Tabs and ViewPager

ViewPager是Android上面实现横向滑动的基础组件,能够帮助大家迅速搭建类似上面图示一样的左右滑动交互设计。ViewPager需要使用PagerAdapter来提供内容,除了PagerAdpater,Android还提供了FragmentPagerAdpater与FragmentStatePagerAdapter,前者会把所有的fragment都保存在内存中,以便提高切换速度,后者仅仅保留了fragment状态信息,fragment还是会进行正常的重建与销毁。一个典型的使用demo代码如下:

为了实现前面图示的Tab与ViewPager的绑定,我们可以使用Android Design Support Library提供的TabLayout
,仅仅需要按照下面的代码示例一样把TabLayout与ViewPager做一个绑定,就能够实现左右滑动与点击Tab快速切换的功能:

关于Material Design里面的Tabs设计,请再参考http://www.google.com/design/spec/components/tabs.html以及官方Training课程里面的http://developer.android.com/training/implementing-navigation/lateral.html
10)Making Apps Accessible
为了照顾部分视力或者听觉不好的用户,我们需要做一定的处理使得自己的应用能够被每一个可用。Android系统为了帮助应用实现辅助功能,提供了诸如文本朗读,触感反馈,指向炳导航,手势导航等等功能来更好的帮助用户使用这些应用。

为了确保你的应用能够被Android系统提供的辅助功能正常使用,需要做以下三个步骤的检查:
Content Description:确保类似ImageView,ImageButton,CheckBox等组件都包含了content descrption。

Focus Order:确保给布局里面的关键元素增加了Focus的指示顺序,只有这样,辅助功能才能够在指向导航的时候帮助用户按照指定的顺序来聚焦界面元素。


Feedback Mechanisms:确保部分关键的操作有多个反馈,例如当短信来的时候,既有声音也有震动,这样才能够确保听力不好的用户可以通过震动的反馈来感知到响应。

更多关于辅助功能的知识,请参考
http://developer.android.com/guide/topics/ui/accessibility/checklist.html

« 转载自:胡凯--Android性能优化典范 »

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容