您的位置:首页 > 移动开发 > Android开发

《Android群英传》学习笔记

2015-12-09 13:01 218 查看
  最近仍在通过看一些书来查缺补漏,全面从入门进阶中级工程师。这篇博客是《Android群英传》的学习笔记,只记录了一些对于我而言有帮助的知识点,如果读者想全面学习的话仍需要自己购买书籍来全面学习。

  1.Android控件架构

  Android控件大致可分为两类,即ViewGroup与View控件。ViewGroup控件作为父控件可以包含多个View控件,并管理其包含的View控件,通过ViewGroup,正业界面上的控件形成了一个树形结构,也就是常说的控件树,上层控件负责下层子空间的测量与绘制,并传递交互事件。Activity中的findViewById()就是在控件树种以树的深度优先遍历来查找对应元素。

  每个Activity对象都包含一个Window对象,Window对象通常由PhoneWindow实现。PhoneWindow将一个DecorView设置为整个应用窗口的根View,所有的View的监听事件,都通过WindowServiceManager来进行接收,并通过Activity来进行回调。在显示上,它将屏幕氛围两部分,一个部分是TitleView,也就是状态栏,另一部分就是ContentView。ContentView是一个ID为Content的FrameLayout,Activity的setContentView()方法就是给这个View设置相应的布局。所以想通过调用requestWindowFeature(Window.FEATURE_NO_TITLE)必须在setContentView()之前调用,否则不生效。AMS在回调Activity的onResume()之后,系统才将整个DecorView放到Window中,并让其显示出来,最终完成整个绘制界面的过程。

  2.View的测量

  Android系统提供了MeasureSpec类测量View,MeasureSpec是一个32位的int值,高2位为测量模式,低32位为测量的大小。(1)EXACTLY模式:精确模式,指定View的大小。(2)AT_MOST模式:最大值模式,属性指定为wrap_content。(3)UNSPECIFIED模式:不指定大小,View想要多大就多大。

  View类默认的onMeasure()方法只支持EXACTLY模式,因此自定义View不重写onMeasure的话,就只能使用EXACTLY模式。重写onMeasure之后,最重要调用setMeasuredMimension()方法。

  3.ViewGroup的测量

  ViewGroup在测量时通过遍历所有的子View,从而调用子View的Measure方法来获得每个子View的测量结果。子View测量完毕之后,就需要将子View放到合适的位置。ViewGroup在Layout过程时,同样是使用遍历来调用子View的Layout方法,指定其显示位置,从而决定布局的位置。

  4.自定义View

  在自定义View时,通常会去重写OnDraw()方法啦绘制View的显示内容,如果自定义View使用wrap_content属性,还需要重写onMeasure()方法。

  View中重要的回调方法:(1)onFinishInflate():从XML加载组件后回调。(2)onSizeChanged():组件大小改变时回调。(3)onMeasure():回调该方法来进行测量。(4)onLayout():回调该方法来确定显示的位置。(5)onTouchEvent():监听到触摸事件时回调。

  在布局XML文件中需要制定引用第三方控件的命名空间,如xmlns:android=“http://schemas.android.com/apk/res/android”.这行代码就是制定引用的命名空间是xmlns,这里指定了命名空间为”android”,因此在接下来的系统属性的时候才可以使用”android:”来引用Android系统属性。在使用自定义属性时,就要创建自己的命名空间。在AS中,第三方控件的命名空间都是:xmlns=custom=“http://schemas.android.com/apk/res-auto”。

  5.事件分发

  Android的事件分发机制不是三言两语能够说清楚的,这里只做一些总结性的描述。Android的事件分发机制是从最外层的ViewGroup逐步往下传递的。ViewGroup比View多了一个onInterceptTouchEvent()方法,此方法决定是否往ViewGroup的子View传递事件,默认是传递的。如果传递,在dispatchTouchEven中调用onInterceptTouchEven,如果传递,则通过深度遍历的方式调用子View的dispatchTouchEven,然后子View的onTouchEven()方法处理,若消耗传递事件则返回true,否则返回false。如果返回false,再逐层往上调用父View的onTouchEven()方法。如果返回true,那么事件传递到此View为止,不再传递,不再调用父View的onTouchEven()方法。

  View的onTouch事件先于onTouchEven回调。Activity的onTouchEven在当没有任何一个View消耗onTouchEven事件时回调。

  6.ListView优化

  (1)复用convertView,避免每次都inflate一个新的view

  (2)使用ViewHolder,避免每次都findViewById(),提高效率

  (3)异步加载图片,滚动时不加载,停止时才加载。

  (4)尽量让itemView层次简单,避免复杂嵌套。

  可以通过onScroolListener来判断ListView的滑动状态。

  7.startService和bindService

  执行startService时,Service会经历onCreate->onStartCommand。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再起来仍然可以stopService。

  执行bindService时,Service会经历onCreate->onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。

  多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。

  第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息