Giter VIP home page Giter VIP logo

blog's People

Contributors

zhangsr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

genglei-cuan

blog's Issues

Android IPC 机制

各种 IPC 方式的优缺点和适用场景(参考《Andoid开发艺术探索》,并按自己的理解做了改动)

名称 优点 缺点 适用场景 实例
Bundle 简单易用 只能传输 Bundle 支持的数据类型 Activity、Service、Broadcast 之间单向单次的进程间通信 传参启动 Activity
文件共享 简单易用 (1)不适合高并发场景(2)不适合即时通信 (1)无并发访问(2)不要求实时 SharedPreference
AIDL (1)支持一对多并发通信(2)实时通信 (1)使用稍复杂(2)需要处理好线程同步 (1)一对多双向并发通信(2)有RPC需求 音乐播放器
Messenger (1)支持一对多串行通信(2)实时通信 (1)低并发(2)不支持RPC(3)只能传输 Bundle 支持的数据类型 (1)一对多双向低并发通信(2)无RPC或无需返回的RPC
ContentProvider 标准数据共享接口 提供数据共享,包括CRUD操作 通讯录信息
Socket 网络传输 实现繁琐 网络传输 聊天室

其中 AIDL、Messenger、ContentProvider 都是基于 Binder

简化的 Binder 应用层原理图:

调用过程解析

非 IPC:

(1)Client 调用 Stub 接口的方法 A
(2)直接由
(3)Service 中该接口的实现响应。
(4)直接由
(5)Client 方法 A 返回

IPC:

(1)Client 调用 Stub 接口的方法 A
(2)在 Client 端,由 Stub 的内部类 Proxy 响应,并将方法id 和参数序列化,通过 transact 方法传到底层,Client 端线程阻塞。在 Service 端,系统(线程池)回调onTransact 方法,反序列化,并调用不同的 Stub 接口方法。
(3)Service 中该接口的实现响应。
(4)onTransact 方法得到结果并序列化,返回 true 标记成功,transact 方法线程阻塞解除,得到结果并反序列化,返回结果。
(5)Client 方法 A 返回

可以看出来非IPC 与 IPC 的区别只有第(2)(4)步,而这一步的代码是通过 .aidl 文件生成的,也就是系统屏蔽了进程间通信的具体实现,只暴露给开发者(1)(3)(5)三步,使得在开发者的眼里,IPC 就好像在同一个进程中一样,实现起来非常简单。

Android View 绘制流程

主要绘制流程如下:

measure、layout、draw的遍历如下:

measure 过程

measure() onMeasure()
SomeView 不重写,用View的默认实现 重写,用自己特定的计算方式
SomeViewGroup 不重写,用View的默认实现 重写,用自己特定的计算方式

View的measure()默认实现做了一些缓存检查之类的工作,最终还是调用了onMeasure(),下面展示onMeasure()做了什么:

onMeasure()
SomeView (1)测量实际内容(2)setMeasured()设置自己的值
SomeViewGroup (1)读取子View的layout_*,结合自己的measuredSpec生成子View的measuredSpec(2)调用子View onMeasure()(3)获取子View测量值(4)setMeasured()设置自己的值

View大小的控制是由父View、layout.xml文件、以及View本身共同完成的,父View会提供给子View参考的大小,而开发人员可以在layout.xml文件中指定View的大小,然后View本身会对最终的大小进行拍板

measure 过程的结果:所有的View、ViewGroup都调用setMeasured()设置了自己的宽高,以备 layout 过程使用。

layout 过程

layout() onLayout()
SomeView 可重写,也可用View的默认实现 不重写,View的为空实现
SomeViewGroup 不重写,用View的默认实现 重写,用自己特定的布局方式布局子View

无论是View还是ViewGroup,layout()都可以使用View的默认方式:

  1. 设置左上右下坐标
  2. 判断有无change
  3. 有的话调用onLayout()

layout 过程的结果:设置好View、ViewGroup的左上右下坐标

draw 过程

draw() onDraw()
SomeView 不重写,用View的默认实现 重写,View的为空实现
SomeViewGroup 不重写,用View的默认实现 �不重写,�无内容绘制

onDraw()原理简单,自定义View需要重点实现,以绘制出想要的内容。

draw()虽都不重写,但很重要,View的默认实现已经把所有步骤都做好了:

  1. drawBg(canvas)
  2. onDraw(canvas)
  3. dispatchDraw(canvas)
  4. onDrawScrollBars(canvas)

ViewGroup已经重写了dispatchDraw方法,实现了遍历子View绘制,所以一般自定义ViewGroup时不需要重写

以上四个步骤按序调用,完成了所有绘制。

draw 过程的结果:将图像绘制到 Canvas 上。

参考

http://blog.csdn.net/yanbober/article/details/46128379
http://blog.csdn.net/guolin_blog/article/details/16330267
http://developer.android.com/intl/zh-cn/guide/topics/ui/how-android-draws.html
http://blog.csdn.net/luoshengyang/article/details/8372924
http://www.codekk.com/blogs/detail/54cfab086c4761e5001b253f

Android View 自定义

继承 View

主要:重写 onDraw() 控制绘制的内容
其它:

  • 重写 onMeasure() 使 wrap_content 有效
  • 在 draw 时算入 padding
  • 自定义属性
  • 实现 onTouchEvent() 的交互

继承 ViewGroup

主要:实现 measure() layout() 过程
其它:

  • 解决滑动冲突
  • 实现 onTouchEvent() 的交互

Android Event 事件传递机制

原理流程图:

dispatchTouchEvent() 负责如何传递触摸事件
  • 包括传递给onTouch() 还是 onTouchEvent()
  • 标记DOWN的后续事件传递给哪个View
onInterceptTouchEvent() 负责如何拦截触摸事件
  • 判断是否已经detach并拦截
  • 判断是否开始滑动并拦截
onTouchEvent() 负责如何处理触摸事件
  • 获取焦点
  • 设置按下状态
  • 调用onClick()

自定义View

dispatchTouchEvent() onInterceptTouchEvent() onTouchEvent()
SomeView 不重写,用View的默认实现 重写
SomeViewGroup 一般不重写,用ViewGroup的默认实现 重写,默认返回false (1)不重写,用View的默认实现如LinearLayout;(2)重写,如ListView

常见问题

onTouch() vs onTouchEvent()
  • 两者都用以处理触摸事件
  • 前者给View的用户使用,后者是View自身的逻辑
  • 前者先调用,如果消费了事件,不调用后者

参考

http://wangkuiwu.github.io/2015/01/01/TouchEvent-Introduce/ 系列
http://blog.csdn.net/guolin_blog/article/details/9097463 系列

Java 集合类

基础

常用分类:

  • List:ArrayList、LinkedList、Vector、Stack
  • Set:HashSet、LinkedHashSet、TreeSet
  • Map:HashMap、LinkedHashMap、TreeMap、HashTable

特点:

  • List:有序可重复
  • Set:不可重复
  • Map:键值对

List:

  • ArrayList:可变长数组
  • LinkedList:链表实现,插入删除效率高
  • Vector:线程安全的 ArrayList
  • Stack:Vector 的子类,多了堆栈操作的方法,方便

Set:

  • HashSet:为快速查找而生,基于 HashMap
  • LinkedHashSet:有序 HashSet,按插入顺序排列
  • TreeSet:有序 HashSet,按值排列

Map

  • HashMap:键值对结构
  • LinkedHashMap:有序 HashMap,按插入顺序排列
  • TreeMap:有序 HashMap,按值排列
  • HashTable:线程安全的 HashMap

选择流程图:

Tips

遍历:

  • for(int i; i < size; i++):效率低,每次通过get(i)获取都是O(n)
  • for(Object obj : objectList)
  • while (iteraotr.hasNext())

Android setText() 渲染流程

为了清晰,下面用伪代码简化

调用textView.setText(),首先会经过几层简单的封装,方法名都是setText()

// TextView.java
setText() {
    notifyListeners();
    checkForRelayout();
}

首先通知到文本改变的监听器,如TextChangedListener()

// TextView.java
checkForRelayout() {
    ...... 
    if (needReLayout) {
        requestLayout(); //重新布局
    }

    invalidate(); //即调用onDraw()重新绘制
}

检查是否需要改变布局,如果需要,则在重绘之前会调用requestLayout()

// TextView.java
onDraw() {
    drawBackground();
    drawIcon();
    drawShadow();
    ......
    layout.draw();
}

针对整个TextView的范围,绘制好文字以外或者底部的各种部件

// Layout.java
draw() {
    drawBackground(); //绘制段落的背景
    drawText();
}

针对文字段落,绘制背景,然后终于轮到了主角

// Layout.java
drawText() {
    ...... // 计算渲染的位置坐标
    for (每行) {
        if (!mSpannedText) {
            // 普通无样式文本
            canvas.drawText()
        } else {
            // TODO
        }
    }
}

针对每一行文字,逐行进行绘制

// Canvas.java
drawText() {
    native_drawText(canvas, paint, x, y, ...);
}

调用native渲染方法,并提供必须的参数:画布、画笔(包括各个属性,大小、粗细、颜色等)、坐标。

这就是TextView setTextView渲染的主要流程,给出个大概框架之后,可以供后面深入优化参考。

Android Broadcast 使用指南

类型

发送方式 特点 应用场景
普通广播 sendBroadcast() 异步、无序 普通场景
有序广播 sendOrderedBroadcast() Receivers 轮流,可附加信息 拨号广播的拦截、格式化
黏性广播 sendSticktBroadcast() 接收者主动 监听电池状态信息的广播

广播接收器注册方式

  • 动态:registerReceiver()
  • 静态:在manifest 中添加

安全性

使用LocalBroadcastManager,避免其他应用发来的恶意广播,避免内部广播被其他应用接收

Android Service 使用指南

一、是什么

Service 继承自 Context,相当于与 Activity 同级的运行上下文。

二、特点

  • 无交互
  • 后台运行:不受界面、应用切换的影响
  • 自重启
  • 默认在主线程执行,一般会另起线程

三、启动方式

Stated 方式

典型使用场景:社交应用的在线心跳 (与 Activity 单向通信)

Bound 方式

典型使用场景:音乐播放(与 Activity 双向通信)

四、选用决策图

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.