Android Lock Pattern 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 介绍 1.1 关于 Android 的图案密码解锁,通过手势连接 3 * 3 的点矩阵绘制图案表示解锁密码。基于 Android Source Code。 1.2 特点 支持: Android 1.6+ (API 4+)。 无特殊依赖。 支持手机与平板的布局。 Stealth mode (invisible pattern)。 包含 5 种主题: Dark/Light Light with dark action bar (API 14+) Dark/Light dialogs 有验证码模式。 1.3 使用 1.3.1 Manifest 配置 <activity android:name="com.haibison.android.lockpattern.LockPatternActivity" android:theme="@style/Alp.42447968.Theme.Dark" /> 1.3.2 创建图形锁模式 private static final int REQ_CREATE_PATTERN = 1; Intent intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN, null, your-context, LockPatternActivity.class); startActivityForResult(intent, REQ_CREATE_PATTERN); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQ_CREATE_PATTERN: { if (resultCode == RESULT_OK) { char[] pattern = data.getCharArrayExtra( LockPatternActivity.EXTRA_PATTERN); ... } break; } } } 1.3.3 验证图形锁 private static final int REQ_ENTER_PATTERN = 2; char[] savedPattern = ... Intent intent = new Intent(LockPatternActivity.ACTION_COMPARE_PATTERN, null, your-context, LockPatternActivity.class); intent.putExtra(LockPatternActivity.EXTRA_PATTERN, savedPattern); startActivityForResult(intent, REQ_ENTER_PATTERN); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQ_ENTER_PATTERN: { switch (resultCode) { case RESULT_OK: // The user passed break; case RESULT_CANCELED: // The user cancelled the task break; case LockPatternActivity.RESULT_FAILED: // The user failed to enter the pattern break; case LockPatternActivity.RESULT_FORGOT_PATTERN: // The user forgot the pattern and invoked your recovery Activity. break; } int retryCount = data.getIntExtra( LockPatternActivity.EXTRA_RETRY_COUNT, 0); break; } } } 2. 总体设计 本项目较为简单,总体设计略过,具体实现请参考下面的分析。 ...

2015年4月8日 · 2 分钟 · 天边的星星

Dagger 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 1.1 Dagger Dagger 是一款 Java 平台的依赖注入库,关于依赖注入,详细见 依赖注入简介。 Java 的依赖注入库中,最有名的应该属 Google 的 Guice,Spring 也很有名,不过是专注于 J2EE 开发。Guice 的功能非常强大,但它是通过在运行时读取注解来实现依赖注入的,依赖的生成和注入需要依靠 Java 的反射机制,这对于对性能非常敏感的 Android 来说是一个硬伤。基于此,Dagger 应运而生。 Dagger 同样使用注解来实现依赖注入,但它利用 APT(Annotation Process Tool) 在编译时生成辅助类,这些类继承特定父类或实现特定接口,程序在运行时 Dagger 加载这些辅助类,调用相应接口完成依赖生成和注入。Dagger 对于程序的性能影响非常小,因此更加适用于 Android 应用的开发。 1.2 依赖注入相关概念 **依赖(Dependency):**如果在 Class A 中,有个属性是 Class B 的实例,则称 Class B 是 Class A 的依赖,本文中我们将 Class A 称为宿主(Host),并且全文用 Host 表示;Class B 称为依赖(Dependency),并且全文用 Dependency 表示。一个 Host 可能是另外一个类的 Dependency。 **宿主(Host):**如果 Class B 是 Class A 的 Dependency,则称 Class A 是 Class B 的宿主(Host)。 ...

2015年4月8日 · 10 分钟 · 天边的星星

HoloGraphLibrary 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 HoloGraphLibrary 是一个可用于绘制图表的项目,支持绘制线状图、柱状图、饼状图。 优点:图形设计友好,使用方便。 2. 总体设计 本项目较为简单,总体设计请参考4.1类关系图。 3. 流程图 本项目的每个控件的流程较为类似,可以抽象成一个流程图来理解。 4. 详细设计 4.1 类关系图 其中LineGraph、BarGraph、PieGraph分别对应线状图、柱状图、饼状图控件。 其他除 View 以外的类都表示封装的数据。 4.2 核心类功能介绍 4.2.1 柱状图: Bar.java:用于表现一个柱体,构成柱状图的基本元素。封装了颜色,名字,BarStackSegment(下文将会涉及)数组等属性。若需要对Bar的每一个片段进行控制,改变BarStackSegment数组属性即可。 BarStackSegment.java:一般来说,一个柱体用于展示一个类型的数据,而BarStackSegment是作为柱体的扩展部分,用在同一个柱体上不同区间展示不同数据。 BarGraph.java:继承View类,表示柱状图控件,通过数据绘制负责柱状图。 (1). onDraw 流程图 (2). onDraw 源码分析 a. 绘制的样式定义(柱体颜色、宽度大小等属性) `public void onDraw(Canvas ca) { ... // 柱体的样式定义 float maxValue = 0; float padding = 7; int selectPadding = 4; float bottomPadding = 40; // 定义绘制柱体的区间 float usableHeight; if (showBarText) { this.p.setTextSize(40); this.p.getTextBounds(unit, 0, 1, r3); usableHeight = getHeight() - bottomPadding - Math.abs(r3.top - r3.bottom) - 26; } else { usableHeight = getHeight() - bottomPadding; } ... // 绘制柱体 int count = 0; for (Bar p : points) { // 绘制每个柱体里的自定义区间 if(p.getStackedBar()){ ... }else { // 若没有自定义区间,则正常绘制 ... } } ... } ` b. 绘制计算过程(详细看源码) 1)绘制 X 轴 2)确定柱体的数量 3)计算柱体所需的宽度 4)如果使用动画,柱体最大值(影响绘画的高度)使用动态计算的最大值 5)计算 X 轴上标签的字体的大小(不考虑动画状态,否则会导致字体抖动) 6)设置柱体边界 7)绘制柱体 8)创建选择区域 9)绘制标签 10)绘制柱体顶部的文字 11)限制总体宽度,防止弹出 12)若有使用后,设置监听,对进行动画更新 ...

2015年4月8日 · 1 分钟 · 天边的星星

PhotoView 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 特性(Features): 支持Pinch手势自由缩放。 支持双击放大/还原。 支持平滑滚动。 在滑动父控件下能够运行良好。(例如:ViewPager) 支持基于Matrix变化(放大/缩小/移动)的事件监听。 优势: PhotoView是ImageView的子类,自然的支持所有ImageView的源生行为。 任意项目可以非常方便的从ImageView升级到PhotoView,不用做任何额外的修改。 可以非常方便的与ImageLoader/Picasso之类的异步网络图片读取库集成使用。 事件分发做了很好的处理,可以方便的与ViewPager等同样支持滑动手势的控件集成。 2. 总体设计 PhotoView这个库实际上比较简单,关键点其实就是Touch事件处理和Matrix图形变换的应用. 2.1 TouchEvent及手势事件处理 对TouchEvent分发流程不了解的建议先阅读 Android Touch事件传递机制 本库中对Touch事件的处理流程请参考第三部分的流程图,会有一个比较直观的认识。 2.2 Matrix 由于Matrix是Android系统源生API,很多开发者对此都比较熟悉,为了不影响阅读效果,故不在此详细叙述,如果对其不是很了解,可以查看本文档末尾的Matrix补充说明 3. 流程图 Touch及手势事件判定及传递流程: 如图,从架构上看,干净利落的将事件层层分离,交由不同的Detector处理,最后再将处理结果回调给PhtotViewAttacher中的Matrix去实现图形变换效果。 4. 详细设计 4.1 核心类功能介绍 Core核心类 4.1.1 PhotoView PhotoView 类负责暴露所有供外部调用的API,其本身直接继承自ImageView,同时实现了IPhotoView接口. IPhotoView接口提供了缩放相关的设置属性 和操控matrix变化的回调接口. 主要方法说明: public PhotoView(Context context) public PhotoView(Context context, AttributeSet attr) public PhotoView(Context context, AttributeSet attr, int defStyle) 构造函数,完全与ImageView相同,你可以将PhotoView直接当做ImageView使用,完全兼容. public void setPhotoViewRotation(float rotationDegree) 用于设置图片旋转角度. 注意: 例如使用Android相机拍摄的相片,会根据拍摄时手机方向的不同,在EXIF中存储不同的旋转角度信息,显示时往往需要查询EXIF信息并将照片旋转至正确的方向. 通常我们处理这种问题有两种方案: 通过Bitmap.createBitmap方式重建出正确方向的图片,再加载到ImageView中显示。(不建议使用,因为会占用双倍的内存,Bitmap的回收不是立即生效的。) 在ImageView中使用自定义Matrix将图片旋转到正确的方向。 由于PhotoView中对图片的 缩放 操作依赖对Matrix的操作,自定义Matrix会干扰 PhotoView 的缩放行为,所以PhotoView并不支持ScaleType.Matrix. 可参见PhotoViewAttacher源码: ...

2015年4月8日 · 3 分钟 · 天边的星星

xUtils 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 xUtils一个Android公共库框架,主要包括四个部分:View,Db, Http, Bitmap 四个模块。 View模块主要的功能是通过注解绑定UI,资源,事件。 Db模块是一个数据库orm框架, 简单的语句就能进行数据的操作。 Http模块主要访问网络,支持同步,异步方式的请求,支持文件的下载。 Bitmap模块是加载图片以及图片的处理, 支持加载本地,网络图片。而且支持图片的内存和本地缓存。 2. 详细设计 2.1 View模块 2.1.1 总体设计 流程和关系较少, 请看下面的详细分析 2.1.2 流程图 2.1.3 核心类功能介绍 请先了解注解 ,动态代理 可以帮助到您, 如果已经了解请忽略。 注解和反射知识是这个模块的主要内容 1.ViewUtils.java View和各种事件的注入以及资源的注入。 (1)主要函数 ` private static void injectObject(Object handler, ViewFinder finder) ` 第一个参数Object handler代表的是需要注入的对象, 第二个参数是需要注入View(这个View就是handler的成员变量)所在的View或者Activity的包装对象。 该方法完成了View和各种事件的注入以及资源的注入。主要的原理就是通过反射和注解。 完成Activity的setContentView。 完成View的注入。 完成资源的注入。 完成各种事件的注入。 2.ViewFinder.java (1)主要函数 ` public View findViewById(int id, int pid) public View findViewById(int id) ` 如果存在父View, 优先从父View寻找,否则从当前的View或者Activity中寻找。 3.ResLoader.java ` public static Object loadRes(ResType type, Context context, int id) ` 获取资源文件值。支持多种资源的获取。 ...

2015年4月8日 · 4 分钟 · 天边的星星

Android Universal Image Loader 源码分析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的、可高度定制的图片缓存,本文简称为UIL。 简单的说 UIL 就做了一件事——获取图片并显示在相应的控件上。 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化ImageLoader,如下: `public class YourApplication extends Application { @Override public void onCreate() { super.onCreate(); ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) // 添加你的配置需求 .build(); ImageLoader.getInstance().init(configuration); } } ` 其中 configuration 表示ImageLoader的配置信息,可包括图片最大尺寸、线程池、缓存、下载器、解码器等等。 1.2.2 Manifest 配置 `&lt;manifest&gt; &lt;uses-permission android:name="android.permission.INTERNET" /&gt; &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&gt; &lt;application android:name=".YourApplication" …… &gt; …… &lt;/application&gt; &lt;/manifest&gt; ` 添加网络权限。如果允许磁盘缓存,需要添加写外设的权限。 ...

2015年4月8日 · 10 分钟 · 天边的星星

Volley 源码解析

1. 功能介绍 1.1. Volley Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框架。在 Google I/O 2013 大会上发布。 名字由来:a burst or emission of many things or a large amount at once 发布演讲时候的配图 从名字由来和配图中无数急促的火箭可以看出 Volley 的特点:特别适合数据量小,通信频繁的网络操作。(个人认为 Android 应用中绝大多数的网络操作都属于这种类型)。 1.2 Volley 的主要特点 (1). 扩展性强。Volley 中大多是基于接口的设计,可配置性强。 (2). 一定程度符合 Http 规范,包括返回 ResponseCode(2xx、3xx、4xx、5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。 (3). 默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现,这两者的区别及优劣在4.2.1 Volley中具体介绍。 (4). 提供简便的图片加载工具。 2. 总体设计 2.1. 总体设计图 上面是 Volley 的总体设计图,主要是通过两种Diapatch Thread不断从RequestQueue中取出请求,根据是否已缓存调用Cache或Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据,然后交由ResponseDelivery去做结果分发及回调处理。 2.2. Volley 中的概念 简单介绍一些概念,在详细设计中会仔细介绍。 Volley 的调用比较简单,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue后,只需要往这个RequestQueue不断 add Request 即可。 ...

2015年4月8日 · 7 分钟 · 天边的星星

几个安卓开发辅助工具

本文将介绍几个对安卓开发者有用的几个工具。 设计师/开发者工具 Android Button Maker 是一个产生按钮代码的在线工具。Android API提供了由xml定义的Drawable,可以定义形状、颜色、渐变等。基于这种方式生产的按钮要比普通的png按钮速度快很多。你可以在这个工具的设置界面中自定义按钮的属性,然后获取代码。 1427680999497361.png Android Pixel Calculator 帮助你搞清楚dp, px, sp, in, mm 和pt关系以及相互转换的工具。 1427681547132533.png 优化png图片的开源工具 OptiPNG 、PNGCrush 和TinyPNG 是几个用于优化PNG图片的开源命令行工具。你可以通过各种各样的算法来压缩png图片。如果你的app高度依赖于美工设计的图片,你应该考虑使用它们来减小图片的大小。 Android Asset Studio 一个基于web的安卓资源生成工具,可以生成图标、样式等资源文件。目前可以生成: Launcher 图标 Action bar and tab 图标 Notification 图标 Navigation drawer indicator 普通图标 OTHER GENERATORS — MISCELLANEOUS ASSET CREATION TOOLS 点9图片 Official Android Device Art Generator COMMUNITY TOOLS — SIMILAR TOOLS FROM THE OPEN SOURCE COMMUNITY Android Action Bar Style Generator by Jeff Gilfelt ...

2015年4月2日 · 1 分钟 · 天边的星星

Android性能调优

本文主要分享自己在appstore项目中的性能调优点,包括同步改异步、缓存、Layout优化、数据库优化、算法优化、延迟执行等。 性能优化专题已完成五部分: 性能优化总纲——性能问题及性能调优方式 性能优化第三篇——Java(Android)代码优化 性能优化第二篇——布局优化 性能优化第一篇——数据库性能优化 性能优化实例 一、性能瓶颈点 整个页面主要由6个Page的ViewPager,每个Page为一个GridView,GridView一屏大概显示4*4的item信息(本文最后有附图)。由于网络数据获取较多且随时需要保持页面内app下载进度及状态,所以出现以下性能问题 a. ViewPager左右滑动明显卡顿 b. GridView上下滚动明显卡顿 c. 其他Activity返回ViewPager Activity较慢 d. 网络获取到展现速度较慢 ** 二、性能调试及定位** 主要使用Traceview、monkey、monkey runner调试,traceview类似java web调优的visualvm,使用方法如下: 在需要调优的activity onCreate函数中添加 1 <td class="crayon-code"> <div class="crayon-pre"> <div id="crayon-551b51a07ef3f771207698-1" class="crayon-line"> <span class="crayon-v">android</span><span class="crayon-sy">.</span><span class="crayon-v">os</span><span class="crayon-sy">.</span><span class="crayon-v">debug</span><span class="crayon-sy">.</span><span class="crayon-e">startMethodTracing</span><span class="crayon-sy">(</span><span class="crayon-s">&#8220;Entertainment&#8221;</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span> </div> </div> </td> </tr> </table> onDestrory函数中添加 1 <td class="crayon-code"> <div class="crayon-pre"> <div id="crayon-551b51a07ef54202315585-1" class="crayon-line"> <span class="crayon-v">android</span><span class="crayon-sy">.</span><span class="crayon-v">os</span><span class="crayon-sy">.</span><span class="crayon-v">debug</span><span class="crayon-sy">.</span><span class="crayon-e">stopMethodTracing</span><span class="crayon-sy">(</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span> </div> </div> </td> </tr> </table> 程序退出后会在sd卡根目录下生成Entertainment.trace这个文件,cmd到android sdk的tools目录下运行traceview.bat Entertainment.trace即可,截图如下 ...

2015年4月1日 · 12 分钟 · 天边的星星

Android LayoutInflater原理分析,带你一步步深入了解View(一)

转载:http://blog.csdn.net/guolin_blog/article/details/12921889 有段时间没写博客了,感觉都有些生疏了呢。最近繁忙的工作终于告一段落,又有时间写文章了,接下来还会继续坚持每一周篇的节奏。 有不少朋友跟我反应,都希望我可以写一篇关于View的文章,讲一讲View的工作原理以及自定义View的方法。没错,承诺过的文章我是一定要兑现的,而且在View这个话题上我还准备多写几篇,尽量能将这个知识点讲得透彻一些。那么今天就从LayoutInflater开始讲起吧。 相信接触Android久一点的朋友对于LayoutInflater一定不会陌生,都会知道它主要是用于加载布局的。而刚接触Android的朋友可能对LayoutInflater不怎么熟悉,因为加载布局的任务通常都是在Activity中调用setContentView()方法来完成的。其实setContentView()方法的内部也是使用LayoutInflater来加载布局的,只不过这部分源码是internal的,不太容易查看到。那么今天我们就来把LayoutInflater的工作流程仔细地剖析一遍,也许还能解决掉某些困扰你心头多年的疑惑。 先来看一下LayoutInflater的基本用法吧,它的用法非常简单,首先需要获取到LayoutInflater的实例,有两种方法可以获取到,第一种写法如下: **[java]** [view plain](http://blog.csdn.net/guolin_blog/article/details/12921889#)[copy](http://blog.csdn.net/guolin_blog/article/details/12921889#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/118597)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/118597/fork) <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1"> </embed> </div> </div> - LayoutInflater layoutInflater = LayoutInflater.from(context); 当然,还有另外一种写法也可以完成同样的效果: **[java]** [view plain](http://blog.csdn.net/guolin_blog/article/details/12921889#)[copy](http://blog.csdn.net/guolin_blog/article/details/12921889#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/118597)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/118597/fork) <div> <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2"> </embed> </div> </div> - LayoutInflater layoutInflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 其实第一种就是第二种的简单写法,只是Android给我们做了一下封装而已。得到了LayoutInflater的实例之后就可以调用它的inflate()方法来加载布局了,如下所示: **[java]** [view plain](http://blog.csdn.net/guolin_blog/article/details/12921889#)[copy](http://blog.csdn.net/guolin_blog/article/details/12921889#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/118597)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/118597/fork) <div> <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_3"> </embed> </div> </div> - layoutInflater.inflate(resourceId, root); inflate()方法一般接收两个参数,第一个参数就是要加载的布局id,第二个参数是指给该布局的外部再嵌套一层父布局,如果不需要就直接传null。这样就成功成功创建了一个布局的实例,之后再将它添加到指定的位置就可以显示出来了。 ...

2015年4月1日 · 12 分钟 · 天边的星星