文档库 最新最全的文档下载
当前位置:文档库 › android输入法01:SoftKeyboard源码解析01

android输入法01:SoftKeyboard源码解析01

android输入法01:SoftKeyboard源码解析01
android输入法01:SoftKeyboard源码解析01

android输入法01:SoftKeyboard源码解析01

本文主要介绍android自带输入法实例SoftKeyboard的源码,共分为两篇:第一篇为SoftKeyboard框架概述,第二篇为源码注释。

1、IMF简介

一个IMF结构中包含三个主要的部分:

?i nput method manager:管理各部分的交互。它是一个客户端API,存在于各个应用程序的context中,用来沟通管理所有进程间交互的全局系统服务。

?i nput method(IME):实现一个允许用户生成文本的独立交互模块。系统绑定一个当前的输入法。使其创建和生成,决定输入法何时隐藏或者显示它的UI。同一时间只能有一个IME

运行。

?c lient application:通过输入法管理器控制输入焦点和IME的状态。一次只能有一个客户端使用IME。

1.1 InputManager

由UI控件(View,TextView,EditText等)调用,用来操作输入法。比如,打开,关闭,切换输

入法等。

它是整个输入法框架(IMF)结构的核心API,处理应用程序和当前输入法的交互。可以通过Context.getSystemService()来获取一个InputMethodManager的实例。

在开发过程中,最基础最重要的就是养成阅读API的习惯。优秀的程序员要养成把自己关在小黑屋里,断绝与外界的联网和联系,仅仅靠自己电脑中的开发环境和API文档,以及漂亮女仆送来的每

天三顿饭,写出优秀的程序。这个在武侠小说中叫闭关,在软件开发中叫Clean Room,哈哈。Android的API文档在:%SDK_ROOM%/docs/reference/index.html,

InputManager类的位

置:%SDK_ROOM%/docs/reference/android/view/inputmethod/InputMethodManager.html 由于,该类跟本次要讲的Sample关系不大,这里就不详细分析,请各位自行阅读API doc吧。

1.2 InputMethodService

包括输入法内部逻辑,键盘布局,选词等,最终把选出的字符通过commitText提交出来。实

现输入法的基础就是名为InputMethodService的类,比如你要实现一个谷歌输入法,就是要extends本类。我们接下来要学习的SoftKeyboard Sample也是extends本类。InputMethodService类的位置

在:%SDK_ROOM%/docs/reference/android/inputmethodservice/InputMethodService.html

?I nputMethodService是InputMethod的一个完整实现,你可以再在其基础上扩展和定制。它的主要方法如下:

?o nInitializeInterface() 顾名思义,它在初始化界面的时候被调用,而一般是由于配置文件的更改导致该函数的执行

?o nBinndInput() 它在另外的客户端和该输入法连接时调用

?o nStartInput() 非常重要的一个回调,它在编辑框中用户已经开始输入的时候调用。比如,当点击一个输入框,我们需要根据这个输入框的信息,设置输入法的一些特性,这个在

Sample中很有体会。

?o nCreateInputView() 返回一个层次性的输入视图,而且只是在这个视图第一次显示的时候被调用

?o nCreateCandidatesView() 同onCreateInputView(),只不过创建的是候选框的视图。

?o nCreateExtractTextView() 比较特殊,是在全屏模式下的一个视图。

?o nStartInputView() 在输入视图被显示并且在一个新的输入框中输入已经开始的时候调用。

基本上输入法的定制,都是围绕在这个类来实现的,它主要提供的是一个基本的用户界面框架(包括输入视图,候选词视图和全屏模式),但是这些都是要实现者自己去定制的。这里的实现是

让所有的元素都放置在了一个单一的由InputMethodService来管理的窗口中。它提供了很多的回调API,需要我们自己去实现。一些默认的设置包括:

?软键盘输入视图,它通常都是被放置在屏幕的下方。

?候选词视图,它通常是放置在输入视图的上面。

当我们输入的时候,需要改变应用程序的界面来适应这些视图的放置规则。比如在Android上

面输入,编辑框会自动变形腾出一个软键盘的位置来。

两个非常重要的视图:

1. 软输入视图。是与用户交互的主要发生地:按键,画图或者其他的方式。通常的实现就是简

单的用一个视图来处理所有的工作,并且在调用 onCreateInputView()的时候返回一个新的实例。

通过调用系统的onEvaluateInputViewShow()来测试是否需要显示输入视图,它是系统根据当前的

上下文环境来实现的。当输入法状态改变的时候,需要调用updateInputViewShown()来重新估计

一下。

2. 候选词视图。当用户输入一些字符之后,输入法可能需要提供给用户一些可用的候选词的列表。这个视图的管理和输入视图不大一样,因为这个视图是非常的短暂的,它只是在有候选词的时

候才会被显示。可以用setCandidatesViewShow()来设置是否需要显示这个视图。正是因为这个显

示的频繁性,所以它一般不会被销毁,而且不会改变当前应用程序的视图。

最后,关于文本的产生,这是一个IME的最终目的。它通过InputConnection来链接IME和应

用程序的:能够直接产生想要的按键信息,甚至直接在候选和提交的文本中编辑。当用户在不同的

输入目标之间切换的时候,IME会不断的调用onFinishInput() 和 onStartInput()。在这两个函数中,需要反复做的就是复位状态,并且应对新的输入框的信息。

以上是一个输入法的最基本的介绍,下面将根据Sample中的SoftKeyboard来说明这些问题。

2、创建Eclipse工程

这里使用最新版本的Android SDK 2.3.3下的SoftKeyboard Sample来创建工程,其实,从

1.5版本,该Sample就已经存在了。同时,由于SoftKeyboard会使人误解为KeyBoard的子类,

这里特别改名为InputMethodServiceSample,更符合其功能和特性。

点击Finish,完成项目的创建,可以看到项目工程结构如下:

在Android SDK 2.3.3模拟器上运行本Sample,需要在Setting中选择使用本Sample,需要在Language&keyboard中选中本Sample的名称。

因为它可以收集和记录所有你的输入,这个特性如果被有心人利用会很恐怖。

选中Sample Soft Keyboard作为我们的输入法之后,进入需要输入法的地方,这里以短信界

面作为范例,在输入框中长按,会出现“编辑文本”选单,点击“输入法”即可进入当前输入界面的输入

法选择框。就可以使用输入法切换到本输入法看到它的keyboard。

3、配置和资源文件解析

除去源代码将在后文统一分析之外,这里介绍下配置和资源文件。

3.1 AndroidMainifest.xml

每个Android应用都会有的配置描述文件。在这里,Sample把自己声明成了服务,而且绑定

在了输入法之上。它的intent-filter是直接用的InputMethod接口,这也是所有的输入法的接口。

xmlns:android="https://www.wendangku.net/doc/f218498700.html,/apk/res/android"

package="com.example.android.softkeyboard">

android:permission="android.permission.BIND_INPUT_METHOD">

android:resource="@xml/method" />

3.2 res目录

放置resource,即资源文件,里面蛮多东西的,具体如下。

(1) drawable目录,放置的是图标文件。

(2) values目录,包含strings.xml以及一些自定义的类型和值的xml文件。

strings.xml

― ime_name 定义了该输入法的名字

― word_separators 词的分隔符,即输入过程中可能用来表示一个词输入完成的符号,比如空格,

标点等等)

― label_xx_key 为软键盘定义确认键的标签。在后面代码解析中可以看到,程序会根据输入框的信息来设置EnterKey的图标或者标签。如:在一个网址上面输入,就会显示一个搜索的图标,而在

编辑短信时,如果在收信人写,那么EnterKey就是Next标签,用来直接跳到短信正文部分。dimens.xml,定义软键盘的尺寸信息,包括键高(key_height),候选词字体的高度

(candidate_font_height),候选词垂直间隙(candidate_vertical_padding)。

color.xml,定义候选词的背景颜色,比如正常(candidate_normal),推荐

(candidate_recommended),背景(candidate_background)和其它(candidate_other)等颜色。

(3) layout目录,保存布局配置文件。这里只有一个配置文件:input.xml,它定义的是输入视图的信息,包括id(android:id="@+id/keyboard"),放置在屏幕下方

(android:layout_alignParentBottom="true"),水平最大填充(android:layout_width="match_parent"),垂直包含子内容(android:layout_height="wrap_content")。

(4) xml目录,文件如下:

method.xml,为搜索管理提供配置信息。

qwerty.xml,英文字符的全键盘布局文件。定义很直观,很容易就可以看懂。

symbols_shift.xml和symbols.xml,是标点字符的全键盘布局文件。

4、源代码解析

4.1 概述

从InputMethodServiceSample项目可以看出实现一个输入法至少需要CandidateView, LatinKeyboard, LatinKeyboardView,SoftKeyboard这四个文件:

?C andidateView负责显示软键盘上面的那个候选区域。

?L atinKeyboard负责解析并保存键盘布局,并提供选词算法,供程序运行当中使用。其中键盘布局是以XML文件存放在资源当中的。比如我们在汉字输入法下,按下b、a两个字母。

LatinKeyboard就负责把这两个字母变成爸、把、巴等显示在CandidateView上。

?L atinKeyboardView负责显示,就是我们看到的按键。它与CandidateView合起来,组成了InputView,就是我们看到的软键盘。

?S oftKeyboard继承了InputMethodService,启动一个输入法,其实就是启动一个InputMethodService,当SoftKeyboard输入法被使用时,启动就会启动SoftKeyboard这

个Service。

4.2 LatinKeyboard.java

软键盘类,直接继承了Keyboard类,并定义一个xml格式的Keyboard的布局,来实现一个

输入拉丁文的键盘。这里只是创建一个键盘对象,并不对具体的布局给出手段。

为了更好的理解LatinKeyboard类,这里简单介绍一下Keyboard类。Keyboard可以载入一个用来

显示键盘布局的xml来初始化自己,并且可以保存这些键盘的键的属性。他有三个构造函数:Keyboard(Context context, int xmlLayoutResId),用语境和xml资源id索引xml文件来创建。Keyboard(Context context, int xmlLayoutResId, int modeId),这个和上面差不多,只不过多了一个modeld。

Keyboard(Context context, int layoutTemplateResId, CharSequence characters, int columns, int horizontalPadding),这个比较复杂,用一个空xml布局模板创建一个键盘,然后用指定的

characters按照从左往右,从上往下的方式填满这个模板。

本文件源码前面完全继承keyboard,直接用了父类构造函数进行初始化。

这里因为重写了Keyboard类的createKeyFromXml(Resources res, Row parent, int x, int y, XmlResourceParser parser),为了要返回一个Key对象,干脆直接创建LatinKey对象好了。从这

里我们能看出面向对象和使用框架的要求。

接着,本文件重载了一个createKeyFromXml的函数,这是一个回调函数,它在键盘描绘键的

时候调用,从一个xml资源文件中载入一个键,并且放置在(x,y)坐标处。它还判断了该键是否是回

车键,并保存起来。在这里,为了要返回一个Key对象,于是直接创建内部类的LatinKey对象。

从这里我们能看出面向对象和使用框架的要求。

此外,还有一个函数是:setImeOptions,它是根据编辑框的当前信息,来为这个键盘的回车键

设置适当的标签。输入框的不同,会产生不同的回车键的label或者icon。在这个函数中,有一个

技巧是用了一些imeOption的位信息,比如IME_MASK_ACTION等等。主要是查看的EditorInfo

的Action信息,这里有:

IME_ACTION_GO: go操作,将用户带入到一个该输入框的目标的动作。确认键将不会有icon,只

有label: GO

IME_ACTION_NEXT: next操作,将用户带入到该文本框的写一个输入框中。如: 编辑短消息的时候,内容就是收件人手机号码框的next文字域。它也只是一个NEXT label就行了。

IME_ACTION_SEARCH: search操作,默认动作就是搜索。如: 在URL框中输入的时候,默认的

就是search操作,它提供了一个像放大镜一样的icon。

IME-ACTION_SEND: send操作,默认动作就是发送当前的内容。如: 短消息的内容框里面输入的

时候,后面通常就是一个发送操作。它也是只提供一个Label:SEND

DEFAULT: 默认情况下表示文本框并没有什么特殊的要求,所以只需要设置return的icon即可。

最后,它还定义了一个内部类——LatinKey,它直接继承了Key,来定义一个单独的键,它唯

一重载的函数是isInside(int x , int y ),用来判断一个坐标是否在该键内。它重载为判断该键是否是CANCEL键,如果是则把Y坐标减少10px,按照他的解释是用来还原这个可以关掉键盘的键的目

标区域。

4.3 LatinKeyboardView.java

这里就是个View,自然也继承自View,因为前面创建的键盘只是一个概念,并不能实例出来

一个UI,所以需要借助于一个VIEW类来进行绘制。这个类简单的继承了KeyboardView类,然后

重载了一个动作方法,就是onLongPress。

它在有长时间按键事件的时候会调用,首先判断这个按键是否是CANCEL键,如果是的话就

通过调用 KeyboardView被安置好的OnKeyboardActionListener对象,给键盘发送一个OPTIONS

键被按下的事件。它是用来屏蔽CANCEL键,然后发送了一个未知的代码的键。

4.4 CandidateView.java

CandidateView是一个候选字显示view,它提供一个候选字选择的视图,直接继承于View类

即可。在我们输入字符时,它应该能根据字符显示一定的提示,比如拼音同音字啊,联想的字啊之

类的。

1 先看它定义了那些重要变量

?m Service: candidateView的宿主类,即该view是为什么输入法服务的。

?m Suggestions: 建议。比如说当我们输入一些字母之后输入法希望根据输入来进行联想建议。

?m SelectedIndex: 用户选择的词的索引。

?m SelectionHighlight: 描绘选择区域高亮的类。

?m TypedWordValid: 键入的word是否合法正确。

?m BgPadding: 背景填充区域。

?m WordWidth: 每个候选词的宽度

?m WordX:每个候选词的X坐标。有了这两个变量,就能够在屏幕上准确的绘制出该候选键。

?m Color*:定义了各种颜色。

?m Paint: 一个绘图类,后面会用到

?m VerticalPadding: 垂直填充区域。

?m TargetScrollX: 目标滚动的横坐标,即要将目标滚动到何处。

?m TotalWidth: 总的宽度

?m GestureDetector: 声明一个手势监测器

GestureDetector对象似乎很少见,让我们了解一下android.view.GestureDetector。这是一个

与动作事件相关的类,可以用来检测各种动作事件,这里称之为:手势监测器。它的回调函数是GestureDetector.OnGestureListener,在动作发生时执行,而且只能在触摸时发出,用滚动球无效。要使用这个通常要先建立一个对象,如同代码里体现的,然后设置

GestureDetector.OnGestureListener 同时在 onTouchEvent(MotionEvent)中写入动作发生要执行的代码。

2 构造函数

首先初始化了mSelectionHighlight,这是一个drawable对象,并利用drawable的setState方

法设置这个drawable的初始状态。同时在res目录下加入一个color.xml文件来定义用到的所有颜

色资源,然后用R索引,这些资源可以被加入到自己的R.java的内容里,可以直接引用。剩下的

内容就是初始化背景,选中,未选中时的view的背景颜色,这里都是在前面color.xml内定义的了。用这样的方式获得:

Resources r = context.getResources();

获得当前资源对象的方法。

setBackgroundColor(r.getColor(R.color.candidate_background));

然后初始化了一个手势检测器(gesturedetector),它的Listener重载了一个方法,就是onScroll,

这个类是手势检测器发现有scroll动作的时候触发。在这个函数里,主要是进行滑动的判断。

这里用到了很多view下的方法:getScrollX();getWidth();scrollTo(sx, getScrollY());invalidate();我们分别解释如下:

getScrollX():获得滚动后view的横坐标

scrollTo():滚动到目标坐标

getScrollY():获得滚动后view的纵坐标

invalidate():使view重画

在这里,distanceX是上次调用onscroll后滚动的X轴距离。假设这个view之前没有被滚动过,第

一次滚动且坐标在显示区域内,sx=getScrollX()+distanceX,则view就scrollTo这个位置。如果

sx超过了最大显示宽度,则scrollTo就滚想原先sx处,也就是不动。也就是说:系统滚动产生一

个惯性的感觉,当你把view实际到了X坐标点,系统再给你加一个distanceX,这个distanceX不

是两个动作之间的距离,应该是上一个滚动动作的停止点和本次滚动动作的停止点之间的距离,这

个距离系统自己算,我们不用管,只要到了最大边界,view就不再滚动,或者说是原地滚动。

接下来:

setHorizontalFadingEdgeEnabled(true);// 设置view在水平滚动时,水平边是否淡出。setWillNotDraw(false);// view不自己绘制自己

setHorizontalScrollBarEnabled(false);// 不设置水平滚动条

setVerticalScrollBarEnabled(false);// 不设置垂直滚动条

3 setService是设置宿主输入法。

4. computeHorizontalScrollRange,表示这个view的水平滚动区域,返回的是候选视图的总体宽度。

5. onMeasure,重载自view类,在布局阶段被父视图所调用。比如当父视图需要根据其子视

图的大小来进行布局时,就需要回调这个函数来看该view的大小。当调用这个函数时必须在内部

调用setMeasureDimension来对宽和高进行保存,否则将会有异常出现。这里重载它是为了系统

检测要绘制的字符区的大小,因为字体可能有大小,应根据字体来。它首先计算自己的期望的宽度,调用resolveSize来看是否能够得到50px的宽度;然后是计算想要的高度,根据字体和显示提示区的padding来确定。

6. onDraw,view的主要函数,每个view都必须重写这个函数来绘制自己。它提供了一块画布,如果为空,则直接调用父类来画。

在这里的内部逻辑大概如下:

判断是否有候选词,没有的话就不用绘制。

初始化背景的填充区域,直接view的背景中得到即可。

对于每一个候选词,得到其文本,然后计算其宽度,然后再加上两边的空隙。

判断是否选择了当前词:触摸的位置+滚动了的位置。如果是在当前词的左边到右边之间,则将高

亮区域绘制在画布上面,高亮区域设置的大小即为当前词的大小,并且保存被选词的索引。

将文本绘制在这个候选词的画布上面,它进行了一个判断,判断哪个才是推荐词。默认情况下是候

选词的第一个词,但是它判断第一个词是否是合法的,如果是,则第一个词是候选词,否者第二个

词才是候选粗,然后进行绘制。

绘制一条线,来分割各个候选词。上面提到的总共的宽度在所有的词都绘制出来之后,就能够得到了。

判断目标滚动是否是当前的,不是就需要滚动过去。

7. scrollToTarget,滚到到目标区域。得到当前值,然后加上一个滚动距离,看是否超过并进

行相应调整,之后滚动到相应坐标。

8. setSuggestions,设置候选词,之后进行绘制。

9. onTouchEvent,触摸事件产生时调用。首先判断是否为gesturedetector监听的动作,如果

不是就进行下面处理。初始化动作,把发生的动作记录下来,点触的坐标也记录下来。然后,根据

动作类型分类反应:

向下:没动作;

移动:如果是向左移动就要手动的选择候选词;

向上:需要手动选择候选词。

10. takeSuggestionAt,选择在坐标x处的词,这个处理的是用户轻轻点击键盘,也就是选择

候选词。

11. removeHighlight,去除高亮显示。

4.5 SoftKeyboard.java

整个输入法的总体的框架,包括什么时候创建,什么时候显示输入法,和怎样和文本框进行通

讯等等。上面的文件,都是为了这个类服务的。总体来说,一个输入法需要的是一个输入视图,一

个候选词视图,还有一个就是和应用程序的链接。

基本时序图如下:

输入法在Android中的本质就是一个Service,假设用户刚刚启动Android,用户移动焦点首次进入文本编辑框时,Android便会通知Service开始进行初始化工作。于是便有了如图中的一系列动作。

追根溯源,onCreate方法继承至Service类,其意义和其他Service的是一样的。

Sample在这里,做了一些非UI方面的初始化,即字符串变量词汇分隔符的初始化。

接下来执行onInitializeInterface,这里是进行UI初始化的地方,创建以后和配置修改以后,都会调用这个方法。Sample在这里对Keyboard进行了初始化,从XML文件中读取软键盘信息,封装进Keyboard对象。

第三个执行的就是onStartInput方法,在这里,我们被绑定到了客户端,接收所有关于编辑对象的详细信息。

第四个执行的方法是onCreateInputView,在用户输入的区域要显示时,这个方法由框架调用,输入法首次显示时,或者配置信息改变时,该方法就会被执行。在该方法中,对inputview进行初始化:读取布局文件信息,设置onKeyboardActionListener,并初始设置 keyboard。

第五个方法是onCreateCandidatesView,在要显示候选词汇的视图时,由框架调用。

和onCreateInputView类似。在这个方式中,对candidateview 进行初始化。

第六个方法,也是最后一个方法,即onStartInputView,正是在这个方法中,将inputview和当前keyboard重新关联起来。

在上面的六个方法中,onCreateInputView和onCreateCandidatesView两个方法只有在初始化时才会执行一次,除非有配置信息发生改变。那么究竟什么是配置信息发生改变呢?在看InputMethodService的API文档时,可以看到有一个方法onConfigurationChanged,根据文档解释,这个方法主要负责配置更改的情况。在示例中,其没有override这个方法,但是在android源码包中的PinyinIME中,有使用这个方法,有兴趣的朋友可以在看完SoftKeyboard Sample之后,看看PinyinIME的源码。

Android Hotfix 新方案——Amigo 源码解读

Android Hotfix 新方案——Amigo 源码解读 首先我们先来看看如何使用这个库。 用法 在project 的build.gradle中 dependencies { classpath 'me.ele:amigo:0.0.3' } 在module 的build.gradle中 apply plugin: 'me.ele.amigo' 就这样轻松的集成了Amigo。 生效补丁包 补丁包生效有两种方式可以选择: ? 稍后生效补丁包 ? 如果不想立即生效而是用户第二次打开App 时才打入补丁包,则可以将新的Apk 放到/data/data/{your pkg}/files/amigo/demo.apk,第二次打开时就会自动生效。可以通过这个方法 ? File hotfixApk = Amigo.getHotfixApk(context); ?

获取到新的Apk。 同时,你也可以使用Amigo 提供的工具类将你的补丁包拷贝到指定的目录当中。 ? FileUtils.copyFile(yourApkFile, amigoApkFile); ? ? 立即生效补丁包 ? 如果想要补丁包立即生效,调用以下两个方法之一,App 会立即重启, 并且打入补丁包。 ? Amigo.work(context); ? Amigo.work(context, apkFile); ? 删除补丁包 如果需要删除掉已经下好的补丁包,可以通过这个方法 Amigo.clear(context); 提示:如果apk 发生了变化,Amigo 会自动清除之前的apk。 自定义界面 在热修复的过程中会有一些耗时的操作,这些操作会在一个新的进程中的Activity 中执行,所以你可以通过以下方式来自定义这个Activity。

Android源码下载方法详解

Android: Android源码下载方法详解 分类:Android平台 安卓源码下载地址:https://www.wendangku.net/doc/f218498700.html,/source/downloading.html 相信很多下载过内核的人都对这个很熟悉 git clone git://https://www.wendangku.net/doc/f218498700.html,/kernel/common.git kernel 但是这是在以前,现在如果这么执行的话,会显示如下内容 Initialized empty Git repository in /home/star/working/kernel/.git/ https://www.wendangku.net/doc/f218498700.html,[0: 149.20.4.77]: errno=Connection refused fatal: unable to connect a socket (Connection refused) 通过浏览器输入https://www.wendangku.net/doc/f218498700.html,/,发现该网站已经被重定向为 https://www.wendangku.net/doc/f218498700.html,/source/downloading.html 可以在该页面的最后发现内核的下载方法。 下面我们介绍一下Android源码下载的步骤。 工作环境: 操作系统:Ubuntu 10.04 或Ubuntu10.10 git程序:1.7.0.4 或1.7.1 转载请注明出处:https://www.wendangku.net/doc/f218498700.html,/pku_android 方法一: 1.1 初始化安装环境 参考网页https://www.wendangku.net/doc/f218498700.html,/source/initializing.html 主要要做的就是安装jdk和安装一些软件包 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev libncurses5-dev x11proto-core-dev \ libx11-dev libreadline6-dev libgl1-mesa-dev tofrodos python-markdown \ libxml2-utils 如果已经安装了,就不许要这步了 1.2 无论下载内核和源码,都需要进行如下操作 参考网页https://www.wendangku.net/doc/f218498700.html,/source/downloading.html $ mkdir ~/bin $ PATH=~/bin:$PATH $ curl https://https://www.wendangku.net/doc/f218498700.html,/dl/googlesource/git-repo/repo > ~/bin/repo 如果出现: repo init error: could not verify the tag 'v1.12.7',

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

Android USB 驱动分析

Android USB 驱动分析 一、USB驱动代码架构和使用 1、代码简介 USB驱动代码在/drivers/usb/gadget下,有三个文件:android.c, f_adb.c, f_mass_storage.c;g_android.ko 是由这三个文件编译而来,其中android.c 依赖于 f_adb.c 和 f_mass_storage.c(这两个文件之间无依赖关系)。 可在android.c中看到: static int __init android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; int ret; printk(KERN_DEBUG "android_bind_config\n"); ret = mass_storage_function_add(dev->cdev, c, dev->nluns); if (ret) return ret; return adb_function_add(dev->cdev, c); } 2、驱动使用 要使USB mass storage连接到主机: 打开/sys/devices/platform/usb_mass_storage/lun0/file文件,向 file文件写入一个存储 设备的路径,例如/dev/block/vold/179:0 (major:minor)路径; 这里的usb_mass_storage根据实际应用可以改的,由 platform_device_register函数的参数决 定。 例如: static struct platform_device fsg_platform_device = { .name = "usb_mass_storage", .id = -1, }; static void __init tegra_machine_init(void) { .... (void) platform_device_register(&fsg_platform_device); .... }

Android 串口编程原理和实现方式附源码

提到串口编程,就不得不提到JNI,不得不提到JavaAPI中的文件描述符类:。下面我分别对JNI、以及串口的一些知识点和实现的源码进行分析说明。这里主要是参考了开源项目android-serialport-api。 串口编程需要了解的基本知识点:对于串口编程,我们只需对串口进行一系列的设置,然后打开串口,这些操作我们可以参考串口调试助手的源码进行学习。在Java中如果要实现串口的读写功能只需操作文件设备类:即可,其他的事都由驱动来完成不用多管!当然,你想了解,那就得看驱动代码了。这里并不打算对驱动进行说明,只初略阐述应用层的实现方式。 (一)JNI: 关于JNI的文章网上有很多,不再多做解释,想详细了解的朋友可以查看云中漫步的技术文章,写得很好,分析也很全面,那么在这篇拙文中我强调3点: 1、如何将编译好的SO文件打包到APK中?(方法很简单,直接在工程目录下新建文件夹libs/armeabi,将SO文件Copy到此目录即可) 2、命名要注意的地方?(在编译好的SO文件中,将文件重命名为:lib即可。其中是编译好后生成的文件) 3、MakeFile文件的编写(不用多说,可以直接参考package/apps目录下用到JNI的相关项目写法) 这是关键的代码: [cpp]view plaincopy

(二):

文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。文件描述符的主要实际用途是创建一个包含该结构的或。这是API的描述,不太好理解,其实可简单的理解为:就是对一个文件进行读写。 (三)实现串口通信细节 1) 建工程:SerialDemo包名:org.winplus.serial,并在工程目录下新建jni和libs两个文件夹和一个org.winplus.serial.utils,如下图: 2) 新建一个类:SerialPortFinder,添加如下代码: [java]view plaincopy 1.package org.winplus.serial.utils; 2. 3.import java.io.File; 4.import java.io.; 5.import java.io.IOException; 6.import java.io.LineNumberReader; 7.import java.util.Iterator; 8.import java.util.Vector; 9. 10.import android.util.Log; 11. 12.public class SerialPortFinder { 13. 14.private static final String TAG = "SerialPort"; 15.

App工程结构搭建:几种常见Android代码架构分析

App工程结构搭建:几种常见Android代码架构分析 关于Android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的角度,看到整齐的代码,优美的分层总是一种舒服的享受的。 从艺术的角度看,其实我们是在追求一种美。 本文先分析几个当今比较流行的android软件包,最后我们汲取其中觉得优秀的部分,搭建我们自己的通用android工程模板。 1. 微盘 微盘的架构比较简单,我把最基本,最主干的画了出来: 第一层:com.sina.VDisk:com.sina(公司域名)+app(应用程序名称) 。 第二层:各模块名称(主模块VDiskClient和实体模块entities)第三层:各模块下具体子包,实现类。 从图中我们能得出上述分析中一个最简单最经典的结构,一般在应用程序包下放一些全局的包或者类,如果有多个大的模块,可以分成多个包,其中包括一个主模块。 在主模块中定义基类,比如BaseActivity等,如果主模块下还有子模块,可以在主模块下建立子模块相应的包。说明一点,有的时候如果只有一个主模块,我们完全可以省略掉模

块这一层,就是BaseActivity.java及其子模块直接提至第二层。 在实体模块中,本应该定义且只定义相应的实体类,供全局调用(然而实际情况可能不是这样,后面会说到)。在微盘应用中,几乎所有的实体类是以xxx+info命名的,这种命名也是我赞成的一种命名,从语义上我觉得xxxModel.java这种命名更生动更真实,xxxModel给我一种太机械太死板的感觉,这点完全是个人观点,具体操作中以个人习惯为主。还有一点,在具体的xxxInfo,java中有很多实体类中是没有get/set的方法,而是直接使用public的字段名。这一点,我是推荐这种方式的,特别是在移动开发中,get/set方法很多时候是完全没有必要的,而且是有性能消耗的。当然如果需要对字段设置一定的控制,get/set方法也是可以酌情使用的。 2. 久忆日记 相比于微盘的工程结构,久忆日记的结构稍微复杂了一些。如下图: 1).第一层和前面微盘一样的. 2).第二层则没有模块分类,直接把需要的具体实现类都放在下面,主要日记的一些日记相关的Activity。 3).第二层的实体包命令为model包,里面不仅存放了实体类

最全的Android源码目录结构详解

最全的Android源码目录结构详解 Android 2.1 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external (android使用的一些开源的模组) |-- frameworks (核心框架——java及C++语言) |-- hardware (部分厂家开源的硬解适配层HAL代码) |-- out (编译完成后的代码输出与此目录) |-- packages (应用程序包) |-- prebuilt (x86和arm架构下预编译的一些资源) |-- sdk (sdk及模拟器) |-- system (底层文件系统库、应用及组件——C语言) `-- vendor (厂商定制代码) bionic 目录 |-- libc (C库) | |-- arch-arm (ARM架构,包含系统调用汇编实现) | |-- arch-x86 (x86架构,包含系统调用汇编实现) | |-- bionic (由C实现的功能,架构无关) | |-- docs (文档) | |-- include (头文件) | |-- inet (?inet相关,具体作用不明) | |-- kernel (Linux内核中的一些头文件) | |-- netbsd (?nesbsd系统相关,具体作用不明) | |-- private (?一些私有的头文件) | |-- stdio (stdio实现) | |-- stdlib (stdlib实现) | |-- string (string函数实现) | |-- tools (几个工具) | |-- tzcode (时区相关代码) | |-- unistd (unistd实现) | `-- zoneinfo (时区信息) |-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,) | |-- alpha (apaha架构) | |-- amd64 (amd64架构) | |-- arm (arm架构) | |-- bsdsrc (?bsd的源码)

android源码分析精典

Android 2.1 源码结构分析 lee Android 2.1 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置)|-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external (android使用的一些开源的模组) |-- frameworks (核心框架——java及C++语言) |-- hardware (主要保护硬解适配层HAL代码) |-- out (编译完成后的代码输出与此目录) |-- packages (应用程序包) |-- prebuilt (x86和arm架构下预编译的一些资源) |-- sdk (sdk及模拟器) |-- system (文件系统库、应用及组件——C语言) `-- vendor (厂商定制代码) bionic 目录 |-- libc (C库) | |-- arch-arm (ARM架构,包含系统调用汇编实现) | |-- arch-x86 (x86架构,包含系统调用汇编实现) | |-- bionic (由C实现的功能,架构无关) | |-- docs (文档) | |-- include (头文件) | |-- inet (?inet相关,具体作用不明) | |-- kernel (Linux内核中的一些头文件) | |-- netbsd (?nesbsd系统相关,具体作用不明) | |-- private (?一些私有的头文件) | |-- stdio (stdio实现) | |-- stdlib (stdlib实现) | |-- string (string函数实现) | |-- tools (几个工具) | |-- tzcode (时区相关代码) | |-- unistd (unistd实现) | `-- zoneinfo (时区信息) |-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能) |-- libm (libm数学库的实现,) | |-- alpha (apaha架构) | |-- amd64 (amd64架构) | |-- arm (arm架构)

Android Galler2源码分析

图库Gallery2 Gallery2主要功能是实现本地存储器、MTP存储器和网络存储器中媒体(图像和视频)的浏览、显示和更多操作(删除、分享、选择和缩放等)。下面用一张简单的用例图描述了Gallery2的功能和职责。 Gallery 主要是4个页面的跳转: AlbumSetPage.Java(相册缩略图); AlbumPage.java(单个相册照片缩略图); PhotoPage.java(单张照片); SlideShowPage.java(幻灯片界面); 跳转过程: AlbumSetPage.Java→AlbumPage.java→PhotoPage.java SlideShowPage.java是单独的。 这些界面类父类为ActivityState.java;这些界面的切换由StateManager.java负责。 1 界面跳转过程: 在Galley2模块,我们先从程序的入口看起,在androidManifest.xml中注册Application标签(Android 系统会为每个程序运行时创建一个Application的类对象且仅创建一个,他的生命周期等于这个程序的生命周期,它是全局的单实例的,一般做一些全局的初始化操作),应用创建时就会被初始化,维护应用内部全局数据,主要看几个函数:initializeAsyncTask(), GalleryUtils.initialize(this),GalleryUtil是Gallery的工具类,获得了屏幕参数,WindowManager,Resource等

Gallery 从launcher进入Gallery,进入GalleryActivity.ava @Override protected void onCreate(Bundle savedInstanceState) { …... setContentView(https://www.wendangku.net/doc/f218498700.html,yout.main); if (savedInstanceState != null) { getStateManager().restoreFromState(savedInstanceState); } else { initializeByIntent(); } } private void initializeByIntent() { Intent intent = getIntent(); String action = intent.getAction(); if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)){ startGetContent(intent); } else if(Intent.ACTION_PICK.equalsIgnoreCase(action)) { // We do NOT really support the PICKintent. Handle it as // the GET_CONTENT. However, we needto translate the type // in the intent here. Log.w(TAG, "action PICK is notsupported"); String type =Utils.ensureNotNull(intent.getType()); if(type.startsWith("vnd.android.cursor.dir/")) { if(type.endsWith("/image")) intent.setType("image/*"); if(type.endsWith("/video")) intent.setType("video/*"); } startGetContent(intent);

Android系统分析

Android操作系统分析 穆英华 基于Linux内核的Android操作系统尽管非常年轻,却已经占领了智能手机9%的市场,而且还在向其它移动平台及嵌入式领域迅速扩张着。下图为2010年一季度的智能手机操作系统占有率统计。在国内外制造商纷纷推出基于Android的产品、Android Market中的应用程序飞速增长的背景下,有必要对Android操作系统的情况进行调研,对比其与Midinux的优劣势、估计其机遇或威胁。本文将从以下几个方面分析Android:目标用户群、支持硬件架构、平台技术架构、应用程序数量、未来发展方向。 一.目标用户群 覆盖高、中、低端智能手机用户是Android的主要目标,尤其是市场上基于ARM11处理器的智能手机已经降到1000元人民币的价格,让低成本的硬件配置也可以运行Android系统,更使得Android从中高端扩展到低端成为可能。除智能手机外,Android已经渗透到了平板电脑、上网本,乃至汽车电子、机顶盒、电子相册、无绳电话等各移动平台和嵌入式产品领域。 对于Android的智能手机和平板电脑用户,Android Market中种类丰富和数量众多的应用程序是其选择Android的重要原因,没有众多可选择的第三方应用程序,操作系统就是再性能优异,也不会对用户有任何杀伤力。这一点类似于苹果的iOS,但总体来说,Android 的用户不会像苹果用户那样忠诚、他们中的很大一部分也不会像苹果用户那样为数码产品花费那么多金钱,可以说Android更大众一些。 二. 支持硬件架构 1.支持的硬件架构 目前Android已经移植到了ARM、X86、M IP S各体系架构中的很多处理器核、处理器芯片、以及更多的板级结构上,对PPC等体系架构的移植也早已开始。如高通、三星等芯片制造商推出的基于ARM C ortex-A8处理器核及P o w er V R显示核心的处理器芯片早已移植Android成功,并被联想的Le Ph one、魅族的M9等许多手机采用,多核的C ortex-A9也蓄势待发。随着

最全的Android源码目录结构详解

最全的Android源码目录结构详解 收藏 转自http: 67."html Android 2."1 |-- Makefile |-- bionic(bionic C库) |-- bootable(启动引导相关代码) |-- build(存放系统编译规则及generic等基础开发包配置)|-- cts(Android 兼容性测试套件标准) |-- dalvik |-- development |-- external |-- frameworks |-- hardware |-- out |-- packages |-- prebuilt |-- sdk |-- system

`-- vendor bionic目录 |-- libc ||-- arch-arm ||-- arch-x86 ||-- bionic ||-- docs ||-- include ||-- kernel ||-- private ||-- stdio ||-- stdlib ||-- string ||-- tools ||-- tzcode ||-- unistd |`-- zoneinfo |-- libdl |-- libm ||-- alpha ||-- amd64(dalvik JAVA虚拟机)

(应用xx相关) (android使用的一些开源的模组) (核心框架——java及C++语言) (部分厂家开源的硬解适配层HAL代码) (编译完成后的代码输出与此目录) (应用程序包) (x86和arm架构下预编译的一些资源) (sdk及模拟器) (底层文件系统库、应用及组件——C语言)(厂商定制代码)(Cxx) ARM架构,包含系统调用汇编实现) x86架构,包含系统调用汇编实现) (由C实现的功能,架构无关) (文档) (头文件) (Linux内核中的一些头文件) (?nesbsd系统相关,具体作用不明) (?一些私有的头文件) (stdio实现) (stdlib实现) (string函数实现)

Android 5.0 Camera系统源码分析(5):Camera预览3A流程

Android 5.0 Camera系统源码分析(5):Camera预览3A流程 1. 前言 本文分析的是Android Hal层的源码,硬件平台基于mt6735。之前几篇讲的预览流程中3A 相关的环节都忽略了,现在重新整理下。 3A指的是Auto Exposure,Auto Focus,Auto White Balance。这三个一起放上来代码实在太多了,这里将重点记录AF的代码。AF的部分工作是由ISP完成的,而ISP的大部分代码mtk都没有开放给我们,比如ISP是如何计算得到对焦位置信息的,但得到对焦位置之后怎么操作对焦马达的代码我们是看得到的,所以涉及到ISP的一些代码将被略过 2. 初始化3A 3A的初始化在DefaultCam1Device的onInit函数里面开始,之前在camera打开流程里面已经提到过 bool DefaultCam1Device:: onInit() { ...... // (1) Open 3A mpHal3a = NS3A::IHal3A::createInstance( NS3A::IHal3A::E_Camera_1, getOpenId(), LOG_TAG); ...... } 构造一个Hal3A对象,看下Hal3A::createInstance的实现 Hal3A* Hal3A:: createInstance(MINT32 i4SensorDevId, MINT32 i4SensorOpenIndex) { switch (i4SensorDevId) { case SENSOR_DEV_MAIN: Hal3ADev::getInstance()->init(i4SensorDevId, i4SensorOpenIndex); return Hal3ADev::getInstance();

最全的Android源码目录结构详解

最全的Android源码目录结构详解收藏 转自https://www.wendangku.net/doc/f218498700.html,/a/android/2010/0622/67.html Android 2.1 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external (android使用的一些开源的模组) |-- frameworks (核心框架——java及C++语言) |-- hardware (部分厂家开源的硬解适配层HAL代码) |-- out (编译完成后的代码输出与此目录) |-- packages (应用程序包) |-- prebuilt (x86和arm架构下预编译的一些资源) |-- sdk (sdk及模拟器) |-- system (底层文件系统库、应用及组件——C语言) `-- vendor (厂商定制代码) bionic 目录 |-- libc (C库) | |-- arch-arm (ARM架构,包含系统调用汇编实现) | |-- arch-x86 (x86架构,包含系统调用汇编实现) | |-- bionic (由C实现的功能,架构无关) | |-- docs (文档) | |-- include (头文件) | |-- inet (?inet相关,具体作用不明) | |-- kernel (Linux内核中的一些头文件) | |-- netbsd (?nesbsd系统相关,具体作用不明) | |-- private (?一些私有的头文件) | |-- stdio (stdio实现) | |-- stdlib (stdlib实现) | |-- string (string函数实现) | |-- tools (几个工具) | |-- tzcode (时区相关代码) | |-- unistd (unistd实现) | `-- zoneinfo (时区信息) |-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,) | |-- alpha (apaha架构) | |-- amd64 (amd64架构)

android天气预报源代码解析

通过google接口在Android中实现天气预报效果 Android可以通过google实现获取指定经纬度位置或者某一个城市的天气信息。如果是根据经纬度查询天气信息,需要对精度为进行转换,例如lat值为31.174165,需要过滤掉小数点,变为31174165传到接口中,维度也一样处理,处理后传 给https://www.wendangku.net/doc/f218498700.html,/ig/api?weather=,,,31174165,121433841既可以获取数据。这里要注意一个问题,如果大家获取的经纬度序列很长,直接去掉小数点,有时候也无法获取天气信息,例如40.478224838152528,124.97828006744385,去掉小数点后,传到参数位置,无法获取值,需要大家将经纬度按下面方式转换一下,只取小数点后6位就可以了。int latI = (int) (lat * 1E6); int lonI = (int) (lon * 1E6); 下面的例子演示了根据输入城市,获取该城市的天气预报,Weather.java的61行,是根据经纬度获取天气信息。 工程结构:

Weather.java类 package com.AndroidWeather; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle;

android应用程序源码结构分析

1、src文件夹存放源码。 2、gen下有跟src中一样的包文件,内部有一个名为R.java类,它是自动生成的一个类;该目录不用我们开发人员维护,但又非常重要的目录。该目录用来存放由Android 开发工具所生成的目录。该目录下的所有文件都不是我们创建的,而是由系统自动生成的。这个R,javav文件是只读类型,用户一般式不需要修改的! R.java 文件中默认有attr 、drawable 、layout 、string 等四个静态内部类,每个静态内部类分别对应一种资源,layout 静态内部类对应layout 中的界面文件main.xml,其中每个静态内部类中的静态常量分别定义一条资源标识符,如“ publicstatic final int main =0x7f030000; ” 用一个十六进制的数来代表常量,当开发者在res文件夹下添加或删除任何一个文件或一个属性,R.java都会随之进行更新! 3、android 2.3.3/ 文件夹表明了开发环境的版本,内部存放Android 自身的jar 包。 4、assets/该目录用来存放应用中用到的类似于视频文件、MP3 一些媒体文件。 5、res/ 该目录为资源目录。该目录可以存放一些应用图标、界面文件、应用中用到的文字信息等。 res/目录下有三个dawable 文件夹,区别只是将图标按分辨率高低来放入不同的目录中,drawable-hdpi存放高分辨率的图标,drawable-mdpi存放中等分辨率的图标, drawable-ldpi存放低分辨率的图标。程序运行时可以根据手机分辨率的高低选取相应目录下的图标。 值得注意的是: 如果是老版本的,比如是1.5版本的,res下的drawable文件夹只有一个,如需修改需要手动添加, res/目录下layout/的文件main.xml是布局文件, main.xml < LinearLayout xmlns:android = "https://www.wendangku.net/doc/f218498700.html,/apk/res/android" android:orientation = "vertical" android:layout_width = "fill_parent"

Android程序启动过程源码分析

Android应用程序启动过程源代码分析 分类:Android 2011-08-19 00:58 5447人阅读评论(40) 收藏举报 前文简要介绍了Android应用程序的Activity的启动过程。在Android系统中,应用程序是由Activity组成的,因此,应用程序的启动过程实际上就是应用程序中的默认Activity 的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程。 在上一篇文章Android应用程序的Activity启动过程简要介绍和学习计划中,我们举例子说明了启动Android应用程序中的Activity的两种情景,其中,在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来。这种启动方式的特点是会启动一个新的进程来加载相应的Activity。这里,我们继续以这个例子为例来说明Android应用程序的启动过程,即MainActivity的启动过程。 MainActivity的启动过程如下图所示:

点击查看大图下面详细分析每一步是如何实现的。 Step 1. Launcher.startActivitySafely

在Android系统中,应用程序是由Launcher启动起来的,其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会Launcher的界面上出现一个相应的图标,点击这个图标时,Launcher就会对应的应用程序启动起来。 Launcher的源代码工程在packages/apps/Launcher2目录下,负责启动其它应用程序的源代码实现在src/com/android/launcher2/Launcher.java文件中: view plaincopy to clipboardprint? 1./** 2.* Default launcher application. 3.*/ 4.public final class Launcher extends Activity 5. implements View.OnClickListener, OnLongClickListener, LauncherMod el.Callbacks, AllAppsView.Watcher { 6. 7. ...... 8. 9. /** 10. * Launches the intent referred by the clicked shortcut. 11. * 12. * @param v The view representing the clicked shortcut. 13. */ 14. public void onClick(View v) { 15. Object tag = v.getTag(); 16. if (tag instanceof ShortcutInfo) { 17. // Open shortcut 18. final Intent intent = ((ShortcutInfo) tag).intent; 19. int[] pos = new int[2]; 20. v.getLocationOnScreen(pos); 21. intent.setSourceBounds(new Rect(pos[0], pos[1], 22. pos[0] + v.getWidth(), pos[1] + v.getHeight())); 23. startActivitySafely(intent, tag); 24. } else if (tag instanceof FolderInfo) { 25. ...... 26. } else if (v == mHandleView) {

Android锁屏与解屏相关代码分析

我觉得对于普通人来说,最常见的是Android解屏的界面,然后应该是Home 界面。今天就来分析一下解屏界面的相关代码(以索爱的解锁界面为例)。 首先看解屏的界面,我把解屏的界面分为两个部分,最上部是status Bar,下面是LockScreenSemc,在LockScreenSemc上有一个可供滑动解锁的界面,每个界面对应的类如图所示。

两个类所在包: com.Android.internal.policy.impl.LockScreenSemc.java com.Android.internal.widget.SlidingTabSemc.java SlidingTabSemc.java分析: 分析我们的Touch在SlidingTabSemc 上产生的效果,主要看onTouchEvent ()的处理。 ACTION_DOWN 时会调用disableButtonPress(),产生手指点击时的动画效果。 ACTION_MOVE 时会调用moveControl()产生图片跟随手指移动的效果。 ACTION_UP 时会判断移动的位置是否已经到了,可以触发Trigger的程度,如果到了,则调用dispatchTriggerEvent,通知在SlidingTabSemc上的Trigger Listener。由于SlidingTabSemc上的Trigger Listener是在LockScreenSemc里实现的,所以会代用到LockScreenSemc中。

LockScreenSemc.java分析: 代码中有一行:private SlidingTabSemc mSelector; 将SlidingTabSemc 作为它的一个属性值, 另外此类实现了SlidingTabSemc.OnTriggerListener。这个listener用来执行我们从左到右或者从右到左的滑动,在构造函数中有 mSelector.setOnTriggerListener(this);这样我们在SlidingTabSemc上的滑动会调用到public void onTrigger(View v, int whichHandle)方法中。 onTrigger的执行为两个分支,一个为从右滑向左,执行了mAudioManager.setRingerMode(),设置了声音的模式,并更新右边声音的图片。另一个为从左滑向右,执行的是mCallback.goToUnlockScreen();这个mCallback 是何方神圣呢?它是KeyguardScreenCallback类型,并且在LockScreenSemc初始化的时候传进来的,跟踪后我们发现,LockScreenSemc是类LockPatternKeyguardView的一个属性值(private View mLockScreen);KeyguardScreenCallback的实现在LockPatternKeyguardView中。 LockPatternKeyguardView中LockPatternKeyguardView的逻辑是,如果用户在设置->位置和安全->设置屏幕锁定中设置了解锁画面,则调用了updateScreen(Mode.UnlockScreen)进入相应的解锁画面,否则调用:getCallback().keyguardDone(true); 这个getCallback() 返回的是KeyguardViewMediator。 KeyguardViewMediator 中keyguardDone()方法,最终会给Handler发送KEYGUARD_DONE 的消息,Handler会执行handleKeyguardDone()方法,在方法中会调用handleHide(),这个函数会将我们的LockScreenSemc给隐藏。 总结:总体来说,上面提到的类基本上可以这么认为,SlidingTabSemc属于LockScreenSemc,LockScreenSemc属于LockPatternKeyguardView, LockPatternKeyguardView 属于KeyguardViewManager,KeyguardViewManager 来统管所有与锁解屏相关的操作,另外通过KeyguardViewMediator,来实现KeyguardViewManager和PhoneWindowManager之间的交互与通信,如图所示: 画面的更新实现

相关文档
相关文档 最新文档