《android艺术探索》

Activity、IPC、View、drawable、动画、window、四大组件、消息机制、线程、bitmap、性能优化

Activity

  • 生命周期
    oncreate–onstart–onresume–onpause–onstop–ondestory onrestart
    (对应的阶段是:完整生命周期–可见生命周期–前台生命周期)
    (onSaveInstanceState和onRestoreInstanceState:生命周期异常情况下调用。
    出现异常情况时,onSaveInstanceState来保存状态;Activity重建时onRestoreInstanceState恢复状态
    避免旋转屏幕导致的重建,只需要设置属性android:configChanges)
    (内存不足时,会按照优先级从低到高杀死antivity:前台>可见>后台)
  • 四种启动模式
    设置方法:在AndroidManifest里配置,或者通过标记位设定,方法是intent.addFlags(Intent.xxx)
    standard:(标准模式,默认模式):每次启动都会生成一个新的activity实例,进入所在在的栈(多次进入,那么需要多次返回才能退出)
    singleTop:栈顶复用:如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调onNewIntent(intent)方法。
    singletask:栈内复用:如果新Actity在一个栈中存在。那么就不会重建,并回调onNewIntent方法。如果不存在则创建任务栈并把activity放进去。
    singleinstance:具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。
  • intentfilter匹配规则
    匹配原则:一个intent只有同时匹配某个Activity的intent-filter中的action、category、data才算完全匹配,才能启动该Activity;一个Activity可以有多个 intent-filter,一个 intent只要成功匹配任意一组 intent-filter,就可以启动该Activity。
    Action:要求intent中的action 存在且必须和intent-filter中的其中一个 action相同(区分大小写)。
    category:系统有默认的属性。若有其他category,则要求intent中的category和intent-filter中的所有category 相同。
    data:intent-filter中有定义data,那么Intent中也必须也要定义data。data主要由mimeType(媒体类型)和URI组成。在匹配时通过intent.setDataAndType(Uri data, String type)方法对date进行设置。

附:采用隐式方式启动Activity时,可以用PackageManager的resolveActivity方法或者Intent的resolveActivity方法判断是否有Activity匹配该隐式Intent。

IPC

  • 概念
    进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法。
    进程:一般指一个执行单元,在PC和移动设备上指一个程序或应用。
    线程:CPU调度的最小单元。线程是一种有限的系统资源。
    (一个进程可包含多个线程,即一个应用程序上可以同时执行多个任务。)
    开启多进程的方式
    1、(不常用)通过JNI在native层fork一个新的进程。
    2、(常用)在AndroidMenifest中给四大组件指定属性android:process
    【以“:”开头的进程:属于当前应用的私有进程,其他进程的组件不能和他跑在同一进程中。】
    【完整命名的进程:全局进程,其他应用可以通过ShareUID方式和他跑在用一个进程中。】
    (UID&ShareUID:android系统为每个应用分配一个唯一的UID,具有相同UID的应用才能共享数据。两个应用通过ShareUID跑在同一进程的条件:ShareUID相同且签名也相同。)
    多进程造成的影响
    1、静态变量和单例模式失效、线程同步机制失效、Application多次创建。(原因:由独立的虚拟机造成)
    2、sharedpreferences不可靠。(不支持两个进程同时进行读写操作)
  • 序列化:序列化Serializable和Parcelable的理解和区别
  • IPC
    多进程使用场景
    1、特殊模块需要运行在单独进程中
    2、加大一个应用可使用的内存,通过多进程来获取多份内存空间
    Android的进程架构:每一个Android进程都是独立的,且都由两部分组成,一部分是用户空间,另一部分是内核空间
    Binder机制(一种跨进程通信方式)
    binder作为android主要IPC方式,优点为:
    1、传输效率高、可操作性强:传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。(而对于Binder来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程
    2、实现C/S架构方便:Binder基于C/S 架构 ,Server端与Client端相对独立,稳定性较好。
    3、安全性高:Binder机制为每个进程分配了UID/PID且在Binder通信时会根据UID/PID进行有效性检测。
    Binder框架定义了四个角色:Server,Client,ServiceManager和Binder驱动。
  • 其他IPC方式
    其他六种IPC方式是通过Binder来实现的
    1、Bundle:支持在Activity、Service和Receiver之间通过Intent.putExtra()传递Bundle数据。
    通过Bundle在Android Activity间传递数据
    Bundle实现Parcelable接口,它可方便的在不同的进程中传输。(通过intent或者bundle传递数据,其本质都是通过bundle传递)
    2、文件共享:两个进程通过读/写同一个文件来交换数据。比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。
    适用情况:对数据同步要求不高的进程之间进行通信,并且要妥善处理并发读/写的问题。(SharedPreferences也是文件存储的一种,但不建议采用。因为系统对SharedPreferences的读/写有一定的缓存策略)
    3、AIDL((Android Interface Definition Language,Android接口定义语言):如果在一个进程中要调用另一个进程中对象的方法,可使用AIDL生成可序列化的参数,AIDL会生成一个服务端对象的代理类,通过它客户端实现间接调用服务端对象的方法。
    AIDL的本质是系统提供了一套可快速实现Binder的工具。
    4、Messager:轻量级的IPC方案,通过它可在不同进程中传递Message对象。
    底层实现是AIDL,即对AIDL进行了封装,更便于进行进程间通信。
    5、ContentProvider:Android提供的专门用来进行不同应用间数据共享的方式。
    6、Socket:不仅可跨进程,还可以跨设备通信。
  • Binder连接池
    场景:有多个业务模块都需要AIDL来进行IPC,此时需要为每个模块创建特定的aidl文件,那么相应的Service就会很多。必然会出现系统资源耗费严重、应用过度重量级的问题。
    作用:将每个业务模块的Binder请求统一转发到一个远程Service中去执行,从而避免重复创建Service。
    工作原理:每个业务模块创建自己的AIDL接口并实现此接口,然后向服务端提供自己的唯一标识和其对应的Binder对象。服务端只需要一个Service,服务器提供一个queryBinder接口,它会根据业务模块的特征来返回相应的Binder对像,不同的业务模块拿到所需的Binder对象后就可进行远程方法的调用了。

view

  • view事件体系
    1、位置参数:坐标系
    left、right、top、bottom是view的初始坐标(在绘制完毕后就不会再改变,均是相对于父view。)
    x、y 是view偏移后的坐标,手指触摸屏幕所对应的位置信息。(x=left+translationX,且x、y是相对于父view。)(translationX是偏移量)
    RawX、RawY是手指触摸屏幕所对应的 距离屏幕最左端的位置、最顶端的位置。
    Android应用坐标系统全面详解
    2、触控事件
    MotionEvent:手指触摸屏幕产生的事件:ACTION_DOWN、ACTION_MOVE、ACTION_UP(一般事件指的是手指按下之后,产生一系列的滑动事件,然后离开屏幕的过程。)
    【MotionEvent 对象可以得到触摸事件的x、y坐标。其中通过getX()、getY()可获取相对于当前view左上角的x、y坐标;通过getRawX()、getRawY()可获取相对于手机屏幕左上角的x,y坐标。】
    TouchSlop:系统所能识别的被认为是滑动的最小距离(该常量和设备有关,可用它来判断用户的滑动是否达到阈值,获取方法:ViewConfiguration.get(getContext()).getScaledTouchSlop()。)
    VelocityTracker:速度追踪,用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。
    GestureDetector:手势检测,用于检测用户单击、滑动、长按、双击等行为。
    3、滑动事件
    View滑动1(不平滑):scrollTo/scrollBy。(scrollTo是绝对滑动,scrollBy是相对滑动。scrollBy调用了scrollTo)而且两者这是对view内容滑动,不对本身滑动
    View滑动2(不平滑):通过动画:主要通过改变View的translationX和translationY参数来实现
    View滑动3(平滑):通过改变View的LayoutParams使得View重新布局
    弹性滑动1:Scroller(配合View的computerScroller方法配合使用。)
    弹性滑动2:动画(弹性滑动)
    弹性滑动2:延时策略。handler+view的postdelayed
  • 事件分发
    本质:对点击事件MotionEvent事件分发的过程,系统将这个事件分配到具体的view上。顺序:activity–window–viewgroup–view(Activity、View、Window的理解
    关键的方法:dispatchTouchEvent(分发,boolea类型)–onInterceptTouchEvent(拦截,只在ViewGroup中有)–onTouchEvent(处理)
    事件分发是逐级下发的,目的是将事件传递给具体的View。
    ViewGroup一旦拦截事件,就不往下分发,同时调用onTouchEvent处理事件。
    滑动冲突
    产生原因:一般情况下,在一个界面里存在内外两层可同时滑动的情况时,会出现滑动冲突现象。
    解决办法:从业务上出发,通过内外拦截,以及具体的滑动方向、速度来解决
    外部拦截法:指点击事件都先经过父容器的拦截处理(父控件决定拦截不拦截)【需要重写父容器的onInterceptTouchEvent方法,在内部做出相应的拦截】
    内部拦截法:子容器的拦截处理(子控件决定拦截不拦截)【父View需要重写onInterceptTouchEvent】
  • view工作原理
    view工作流程:meature(测量宽高)–layout(获取四个顶点位置)–draw(绘制到屏幕上)
    viewroot的对应类viewrootImpl调用performTraversals方法,内部分别调用performMeasure–>performLayout–>performDraw,分别完成顶级 View(即decorView)的绘制。
    meature:宽测量值widthMeasureSpec和高测量值heightMeasureSpec决定View的大小(32位int值,高2位代表SpecMode(测量模式),低30位代表SpecSize( 某种测量模式下的规格大小))(单个view通过meature测量,viewgroup测量自身后会通过遍历子元素去测量)
    layout:确定View的最终宽高和四个顶点的位置
    draw:绘制到屏幕(绘制背景–自己–children–装饰)
  • 自定义view
    自定义之 继承view重写onDraw;
    自定义之 继承viewGroup;
    自定义之 继承特定view(如textview)
    自定义之 继承特定的viewGroup(如linearlayout)
    注意:
    让view支持wrap_content、padding
    不在view中使用handler,没有必要
    view中如果有动画或线程,需及时停止。否则会内存泄露
    如果有滑动嵌套,处理好滑动冲突

drawable

  • 概念
    Drawable是一种可在Canvas上进行绘制的对象,即可绘制物。
    主要用途:作为ImageView中的图像显示,作为View的背景
    创建方式:xml(常用)和java
  • 种类
    BitmapDrawable表示一张图片(一般用于作为view的背景)
    NinePatchDrawable(.9图,拉伸压缩后不失真)
    ShapeDrawable(几何图形:圆矩形线条圆环等,一般用于背景)
    StateListDrawable【常用】(Drawable的集合,每个Drawable对应着View的一种状态:比如点击、显示等(可实现淡入淡出效果))(探索Android中selector和shape的结合使用
    ClipDrawable(我们通过setLevel()方法设置其中的Drawable实例展示比例。可用展开画布样式 )
    更多drawableAndroid Drawable完全解析:Drawable子类用法总结
  • 自定义drawable(通常没有必要自定义,因为不能在xml使用)
    Drawable的工作原理的核心是draw()
    创建自定义Drawable,必须重写其draw()、setAlpha()、setColorFilter()、getOpacity()等方法。

动画

如同要点提炼|开发艺术之Animation
动画主要分 view动画、帧动画、属性动画。

  • view动画分为失四种:平移动画、缩放动画、旋转动画和透明度动画。
    (可以分别使用xml或java创建)
    (可以给动画添加过程监听,这样在动画开始、结束和每一次循环时都可在回调方法中监听到。)
    注意:View动画的View移动只是视觉效果,并不能真正的改变view的位置。
    附加1自定义view动画:继承Animation->重写initialize()和applyTransformation()方法:initialize()用于初始化;applyTransformation()用于进行矩阵变换.(实例:自定义补间动画、3D翻转动画)
    附加2:View动画除了可作用在某个View对象上, 还可以用在特殊的场景,例如:控制ViewGroup的子View 的出场效果,还有Activity的切换效果。(Android动画总结——布局动画、转场动画
  • 帧动画
    (可以分别使用xml或java创建)
    本质:按序播放一组预先定义好的图片
    注意:使用祯动画要注意不能使用尺寸过大的图片,否则容易造成OOM( 内存溢出)错误。
    应用场景:较为复杂的个性化动画效果。
    (实例::Android 逐帧动画:关于 逐帧动画 的使用都在这里了!
  • 属性动画
    (在XML / Java代码中设置)
    本质:在一定时间间隔内,通过不断对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在该属性上的动画效果。
    概念:插值器(内置9种):动画变化的规律,趋势。 估值器(内置3种):辅助插值器计算的动画变化的具体的值
    (ValueAnimator实现属性动画,是先改变值,然后手动赋值给对象的属性从而实现动画;是间接对对象属性进行操作;
    ObjectAnimator实现属性动画,是先改变值,然后自动赋值给对象的属性从而实现动画;是直接对对象属性进行操作;)
    附加:自定义插值器和估值器:自定义估值器需要实现 TypeEvaluator接口 & 复写evaluate();
    附加:属性动画主要使用两个接口:AnimatorUpdateListener&AnimatorListener来监听动画的播放过程。
    实例你真的会使用插值器与估值器吗?

附:共享元素曲线动画项目

window

  • 概念
    window是一个抽象类,定义了顶级窗口的样式和行为,其唯一的实现类是PhoneWindow;
    每个Window都对应一个View和一个ViewRootImpl,Window和View通过ViewRootImpl来建立联系。Window并不可见,它实际以View的形式存在,它是View的直接管理者
    实际使用中无法访问Window,对Window的访问必须通过WindowManager,对Window的操作通过它完成。
  • WindowManager的三个重要参数
    flags:表示Window的属性:获得焦点?点击事件?显示等
    type:表示Window的类型:系统window、子window、应用window
    gravity:表示Window的位置。
  • window的机制
    增加修改删除(三个方法主要是定义在ViewManager接口中,接口WindowManager继承了ViewManager,WindowManagerImpl 实现了WindowManager,并通过WindowManagerGlobal进行及的操作)
    【最终都会通过一个IPC过程移交给WindowManagerService。】【Window和View通过ViewRootImpl来联系,ViewRootImpl可控制View的测量、布局和重绘。】
  • Window的创建过程
    View必须依附Window才能呈现出来,因此有View的地方必有Window。在Android中可以提供View的地方有Activity、Dialog和Toast等。
  • 附加
    android界面:Window,PhoneWindow,DecorView,setContentView源码理解。activity–phonewindow–decorview–titleview contentview

四大组件

  • Activity
    概念:展示界面并与用户交互 的组件。
    需要在AndroidManifest中注册。
    需要借助Intent启动:两种启动方式(显式、隐式)、四种启动模式(standard、singletop、singeinstance、singletask)
    Activity的工作过程

  • Service
    概念:计算型组件
    需要在AndroidManifest中注册。
    需要借助Intent启动:通过通过startService()启动,通过bindService()绑定。(通过unBindService()和stopService()完全停止一个Service。)
    Service的工作过程

  • BroadcastReceiver
    概念:消息型组件:在不同的组件乃至不同的应用之间传递消息。
    两种注册方式:动态注册(需注册后才能接受广播)、静态注册(AndroidManifest里注册,无需启动应用即可注册)
    需要借助Intent发送广播
    四种类型:有序、无序、本地、粘性广播。
    BroadcastReceiver的工作过程

  • ContentProvider
    概念:共享型组件:向其他组件乃至其他应用共享数据。
    需要在AndroidManifest中注册,无需intent启动。四种操作:增删查改。需手动停止。(注意处理好线程同步)
    ContentProvider的工作过程

消息机制

  • 作用
    跨线程通信。(主线程进行UI操作,但不能进行耗时操作。子线程执行耗时操作,但不能操作UI。所以需要handler将在子线程耗时处理的结果通知给主线程进行UI操作)
    实际使用:在主线程创建handler,重写handleMessage方法,对不同的message进行处理;在子线程持有handler的引用发送message即可。
  • 要素
    message:待处理的消息,包含了消息的id、待处理的对象等。由MessageQueue统一列队,最终由Handler处理。
    handler:sendMessage:将消息发送到消息队列。handleMessage:处理相应的消息事件
    MessageQueue:消息队列,存放handler发送来的消息,内部由单链表实现,等待looper抽取=
    looper:Looper.loop()不断地从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者。
    ThreadLocal:线程本地存储区,作用是帮助Handler获得当前线程的Looper)
  • 注意
    管Message有public的默认构造方法,但是你应该通过Message.obtain()来从消息池中获得空消息对象,以节省资源。
    如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存
    擅用message.what来标识信息,以便用不同方式处理message。
    无论是主线程还是子线程,Looper只能被创建一次,即一个Thread只有一个Looper。
    (子线程需自己创建looper。参考HandlerThread。)

附:android的消息处理机制(图+源码分析)——Looper,Handler,Message

线程

  • 概念
    cpu调度的最小单元。线程的创建和销毁是需要一定资源的,所以不能无限的产生。(避免频繁的创建线程造成的系统开销?使用线程池缓存一定量的线程来达到效果)
    在android里分为主线程(即UI线程,主要处理界面交互相关)和子线程(主要执行耗时操作)。
  • AsyncTask
    轻量级的异步任务类。底层封装了线程池和Handler,便于执行后台任务以及在主线程中进行UI操作。
    使用:新建类继承AsyncTask,重写方法。其中doInBackground方法是运行在子线程中的,用于处理耗时任务。
    注意:必须在主线程种创建,只能执行一次。
    注意:不适用于进行特别耗时的后台任务,而是建议用线程池
  • HandlerThread
    线程类,继承自Thread。内部有Looper。
    用途:串行异步通信;构造intentService
  • IntentService
    继承自Service的抽象类,内部封装了HandlerThread和Handler
    优势属于服务,优先级比线程高;任务完成后,自动退出。
    使用:继承IntentService,重写onHandleIntent方法;注册服务;在intent中启动。
  • 线程池
    重用线程池中的线程,避免线程的创建与销毁带来的性能损耗;有效控制线程池的最大并发数;进行线程管理。
    线程池的概念来源:Java中的Executor,它是一个接口。
    线程池的真正实现:ThreadPoolExecutor,提供一系列参数来配置线程池。

Bitmap&Cache

Bitmap类主要用于图片处理。(Bitmap(位图):指一张图片,常见格式:.png、.jpg等)

  • Bitmap的高效加载
    为什么要高效加载?直接加载大容量的高清Bitmap很容易出现显示不完整、内存溢出OOM的问题(如报错:
    如何高效加载?计算一定的采样率将图片缩小后再加载进来。(使用BitmapFactory类)
  • 缓存
    常用的缓存算法是LRU(Least Recently Used):最近最少使用算法
    核心思想:当缓存满时, 会优先淘汰那些近期最少使用的缓存对象。
    两种方式:LruCache(内存缓存)、DiskLruCache(磁盘缓存)。
    LruCache:内部采用一个LinkedHashMap以强引用。(LinkedHashMap利用一个双重链接链表来维护所有条目item) 使用方法:计算可用内存,分配LruCache缓存容量,重写sizeof方法,通过put()、get()和remove()实现数据的添加、获取和删除。
    DiskLruCache:与LruCache区别:DiskLruCache非泛型类,不能添加类型,而是采用文件存储,存储和读取通过I/O流处理。
  • imageLoader
    内部封装了Bitmap的高效加载、LruCache和DiskLruCache
    功能:同步加载、异步加载、图片压缩、内存缓存、磁盘缓存、网络拉取
    场景:照片墙效果等
    优化:不在adapter里直接加载图片、网络加载等;列表滑动时停止加载;开启硬件加速等。

性能优化

  • 布局优化
    思想:减少布局文件的层级
    1、(尽量多使用线性布局和相对布局,不使用绝对布局)相同层级使用linearlayout,多嵌套情况下可使用RelativeLayout减少嵌套
    2、使用< include >标签重用布局。
    3、< merge >标签减少层级(通过include引入,自身不占用层级)
    4、< ViewStub >标签懒加载。(ViewStub引入的布局不占用位置,在解析layout布局是节省了CPU和内存)
    附:Android最佳性能实践–布局优化技巧
  • 绘制优化
    思想:避免在View.onDraw()中执行大量的操作。
    1、避免创建新的局部对象。(多次调用ondraw可能会产生大量对象导致占用内存过多,系统频繁gc会降低执行效率)
    2、避免做耗时任务、大量循环等
  • 内存泄漏优化【是造成应用程序OOM的主要原因之一】
    含义:当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏。
    1、静态变量导致的内存泄漏?将内部类设为静态内部类独立出来。
    2、单例模式导致内存泄露(单例传入参数this来自activity,使得持有activity的引用)?传参context.getApplicationContext()
    3、资源未关闭导致的内存泄漏:Activity销毁的时候要及时关闭或者注销
    无限循环的动画要及时停止;
    BraodcastReceiver:调用unregisterReceiver()注销;
    Cursor,Stream、File:调用close()关闭;
    4、adapter:使用缓存的converview
  • 响应速度优化
    思想:避免在主线程中做耗时操作
    方式:使用多线程
  • ListView优化
    提高ListView性能的技巧
    1、减少布局层级;
    2、使用viewholder;
    3、getview不要有太多的对象、不要有太多的逻辑操作;
    4、滑动加载、不滑动不加载图片;
    5、开启硬件加速
    (ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们可以手动将它关闭掉)
  • Bitmap优化
    (通过计算采样率)见bitmap篇。
  • 线程优化
    使用线程池避免大量线程。见线程篇。
  • 其他
    避免创建过多的对象 ;
    不要过多使用枚举,枚举占用的内存空间要比整型大;
    常量请使用static final来修饰;
    使用一些Android特有的数据结构,比如ArrayMap、SparseArray和Pair等,它们都具有更好的性能;
    适当使用软引用和弱引用;
    采用内存缓存和磁盘缓存;
    尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露。

更多:Android开发性能优化总结Android最佳性能实践系列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android的性能优化思想。, 《Android开发艺术探索》侧重于Android知识的体系化和系统工作机制的分析,通过《Android开发艺术探索》的学习可以极大地提高开发者的Android技术水平,从而更加高效地成为高级开发者。而对于高级开发者来说,仍然可以从《Android开发艺术探索》的知识体系中获益。 目录 第1章 Activity的生命周期和启动模式 / 1 1.1 Activity的生命周期全面分析 / 1 1.1.1 典型情况下的生命周期分析 / 2 1.1.2 异常情况下的生命周期分析 / 8 1.2 Activity的启动模式 / 16 1.2.1 Activity的Launch Mode / 16 1.2.2 Activity的Flags / 27 1.3 Intent Filter的匹配规则 / 28 第2章 IPC机制 / 35 2.1 Android IPC简介 / 35 2.2 Android中的多进程模式 / 36 2.2.1 开启多进程模式 / 36 2.2.2 多进程模式的运行机制 / 39 2.3 IPC基础概念介绍 / 42 2.3.1 Serializable接口 / 42 2.3.2 Parcelable接口 / 45 2.3.3 Binder / 47 2.4 Android中的IPC方式 / 61 2.4.1 使用Bundle / 61 2.4.2 使用文件共享 / 62 2.4.3 使用Messenger / 65 2.4.4 使用AIDL / 71 2.4.5 使用 Content Provider / 91 2.4.6 使用Socket / 103 2.5 Binder连接池 / 112 2.6 选用合适的IPC方式 / 121 第3章 View的事件体系 / 122 3.1 View基础知识 / 122 3.1.1 什么是View / 123 3.1.2 View的位置参数 / 123 3.1.3 Motion Event和Touch Slop / 125 3.1.4 VelocityT racker、Gesture Detector和Scroller / 126 3.2 View的滑动 / 129 3.2.1 使用scroll To/scroll By / 129 3.2.2 使用动画 / 131 3.2.3 改变布局参数 / 133 3.2.4 各种滑动方式的对比 / 133 3.3 弹性滑动 / 135 3.3.1 使用Scroller / 136 3.3.2 通过动画 / 138 3.3.3 使用延时策略 / 139 3.4 View的事件分发机制 / 140 3.4.1 点击事件的传递规则 / 140 3.4.2 事件分发的源码解析 / 144 3.5 View的滑动冲突 / 154 3.5.1 常见的滑动冲突场景 / 155 3.5.2 滑动冲突的处理规则 / 156 3.5.3 滑动冲突的解决方式 / 157 第4章 View的工作原理 / 174 4.1 初识View Root和Decor View / 174 4.2 理解Measure Spec / 177 4.2.1 Measure Spec / 177 4.2.2 Measure Spec和Layout Params的对应关系 / 178 4.3 View的工作流程 / 183 4.3.1 measure过程 / 183 4.3.2 layout过程 / 193 4.3.3 draw过程 / 197 4.4 自定义View / 199 4.4.1 自定义View的分类 / 200 4.4.2 自定义View须知 / 201 4.4.3 自定义View示例 / 202 4.4.4 自定义View的思想 / 217 第5章 理解Remote Views / 218 5.1 Remote Views的应用 / 218 5.1.1 Remote Views在通知栏上的应用 / 219 5.1.2 Remote Views在桌面小部件上的应用 / 221 5.1.3 Pending Intent概述 / 228 5.2 Remote Views的内部机制 / 230 5.3 Remote Views的意义 / 239 第6章 Android的Drawable / 243 6.1 Drawable简介 / 243 6.2 Drawable的分类 / 244 6.2.1 Bitmap Drawable / 244 6.2.2 Shape Drawable / 247 6.2.3 Layer Drawable / 251 6.2.4 State List Drawable / 253 6.2.5 Level List Drawable / 255 6.2.6 Transition Drawable / 256 6.2.7 Inset Drawable / 257 6.2.8 Scale Drawable / 258 6.2.9 Clip Drawable / 260 6.3 自定义Drawable / 262 第7章 Android动画深入分析 / 265 7.1 View动画 / 265 7.1.1 View动画的种类 / 265 7.1.2 自定义View动画 / 270 7.1.3 帧动画 / 272 7.2 View动画的特殊使用场景 / 273 7.2.1 LayoutAnimation / 273 7.2.2 Activity的切换效果 / 275 7.3 属性动画 / 276 7.3.1 使用属性动画 / 276 7.3.2 理解插值器和估值器 / 280 7.3.3 属性动画的监听器 / 282 7.3.4 对任意属性做动画 / 282 7.3.5 属性动画的工作原理 / 288 7.4 使用动画的注意事项 / 292 第8章 理解Window和Window Manager / 294 8.1 Window和Window Manager / 294 8.2 Window的内部机制 / 297 8.2.1 Window的添加过程 / 298 8.2.2 Window的删除过程 / 301 8.2.3 Window的更新过程 / 303 8.3 Window的创建过程 / 304 8.3.1 Activity的Window创建过程 / 304 8.3.2 Dialog的Window创建过程 / 308 8.3.3 Toast的Window创建过程 / 311 第9章 四大组件的工作过程 / 316 9.1 四大组件的运行状态 / 316 9.2 Activity的工作过程 / 318 9.3 Service的工作过程 / 336 9.3.1 Service的启动过程 / 336 9.3.2 Service的绑定过程 / 344 9.4 Broadcast Receiver的工作过程 / 352 9.4.1 广播的注册过程 / 353 9.4.2 广播的发送和接收过程 / 356 9.5 Content Provider的工作过程 / 362 第10章 Android的消息机制 / 372 10.1 Android的消息机制概述 / 373 10.2 Android的消息机制分析 / 375 10.2.1 Thread Local的工作原理 / 375 10.2.2 消息队列的工作原理 / 380 10.2.3 Looper的工作原理 / 383 10.2.4 Handler的工作原理 / 385 10.3 主线程的消息循环 / 389 第11章 Android的线程和线程池 / 391 11.1 主线程和子线程 / 392 11.2 Android中的线程形态 / 392 11.2.1 Async Task / 392 11.2.2 Async Task的工作原理 / 395 11.2.3 Handler Thread / 402 11.2.4 Intent Service / 403 11.3 Android中的线程池 / 406 11.3.1 Thread Pool Executor / 407 11.3.2 线程池的分类 / 410 第12章 Bitmap的加载和Cache / 413 12.1 Bitmap的高效加载 / 414 12.2 Android中的缓存策略 / 417 12.2.1 Lru Cache / 418 12.2.2 Disk Lru Cache / 419 12.2.3 Image Loader的实现 / 424 12.3 Image Loader的使用 / 441 12.3.1 照片墙效果 / 441 12.3.2 优化列表的卡顿现象 / 446 第13章 综合技术 / 448 13.1 使用Crash Handler来获取应用的crash信息 / 449 13.2 使用multidex来解决方法数越界 / 455 13.3 Android的动态加载技术 / 463 13.4 反编译初步 / 469 13.4.1 使用dex2jar和jd—gui反编译apk / 470 13.4.2 使用apktool对apk进行二次打包 / 470 第14章 JNI和NDK编程 / 473 14.1 JNI的开发流程 / 474 14.2 NDK的开发流程 / 478 14.3 JNI的数据类型和类型签名 / 484 14.4 JNI调用Java方法的流程 / 486 第15章 Android性能优化 / 489 15.1 Android的性能优化方法 / 490 15.1.1 布局优化 / 490 15.1.2 绘制优化 / 493 15.1.3 内存泄露优化 / 493 15.1.4 响应速度优化和ANR日志分析 / 496 15.1.5 List View和Bitmap优化 / 501 15.1.6 线程优化 / 501 15.1.7 一些性能优化建议 / 501 15.2 内存泄露分析之MAT工具 / 502 15.3 提高程序的可维护性 / 506

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值