第一章Android 体系与架构 底层通过最快的C语言保证效率,上层使用Java简单、快速进行开发。 Android大致分为四层,Linux内核层,库和运行时、Framwork层和应用层。Android的体系架构鼓励系统组件重用,共享组件间的数据,并且定义组件间的访问权限控制。
Linux层。包含了Android系统的核心服务,包括硬件驱动,进程管理、安全系统,等等。 Dalvik与ART。Dalvik包含了一整套的Android运行环境虚拟机。特点是运行时再编译。Android 5.版本开始,ART模式已经取代了Dalvik,ART采用的是安装时进行编译,以后运行时就不用编译了。 Framwork Standard libraries 这里包含的是Android中的一些标准库,标准库,就是在开发者在开源环境中可以使用的开发库。 Application 
1.3.1 Android四大组件如何协同工作 Activity作为人机交互的第一界面,负责向用户展示信息和处理结果,而这些信息的来源,可以是通过资源获取,也可以通过Content Provider来获取其他应用的信息,或是Service从后台计算,下载、处理的结果,当然也可以是通过BroadCastReceiver获取到的广播信息。同时,Android系统还提供了一个信使——Intent,作为信息传递的载体。组件与组件之间通过Intent来通信、传递信息、交换数据、正是通过这样一种方式,四大组件形成了各自独立而又紧密联系的关系,让整个Android系统活了起来。
1.3.2 应用运行上下文对象 Android系统的上下文对象,即在Context中,为我们封装了这样一个语境。Activity,Service,Application都是继承自Context。 1、创建Application  2、创建Activity 3、创建Service 不难发现,创建Context的时机就是在创建Context的实体类的时候。 1、当应用程序第一次启动时,Android系统都会创建一个Application对象,同时创建Application Context,所有的组件都共同拥有这样一个Context对象,这个应用上下文对象贯穿整个应用进程的生命周期,为应用全局提供了功能和环境支持。 2、创建Activity和Service组件时,系统也会给它们提供运行的上下文环境,即创建Activity实例,Service实例的Context对象。
对Makfile的解释:一个像Android这样的大型工程,它的源文件不计其数,不同的功能、模块,按类型分别防止在不同的目录中,这些模块通常会有一个叫Makefile的文件来进行管理,它定义了一系列的规则来指定模块,哪些文件需要编译,以及这些文件该按照怎样的顺序去编译。甚至,它还可以配置跟复杂的功能操作,比如定义编译规则,打包规则等,因为makeFile就像一个shell脚本,不仅可以使用自己的语法,也能调用操作系统的命令。 Makefile最大的好处就是自动化编译,同时还可以做到可控制的编译。Android通过makefile来描述Android各个组件间的联系并指导它们进行自动化编译。
1.4.2 Android系统目录 1、/system/app/ 这里面放的一些系统的App 2、/system/bin/ 这里面主要放的是Linux自带的组件  3、/system/build.prop 这里记录的是系统的属性信息 4、/system/fonts/ 系统字体存放目录root后可下载TTF格式字体替换原字体 5、/system/framework/ 系统的核心文件、框架层  6、/system/lib/ 存放几乎所有的共享库(。so)文件 7、/system/media/ 该目录是用来保存系统提示音,系统铃声。其中system/media/audio/目录,这里面保存着Android系统默认的铃声,alarms目录是闹铃提醒,notification目录是短信和提示音,ringtones目录是来电铃声,而ui目录则是一些界面音效。 8、/system/usr/ 该目录用来保存用户的配置文件,如键盘布局、共享、时区文件等。 9、/data/app/ data目录包含了用户的大部分数据信息,其中,/data/app/这个目录包含了用户安装的App或升级的App。 10、/data/data/ 这个目录应该是开发者访问的最多的目录了,这里包含了App的数据信息,文件信息,数据库信息等,以包名的方式来区分各个应用。 11、/data/system 这个目录包含了手机的各项系统信息  12、/data/misc/ 这个目录保存了大部分的WIFI,VPN信息。
Android studio中的Project就相当于Eclipse里面的Workspace,而Androidstudio中的Module就相当于Ecliose里面的project就可以了。
Android studio 选择editor标签,在other中选择勾选show quick doc on mouse move 选项。
在Editor标签中选择Code Completion选项,在Code Sensitive completion里面选择None,即提示不区分大小写。
Android Build Tools是Android SDK的Build 工具,经常会有更新,建议保持最新,它对应着Gradle中Module下的Build.gradle文件中的buildToolVersion属性。
/system/core/toolbox和\framework\base\cmds 就是我们所有ADB命令和Shell命令的来源了。
Android 控件结构 
ViewGroup控件作为父控件可以包含多个View控件,并管理其包含的View控件。 通过ViewGroup,整个界面上的控件形成了一个树形结构,上层控件负责下层子控件的测量与绘制,并传递交互事件。 通常在Activity中使用findViewbyId()方法,就是在控件树中以树的深度优先遍历来查找对应元素。在每棵控件树的顶部,都有一个ViewParent对象,这就是整棵树的控制核心,所以的交互管理事件都由它来统一调度和分配,从而可以对整个视图进行整体控制。
1、每个Activity都包含一个Window对象,在Android中Window对象通常由PhoneWindow来实现。 2、PhoneWindow将一个DecorView设置为整个应用窗口的根View 3、DecorView作为窗口界面的顶层视图,封装了一些窗口操作的通用方法。换句话说,DecorView将要显示的具体内容呈现了PhoneWindow上。 4、这里所有的View的监听事件,都通过windowManagerService来进行接收,并通过Activity对象来回调响应的onClickListener。显示上,它将屏幕分成两部分,一个是TitileView,一个是ContentView。
第二层装载一个LinearLayout,作为ViewGroup,这一层的布局结构会根据对应的参数设置不同的布局。
在代码中,当程序在onCreate()方法中调用setContentView()方法后,ActivityManagerService会回调onResume()方法,此时系统才会把整个decorView添加到PhoneWindow中。并让其显示出来,从而最终完成界面的绘制。
3.2 View的测量 Android系统给我们提供了一个设计短小精悍却功能强大的类——MeasureSpec类。MeasureSpec是一个32位的Int值,其中高2位为测量的模式,低30位为测量的大小。 测量模式分为三种: 1、EXACTLY。精确值模式 2、AT_MOST。即最大值模式。当控件属性指定为wrap_content时,控件大小一般随着控件的子控件或内容的变化而变化,此时控件的尺寸只要不超过父控件允许的最大尺寸即可。 3、UNSPEIFIED。不指定大小。通常在绘制自定义View时才会使用。
View类默认的onMeasure()方法只支持EXACTLY模式。控件可以响应你指定的具体宽高值或者match_parent属性。 而如果让自定义View支持wrap_content属性,那么就必须重写onMeasure()方法来指定wrap_content时的大小。
3.3 View的绘制  当测量好一个View之后,我们就可以简单地重写onDraw()方法,并在canvas对象上来绘制所需要的图形。 当创建一个Canvas对象时,为什么要传进去一个bitmap对象呢?传进去的bitmap与通过这个bitmap创建的Canvas画布是紧紧联系在一起的,这个过程我们称之为装载画布。这个bitmap用来存储所有绘制在Canvas上的像素信息。 我们可以使用Canvas的绘制API,然后让View重绘,从而显示改变之后的bitmap。
3.4 ViewGroup测量 ViewGroup在测量时通过遍历所有子View,从而调用子View的Measure方法获得每一个子View的测量结果。
3.5ViewGroup的绘制 ViewGroup使用dispatchDraw()方法来绘制其子View,其过程同样是通过遍历所有子View,并调用子View的绘制方法来完成绘制工作。
3.6自定义View 在View中通常有以下一些比较重要的回调方法 1、onFinishInflate(),从xml加载组件后回调  2、onSizeChanged(),组件大小改变时回调 3、onMeasure();回调该方法进行测量 4、onLayout():回调该方法进行测量。 5、onTouchEvent():监听到触摸事件时回调。
通常有以下三种情况来实现自定义的控件 1、对现有控件进行拓展。 2、通过组合来实现新的控件 3、重写View来实现全新的控件 
3.6.1 对现有控件进行拓展 程序调用super.onDraw(canvas)方法来实现原生控件的功能,但是在调用super.onDraw()方法之前和之后,我们都可以实现自己的逻辑,分别在系统绘制文字前后,完成自己的操作。
//在回调父类方法前,实现自己的逻辑,对TextView来说即是在绘制文本内容前 super.onDraw(canvas) //在回调父类方法后,实现自己的逻辑,对TextView来说即是在绘制文本内容后
3.6.2 创建复合控件
3.6.2.1 定义属性 我们在代码中通过标签声明了使用自定义属性,并通过name属性来确定引用的名称。最后,通过标签来声明具体的自定义属性,比如在这里定义标题文字的字体,大小,颜色,并通过format属性来指定属性的类型。 在确定好属性后,就可以创建一个自定义控件——TopBar,并让它继承自ViewGroup,从而组合一些需要的控件。
3.6.2.2组合控件 1、xmlns:android="http://schemas.android.com/apk/res/android" 这行代码就是在指定引用的名字控件xmlns,即xml namespace。这里指定了名字空间为”android“,因此在接下来使用系统属性的时候,才可以用”android:“来引用Android的系统属性。
2、xmlns:custom="http://schemas.android.com/apk/res-auto" 如果要使用自定义的属性,那么就需要创建自己的名字控件,在Android studio中,第三方控件都使用如下代码来引入名字空间。 使用自定义的View与原生的View最大的区别就是在申明控件时,需要指定完整的报名,而在应用自定义的属性时,需要使用自定义的xmlns名字。
3.6.3重写View来实现全新的控件
3.7 自定义ViewGroup ViewGroup存在的目的就是为了对其子View进行管理,为其子View添加显示、响应的规则。自定义ViewGroup通常需要重写onMeasure()方法来对子View进行测量,重写onLayout()方法来确定子View的位置,重写onTouchEvent()方法来增加响应事件。
3.8 事件拦截分析  触摸事件就是捕获触摸屏幕后产生的事件。 当点击一个按钮,通常会产生两个或三个事件。 1、按钮按下,这是事件一 2、如果不小心滑动一点,这就是事件二 3、当手抬起,这是事件三。
我们的触摸事件就是一个,到底该分给谁呢?同一个事件,子View和父ViewGroup都有可能想要进行处理,因此,这产生了事件拦截。
事件的传递顺序是(InterceptTouchEvent): 总经理(MyViewGroupA)->部长(MyViewGroupB)->你(View)。事件传递的时候,先执行dispathchTouchEvent()方法,再执行onInterceptTouchEvent()方法。
事件的处理顺序是: 你(View)->部长(MyViewGroupB)->总经理(MyViewGroupA)。事件处理都是执行onTouchEvent()方法。
事件传递的返回值非常容易理解:true,拦截,不继续;False,不拦截,继续流程。 事件处理的返回也类似:true,处理了,不用审核了;False,给上级处理。
初始情况下,返回值都是false。
第四章 ListView使用技巧 4.1 ListView常用优化技巧  4.1.1 使用ViewHolder模式提高效率 
4.1.2 设置项目间分隔线  android:divider="android:color/darker_gray" android :dividerHeight="10dp"
4.1.3 取消ListView的Item点击效果  android :listSelector =#00000000
4.1.5 设置listView需要显示在第几项  listView.setSelection(N) 实现平移滑动 listview.smoothScrollBy(distance,duration) listview.smoothScrollByOffset(offset) listview.smoothScrollToPosition(index)
4.1.6 动态修改ListView mData.add("new"); mAdapter.notifyDataSetChanged();
4.1.7 遍历ListView中的所有item for(int i=0;i 4.1.8 处理空ListView 当listView列表中无数据时,ListView不会显示任何数据或提示,按照完善用户体验的需求,这里应该给以无数据的提示。listView提高了一个方法:setEmptyView()。
当用户没有做手指抛动的状态时,这个方法只会回调2次,否则会回调3次,差别就是手指抛动这个状态。 通常情况下,我们会在这个方法中通过不同的状态来设置一些标志Flag,来区分不同的滑动状态,供其他方法处理。
4.2.1 具有弹性的ListView listview中有一个控制滑动到边缘的处理方法。overScrollBy方法。里面有一个参数maxOverScrollBy,注释中写道,Number of piexls to overscroll by in either direction along the Y axis 。只要修改这个参数的值,就可以让ListView具有弹性了。
4.2.2 自动显示、隐藏布局的ListView
4.2.3 聊天ListView
4.2.4 动态改变ListView

更多相关文章

  1. Android的按钮监听事件&自定义回调函数
  2. Android入门第十六篇之Style与Theme[转]
  3. android 中发送短信
  4. Android支持HTML标签
  5. [转] Android(安卓)TextView处理HTML标签、显示图片等
  6. Android热补丁技术—dexposed原理简析(手机淘宝采用方案)
  7. [置顶] Android实现数据存储技术集锦
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android关于arm64-v8a,armeabi-v7a,armea
  2. Android(安卓)Timer编写方式深解(貌似使用
  3. 详解Android是如何启动的
  4. Android(安卓)UI开发第三十篇――使用Fra
  5. Content Providers-原文[译]
  6. Android(安卓)9(P) 核心服务和关键进程启
  7. 当复仇者联盟遇上Dagger2、RxJava和Retro
  8. Android(安卓)studio第一次使用配置
  9. Android4.4 及以下TextView,Button等控件
  10. Android中home键和back键区别实例分析