android50源码分析
Android中对于图形界面以及多媒体的相关操作比较容易实现。而且对于大多数
手机
用户来说,他们主要也就是根据这些方面的功能来对系统那个进行修改。我们可以通过本文介绍的Android多媒体框架的源码解读,来具体分析一下这方面的基本知识。
Android多媒体框架的代码在以下目录中:external/opencore/。这个目录是Android多媒体框架的根目录,其中包含的子目录如下所示:
* android:这里面是一个上层的库,它基于PVPlayer和PVAuthor的SDK实现了一个为Android使用的Player和Author。
* baselibs:包含数据结构和线程安全等内容的底层库
* codecs_v2:这是一个内容较多的库,主要包含编解码的实现,以及一个OpenMAX的实现
* engines:包含PVPlayer和PVAuthor引擎的实现
* extern_libs_v2:包含了khronos的OpenMAX的头文件
* fileformats:文件格式的据具体解析(parser)类
* nodes:编解码和文件解析的各个node类。
* oscl:操作系统兼容库
* pvmi: 输入输出控制的抽象接口
* protocols:主要是与网络相关的RTSP、RTP、HTTP等协议的相关内容
* pvcommon:pvcommon库文件的Android.mk文件,没有源文件。
* pvplayer:pvplayer库文件的Android.mk文件,没有源文件。
* pvauthor:pvauthor库文件的Android.mk文件,没有源文件。
* tools_v2:编译工具以及一些可注册的模块。
Splitter的定义与初始化
以wav的splitter为例,在fileformats目录下有解析wav文件格式的pvwavfileparser.cpp文件,在nodes目录下有pvmf_wavffparser_factory.cpp,pvmf_wavffparser_node.h, pvmf_wavffparser_port.h等文件。
我们由底往上看,vwavfileparser.cpp中的PV_Wav_Parser类有InitWavParser(),GetPCMData(),RetrieveFileInfo()等解析wav格式的成员函数,此类应该就是最终的解析类。我们搜索PV_Wav_Parser类被用到的地方可知,在PVMFWAVFFParserNode类中有PV_Wav_Parser的一个指针成员变量。
再搜索可知,PVMFWAVFFParserNode类是通过PVMFWAVFFParserNodeFactory的CreatePVMFWAVFFParserNode()成员函数生成的。而CreatePVMFWAVFFParserNode()函数是在PVPlayerNodeRegistry::PVPlayerNodeRegistry()类构造函数中通过PVPlayerNodeInfo类被注册到Oscl_Vector<PVPlayerNodeInfo, OsclMemAllocator> 的vector中,在这个构造函数中,AMR,mp3等node也是同样被注册的。
由上可知,Android多媒体框架中对splitter的管理也是与ffmpeg等类似,都是在框架的初始化时注册的,只不过Opencore注册的是每个splitter的factory函数。
综述一下splitter的定义与初始化过程:
每个splitter都在fileformats目录下有个对应的子目录,其下有各自的解析类。
每个splitter都在nodes目录下有关对应的子目录,其下有各自的统一接口的node类和node factory类。
播放引擎PVPlayerEngine类中有PVPlayerNodeRegistry iPlayerNodeRegistry成员变量。
在PVPlayerNodeRegistry的构造函数中,将 AMR, AAC, MP3等splitter的输入与输出类型标示和node factory类中的create node与release delete接口通过PVPlayerNodeInfo类push到Oscl_Vector<PVPlayerNodeInfo, OsclMemAllocator> iType成员变量中。
当前Splitter的匹配过程
PVMFStatus PVPlayerNodeRegistry::QueryRegistry(PVMFFormatType& aInputType, PVMFFormatType& aOutputType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids)函数的功能是根据输入类型和输出类型,在已注册的node vector中寻找是否有匹配的node,有的话传回其唯一识别标识PVUuid。
从QueryRegistry这个函数至底向上搜索可得到,在android中splitter的匹配过程如下:
android_media_MediaPlayer.cpp之中定义了一个JNINativeMethod(java本地调用方法)类型的数组gMethods,供java代码中调用MultiPlayer类的setDataSource成员函数时找到对应的c++函数
1.{"setDataSource", "(Ljava/lang/String;)V", (void *)
android_media_MediaPlayer_setDataSource},
2.static void android_media_MediaPlayer_setDataSource
(JNIEnv *env, jobject thiz, jstring path)
此函数中先得到当前的MediaPlayer实例,然后调用其setDataSource函数,传入路径
3.status_t MediaPlayer::setDataSource(const char *url)
此函数通过调getMediaPlayerService()先得到当前的MediaPlayerService, const sp<IMediaPlayerService>& service(getMediaPlayerService());
然后新建一个IMediaPlayer变量, sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length));
在sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)中
调status_t MediaPlayerService::Client::setDataSource(const char *url)函数,Client是MediaPlayerService的一个内部类。
在MediaPlayerService::Client::setDataSource中,调sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
生成一个继承自MediaPlayerBase的PVPlayer实例。
‘贰’ 怎样评价罗升阳的android系统源代码分析
我干了3年Android sdk开发,觉得到了瓶劲没法更进一步,于是花了一年多点时间,大概摸到点门径。根据前辈的经验,Android底层完全入门需要两年。 先说下我的入门过程: 第零步,下载源码,我下的4.2的,框架层源码10G,内核2G多,ctags给框架层建的标签文件都有600M,当时让我有点震撼,用的vim+ctags+cscope来阅读,还算不错,架构挺清晰的。 第一步,我找到了一本好书《Android的设计与实现 第一卷》它讲了Android框架层的启动,初始化,服务框架初始化,Binder,消息循环,PackageManagerService,ActivityManagerService。据作者说后面会出讲UI子系统的第二卷,拭目以待。其实这本书看了几十页我就发现需要第二步的知识,否则看不下去,于是跳去第二步。 第二步,学习linux系统编程,在看《Android的设计与实现》的时候我发现,框架层的Native部分,全是Linux编程。为了掌握这部分知识,我花了4个月学习了《Linux系统编程手册》(TLPI)这本1000多页的书,我以前是搞WIndows文件系统这块的,所以C语言还比较熟,TLPI的习题很有意思,量也比较大,坚持下来还是收获很多。 第三步,花了4个月学习了一些Linux内核的知识,看了LKD,PLKA看了一半多。越学越没底,觉得不懂得越来越多,不过这个也正常,只有靠慢慢磨,估计以后要不断的磨这块。 第四步,回头看Android源码,这次一口气看完了《Android的设计与实现 第一卷》,终于对框架层有了谱。同时真的数次把我看晕,前面看Linux内核源码都没这么晕,不断在Java层和Native层之间跳有点磨脑浆。其中我又觉得Java的基础没有打太牢,回去补了一个月的《Core Java》第八版。但是这书没有涉及UI子系统,于是又看了《Android内核剖析》 第五步,《Android内核剖析》(这本书实际上是讲框架层的,作者也是个搞嵌入式的,所以他在写框架层的时候文笔不太好,很罗嗦,不过还是有很多看点,到他后来写做ROM,玩开发板时估计是说到了他的本行,一下子遛起来了看得出还是挺有水平的,这本书知识有点旧毕竟讲的是2.3很多代码已经过时,但是作者很多点子很有参考价值)这本书讲UI子系统和按键/触摸消息处理系统还是很有分量的,尤其13章View绘制那里,结合源码研究很有收获。而后面他讲编译框架和ROM相关的东西都是挺宝贵的资料。 第六步,为了再补一下其他诸如电源管理模块等子系统的知识看了,《深入理解android》系列,个人认为这个系列看起来有点不太舒服,不过作为补充印证还是比较有价值。 第七步,《Android系统源代码情景分析》,罗升阳的源码分析大作,比《Android的设计与实现》分析得更细致,但缺点是涉及到模块比较少,选用的源码也比《Android的设计与实现》更旧一点。看完书后需要去研究作者的博客,东西挺多的,一定让你满意。 第八步,买块开发板自己玩。这步我还没走到,原因是我觉得我还差点准备知识。可能要再几个月,到时准备入块6410或者树莓派。 最后,由于我11年以前都是搞Windows这块的,所以对Linux知识不是很了解,不得已看了这么些书,如果是一直做Linux的人,很多步骤估计可以省掉了。直接上源码才是正道。 我本身做着移动GIS开发的工作,学框架层全是因为兴趣,但招聘平台Android框架层开发人员还是蛮有竞争力的有不少定制ROM,智能电视的工作都处于人才难求状态,毕竟有一定的门槛,现在各种ios培训,让奔着钱干开发的人纷纷涌入,而ios只能干sdk开发的缺点就暴露出来了,一堆新手老手,菜鸟大牛全挤在SDK开发这块,我觉得不太妙。 反观Android这边,虽然入门菜鸟没有搞ios来钱,但是可持续性很好,从sdk-》框架》驱动》内核这样干下去。干着干着发现自己渐渐变成了Linux开发者/嵌入式开发者的人也不少,新人,老手,菜鸟大牛各居其位,层次性很好。 转载
‘叁’ 关于Android 平台开发相关的有哪些推荐书籍
推荐十本Android开发畅销书籍:
1. 《Android基础教程》本书是一部关于 android开发的基础教程,采用由浅入深、循序渐进的方式讨论android。书中还结合数独游戏等实例更加形象生动地讲解了 android开发的基本流程,且每章最后都有一个 “快速阅读指南 ”,更加方便了读者的阅读。. 本书内容完整丰富,具有较强的通用性,读者都能通过本书快速学习 android开发,提高相关技能。
2. 《Android应用开发揭秘》(累计印刷6次,内容已更新至Android 2.2,版权输出至台湾)这是一本参考手册,内容的完整性和系统性几乎无可挑剔,可作为广大Android开发者的案头必备书;这是一部权威指南,基础知识部分翔实而丰富,高级知识部分深入且饱含最佳实践,能从本质上提升开发者对Android的理解和开发水平。尤为值得一提的是,Android 2.0中新增了大量激动人心的新特性,不仅支持多点触摸设备、软键盘,而且还支持多账户在线管理、蓝牙……作为国内第一本基于Android 2.0的着作,本书可谓极具前瞻性,第一时间将这些新特性完美地呈现给了广大读者。
3. 《Google Android SDK开发范例大全》(09年度畅销榜NO.10)(台湾天珑书局09年超级畅销书)本书以android手机应用程序开发为主题,通过130多个范例全面且深度地整合了手机、网络及服务等多个开发领域,为读者提高程序设计功力提供了很大的帮助。. 全书共分10章,主要以范例集的方式来讲述android的知识点,详细介绍了开发android的人机交互界面、android常用的开发控件、使用android手机收发短信等通信服务、开发android手机的自动服务功能和娱乐多媒体功能以及整合android与aoogle强大的网络服务等内容,随书光盘中包括了所有范例的程序代码。
4. 《Google Android SDK开发范例大全(第2版)》 本书在上一版的基础上,以android手机应用程序开发(采用android sdk 2.1)为主题,通过160多个范例全面且深度地整合了手机、网络及服务等多个开发领域,为读者提高程序设计功力提供了很大的帮助。全书共分10章,主要以范例集的方式来讲述android的知识点,详细介绍了开发android的人机交互界面、android常用的开发控件、使用android手机收发短信等通信服务、开发android手机的自动服务功能和娱乐多媒体功能以及整合android与aoogle强大的网络服务等内容。随书光盘中包括了所有范例的程序代码。本书讲述由浅入深,由android的基础知识到实际开发应用,结构清晰、语言简洁,非常适合android的初学者和android的进阶程序开发者阅读参考。
5. 《Android/OPhone开发完全讲义》(此书版权已经输出到台湾)推荐这本书有两个原因:一是移动开发的广阔前景,使得越来越多的企业、开发者投入其中。相比iPhone而言,Android平台的开放性以及国内市场的广阔性,使得它更有代表性;二是作者李宁,他写作的理论性和实践性兼备,以及对技术的孜孜追求,使得这本书在Android开发的实战方面很具代表性。也希望读者朋友和我一样能从这本书中获益。
6. 《Android系统原理及开发要点详解》 本书全面介绍开放的移动电话平台android系统,包括android系统中的linux驱动、本地框架、java框架和java应用4个层次。本书内容以知识性内容为纲,重点关注开发要点,各个部分内容注重相互照应,按照清晰的思路向读者介绍整个android系统的原理和开发方法。本书按照android系统的框架和各个子系统的主线,重点介绍开发android应用程序和构建硬件抽象层。其内容涵盖了android应用程序开发和android系统移植构建手机系统两大方面。本书既适合从事android各个层次开发的工程师阅读,也适合通用嵌入式linux系统的学习者使用。
7. 《深入浅出Google Android》(示例生动丰富,理论和实践完美结合)本书是国内最早的android开发团队的集体智慧结晶,真正完全基于android最新的sdk 1.5,内容详实,示例生动丰富,包含大量示例代码,可操作性强。它不仅涵盖了android平台从基础概念到高级应用的所有主题,而且深入浅出地介绍了几种常见的android项目,具有很强的参考价值。特别是在本书的第10、11章重点介绍了android sdk 1.5引入的最为重要的三个特性,即桌面部件、实时文件夹、虚拟键盘与输入法应用的开发方法。.. 通过本书,读者可以迅速掌握android平台来构建应用程序,成为android开发高手,跻身新技术的弄潮儿。
8. 《Google Android开发入门与实战》(09年度畅销榜TOP50)(附赠400分钟高清教学视频,涵盖5大商业案例完整源代码)本书内容上涵盖了用android开发的大部分场景,从android基础介绍、环境搭建、sdk介绍、market使用,到应用剖析、组件介绍、实例演示等方面。从技术实现上,讲解了5个android平台下的完整综合实例及源代码分析,分别是rss阅读器、基于google map的个人gps、豆瓣网(web 2.0)客户端、在线音乐播放器、手机信息查看助手。本书注重对实际动手能力的指导,在遵循技术研发知识体系的严密性同时,在容易产生错误、不易理解的环节配以了翔实的开发情景截图,并将重要的知识点和开发技巧以“小实验”、“小提醒”、“小知识”、“注意”等的活泼形式呈现给读者。在程序实例的讲解方面,主要将实例安插在android开发的精髓知识章节,这为初学者学习与实践结合提供了很好的指导。. 本书配套有400多分钟的全程开发视频光盘,指导读者快速、无障碍地学通android实战开发技术。
9. 《精通Android游戏开发》(将本地PC游戏轻松移植到Android的秘技) 本书讨论如何将pc 上的3d 游戏移植到android 平台。作者从必备的技能和软件工具入手,逐步介绍如何从头构建纯java 游戏,如何混合使用opengl 3d 图形和jni,并以真实的pc游戏wolfenstein 3d和doom为例,介绍如何融合java 的优雅设计和c 的强大功能,使混合游戏达到最佳性能。本书适合熟悉android 平台的开发人员阅读。
10. 《人人都玩开心网:Ext JS+Android+SSH整合开发Web与移动SNS》 本书的主旨为,以开心网为例实现web版和android版的sns应用。本书分为四篇,前三篇主要实现了web版的开心网系统。其中重点介绍了ext js技术,包括ext js的核心组件、对话框、表单组件、布局、数据校验、表格、菜单、树组件等技术。本书的最后一篇实现了android版的开心网,并介绍了与android版开心网相关的技术,包括button、textview、edittext、imageview、gridview等android组件。本书适于以下几类人群:了解传统的web应用程序的开发,希望使用ext js开发web程序的开发人员;了解基本的ext js程序的开发方法,想增加实践经验的开发人员;对ext js感兴趣,想进一步提高ext js开发技能的读者;对android感兴趣,想从事android开发的读者;想开发基于android客户端的c/s程序,但对开发流程不了解的读者。
‘肆’ 做jni开发android系统源码怎么分析
Android中JNI是编译so库的源代码,编译成功后会生成SO库,android中最终是使用SO库的。
1.android的NDK开发需要在linux下进行: 因为需要把C/C++编写的代码生成能在arm上运行的.so文件,这就需要用到交叉编译环境,而交叉编译需要在linux系统下才能完成。
2.安装android-ndk开发包,这个开发包可以在google android 官网下载: 通过这个开发包的工具才能将android jni 的C/C++的代码编译成库
3.android应用程序开发环境: 包括eclipse、java、 android sdk、 adt等。
‘伍’ 从源码中浅析Android中怎么利用attrs和styles定义控件
1.attrs.xml:
我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性
你可以找到attrs.xml这个文件,打开它,全选,右键->Show In->OutLine。可以看到整个文件的解构
我们大概可以看出里面是Android中的各种属性的声明,比如textStyle这个属性是这样定义的:
Java代码
<!-- Default text typeface style. -->
<attr name="textStyle">
<flag name="normal" value="0" />
<flag name="bold" value="1" />
<flag name="italic" value="2" />
</attr>
那么现在你知道,我们在写android:textStyle的时候为什么会出现normal,bold和italic这3个东西了吧,就是定义在这个地方。
再看看textColor:
Java代码
<!-- Color of text (usually same as colorForeground). -->
<attr name="textColor" format="reference|color" />
format的意思是说:这个textColor可以以两种方式设置,要么是关联一个值,要么是直接设置一个颜色的RGB值,这个不难理解,因为我们可以平时也这样做过。
也就是说我们平时在布局文件中所使用的各类控件的属性都定义在这里面,那么这个文件,除了定义这些属性外还定义了各种具体的组件,比如TextView,Button,SeekBar等所具有的各种特有的属性
比如SeekBar:
Java代码
<declare-styleable name="SeekBar">
<!-- Draws the thumb on a seekbar. -->
<attr name="thumb" format="reference" />
<!-- An offset for the thumb that allows it to extend out of the range of the track. -->
<attr name="thumbOffset" format="dimension" />
</declare-styleable>
也许你会问SeekBar的background,等属性怎么没有看到?这是因为Android中几乎所有的组件都是从View中继承下来的,SeekBar自然也不例外,而background这个属性几乎每个控件都有,因此被定义到了View中,你可以在declare-styleable:View中找到它。
总结下,也就是说attrs.xml这个文件定义了布局文件中的各种属性attr:***,以及每种控件特有的属性declare-styleable:***
2.styles.xml:
刚才的attrs.xml定义的是组件的属性,现在要说的style则是针对这些属性所设置的值,一些默认的值。
这个是SeekBar的样式,我们可以看到,这里面设置了一个SeekBar的默认的样式,即为attrs.xml文件中的各种属性设置初始值
Java代码
<style name="Widget.SeekBar">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
<item name="android:thumb">@android:drawable/seek_thumb</item>
<item name="android:thumbOffset">8dip</item>
<item name="android:focusable">true</item>
</style>
这个是Button的样式:
Java代码
<style name="Widget.Button">
<item name="android:background">@android:drawable/btn_default</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
<item name="android:textColor">@android:color/primary_text_light</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
</style>
有了属性和值,但是这些东西是如何关联到一起的呢?它们如何被android的framework层所识别呢?
3.组件的源码
我们看下TextView的源码:
Java代码
public TextView(Context context) {
this(context, null);
}//这个构造器用来给用户调用,比如new TextView(this);
public TextView(Context context,
AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.textViewStyle);
}
public TextView(Context context,
AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);//为用户自定义的TextView设置默认的style
mText = "";
//设置画笔
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = getResources().getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(
getResources().getCompatibilityInfo().applicationScale);
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHighlightPaint.setCompatibilityScaling(
getResources().getCompatibilityInfo().applicationScale);
mMovement = getDefaultMovementMethod();
mTransformation = null;
//attrs中包含了这个TextView控件在布局文件中定义的属性,比如android:background,android:layout_width等
//com.android.internal.R.styleable.TextView中包含了TextView中的针对attrs中的属性的默认的值
//也就是说这个地方能够将布局文件中设置的属性获取出来,保存到一个TypeArray中,为这个控件初始化各个属性
TypedArray a =
context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
int textColorHighlight = 0;
ColorStateList textColor = null;
ColorStateList textColorHint = null;
ColorStateList textColorLink = null;
int textSize = 15;
int typefaceIndex = -1;
int styleIndex = -1;
/*
* Look the appearance up without checking first if it exists because
* almost every TextView has one and it greatly simplifies the logic
* to be able to parse the appearance first and then let specific tags
* for this View override it.
*/
TypedArray appearance = null;
//TextView_textAppearance不太了解为什么要这样做?难道是为了设置TextView的一些默认的属性?
int ap = a.getResourceId(com.android.internal.R.styleable.TextView_textAppearance, -1);
if (ap != -1) {
appearance = context.obtainStyledAttributes(ap,
com.android.internal.R.styleable.
TextAppearance);
}
if (appearance != null) {
int n = appearance.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = appearance.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.TextAppearance_textColorHighlight:
textColorHighlight = appearance.getColor(attr, textColorHighlight);
break;
case com.android.internal.R.styleable.TextAppearance_textColor:
textColor = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorHint:
textColorHint = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorLink:
textColorLink = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textSize:
textSize = appearance.getDimensionPixelSize(attr, textSize);
break;
case com.android.internal.R.styleable.TextAppearance_typeface:
typefaceIndex = appearance.getInt(attr, -1);
break;
case com.android.internal.R.styleable.TextAppearance_textStyle:
styleIndex = appearance.getInt(attr, -1);
break;
}
}
appearance.recycle();
}
//各类属性
boolean editable = getDefaultEditable();
CharSequence inputMethod = null;
int numeric = 0;
CharSequence digits = null;
boolean phone = false;
boolean autotext = false;
int autocap = -1;
int buffertype = 0;
boolean selectallonfocus = false;
Drawable drawableLeft = null, drawableTop = null, drawableRight = null,
drawableBottom = null;
int drawablePadding = 0;
int ellipsize = -1;
boolean singleLine = false;
int maxlength = -1;
CharSequence text = "";
CharSequence hint = null;
int shadowcolor = 0;
float dx = 0, dy = 0, r = 0;
boolean password = false;
int inputType = EditorInfo.TYPE_NULL;
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
//通过switch语句将用户设置的,以及默认的属性读取出来并初始化
switch (attr) {
case com.android.internal.R.styleable.TextView_editable:
editable = a.getBoolean(attr, editable);
break;
case com.android.internal.R.styleable.TextView_inputMethod:
inputMethod = a.getText(attr);
break;
case com.android.internal.R.styleable.TextView_numeric:
numeric = a.getInt(attr, numeric);
break;
//更多的case语句...
case com.android.internal.R.styleable.TextView_textSize:
textSize = a.getDimensionPixelSize(attr, textSize);//设置当前用户所设置的字体大小
break;
case com.android.internal.R.styleable.TextView_typeface:
typefaceIndex = a.getInt(attr, typefaceIndex);
break;
//更多的case语句...
}
通过上面的代码大概可以知道,每个组件基本都有3个构造器,其中只传递一个Context上下文的那个构造器一般用来在java代码中实例化使用。
比如你可以
Java代码
TextView tv = new TextView(context);
来实例化一个组件。
最终调用的是第3个构造器
Java代码
public TextView(Context context,
AttributeSet attrs,
int defStyle)
在这个构造器中为你设置了默认的属性attrs和值styles。关键不在这里,而是后面通过使用下面的代码
Java代码
TypedArray a =
context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
来将属性和值获取出来,放到一个TypeArray中,然后再利用一个switch语句将里面的值取出来。再利用这些值来初始化各个属性。这个View最终利用这些属性将这个控件绘制出来。
如果你在布局文件中定义的一个View的话,那么你定义的值,会被传递给构造器中的attrs和styles。也是利用同样的方式来获取出你定义的值,并根据你定义的值来绘制你想要的控件。
再比如其实Button和EditText都是继承自TextView。看上去两个控件似乎差异很大,其实不然。Button的源码其实相比TextView变化的只是style而已:
‘陆’ 有研究android系统源码的博客吗
我干了3年Android sdk开发,觉得到了瓶劲没法更进一步,于是花了一年多点时间,大概摸到点门径。根据前辈的经验,Android底层完全入门需要两年。
先说下我的入门过程:
第零步,下载源码,我下的4.2的,框架层源码10G,内核2G多,ctags给框架层建的标签文件都有600M,当时让我有点震撼,用的vim+ctags+cscope来阅读,还算不错,架构挺清晰的。
第一步,我找到了一本好书《Android的设计与实现 第一卷》它讲了Android框架层的启动,初始化,服务框架初始化,Binder,消息循环,PackageManagerService,ActivityManagerService。据作者说后面会出讲UI子系统的第二卷,拭目以待。其实这本书看了几十页我就发现需要第二步的知识,否则看不下去,于是跳去第二步。
第二步,学习Linux系统编程,在看《Android的设计与实现》的时候我发现,框架层的Native部分,全是Linux编程。为了掌握这部分知识,我花了4个月学习了《Linux系统编程手册》(TLPI)这本1000多页的书,我以前是搞WIndows文件系统这块的,所以C语言还比较熟,TLPI的习题很有意思,量也比较大,坚持下来还是收获很多。
第三步,花了4个月学习了一些Linux内核的知识,看了LKD,PLKA看了一半多。越学越没底,觉得不懂得越来越多,不过这个也正常,只有靠慢慢磨,估计以后要不断的磨这块。
第四步,回头看Android源码,这次一口气看完了《Android的设计与实现 第一卷》,终于对框架层有了谱。同时真的数次把我看晕,前面看Linux内核源码都没这么晕,不断在Java层和Native层之间跳有点磨脑浆。其中我又觉得Java的基础没有打太牢,回去补了一个月的《Core Java》第八版。但是这书没有涉及UI子系统,于是又看了《Android内核剖析》
第五步,《Android内核剖析》(这本书实际上是讲框架层的,作者也是个搞嵌入式的,所以他在写框架层的时候文笔不太好,很罗嗦,不过还是有很多看点,到他后来写做ROM,玩开发板时估计是说到了他的本行,一下子遛起来了看得出还是挺有水平的,这本书知识有点旧毕竟讲的是2.3很多代码已经过时,但是作者很多点子很有参考价值)这本书讲UI子系统和按键/触摸消息处理系统还是很有分量的,尤其13章View绘制那里,结合源码研究很有收获。而后面他讲编译框架和ROM相关的东西都是挺宝贵的资料。
第六步,为了再补一下其他诸如电源管理模块等子系统的知识看了,《深入理解android》系列,个人认为这个系列看起来有点不太舒服,不过作为补充印证还是比较有价值。
第七步,《Android系统源代码情景分析》,罗升阳的源码分析大作,比《Android的设计与实现》分析得更细致,但缺点是涉及到模块比较少,选用的源码也比《Android的设计与实现》更旧一点。看完书后需要去研究作者的博客,东西挺多的,一定让你满意。
第八步,买块开发板自己玩。这步我还没走到,原因是我觉得我还差点准备知识。可能要再几个月,到时准备入块6410或者树莓派。
最后,由于我11年以前都是搞Windows这块的,所以对Linux知识不是很了解,不得已看了这么些书,如果是一直做Linux的人,很多步骤估计可以省掉了。直接上源码才是正道。
我本身做着移动GIS开发的工作,学框架层全是因为兴趣,但招聘平台Android框架层开发人员还是蛮有竞争力的有不少定制ROM,智能电视的工作都处于人才难求状态,毕竟有一定的门槛,现在各种ios培训,让奔着钱干开发的人纷纷涌入,而ios只能干sdk开发的缺点就暴露出来了,一堆新手老手,菜鸟大牛全挤在SDK开发这块,我觉得不太妙。 反观Android这边,虽然入门菜鸟没有搞ios来钱,但是可持续性很好,从sdk-》框架》驱动》内核这样干下去。干着干着发现自己渐渐变成了Linux开发者/嵌入式开发者的人也不少,新人,老手,菜鸟大牛各居其位,层次性很好。
转载
‘柒’ 大牛们是怎么阅读 Android 系统源码的
由于工作需要大量修改framework代码, 在AOSP(Android Open Source Project)源码上花费了不少功夫, Application端和Services端都看和改了不少.
如果只是想看看一些常用类的实现, 在Android包管理器里把源码下载下来, 随便一个IDE配好Source Code的path看就行.
但如果想深入的了解Android系统, 那么可以看下我的一些简单的总结.
知识
Java
Java是AOSP的主要语言之一. 没得说, 必需熟练掌握.
熟练的Android App开发
Linux
Android基于Linux的, 并且AOSP的推荐编译环境是Ubuntu 12.04. 所以熟练的使用并了解Linux这个系统是必不可少的. 如果你想了解偏底层的代码, 那么必需了解基本的Linux环境下的程序开发. 如果再深入到驱动层, 那么Kernel相关的知识也要具备.
Make
AOSP使用Make系统进行编译. 了解基本的Makefile编写会让你更清晰了解AOSP这个庞大的项目是如何构建起来的.
Git
AOSP使用git+repo进行源码管理. 这应该是程序员必备技能吧.
C++
Android系统的一些性能敏感模块及第三方库是用C++实现的, 比如: Input系统, Chromium项目(WebView的底层实现).
硬件
流畅的国际网络
AOSP代码下载需要你拥有一个流畅的国际网络. 如果在下载代码这一步就失去耐心的话, 那你肯定没有耐心去看那乱糟糟的AOSP代码. 另外, 好程序员应该都会需要一个流畅的Google.
一台运行Ubuntu 12.04的PC.
如果只是阅读源码而不做太多修改的话, 其实不需要太高的配置.
一台Nexus设备
AOSP项目默认只支持Nexus系列设备. 没有也没关系, 你依然可以读代码. 但如果你想在大牛之路走的更远, 还是改改代码, 然后刷机调试看看吧.
高品质USB线
要刷机时线坏了, 没有更窝心的事儿了.
软件
Ubuntu 12.04
官方推荐, 没得选.
Oracle Java 1.6
注意不要用OpenJDK. 这是个坑, 官方文档虽然有写, 但还是单独提一下.
安装:
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer
sudo apt-get install oracle-java6-set-default
Eclipse
估计会有不少人吐槽, 为什么要用这个老古董. 其实原因很简单, 合适. 刚开始搞AOSP时, 为了找到效率最优的工具, 我尝试过Eclipse, IntelliJ IDEA, Vim+Ctags, Sublime Text+Ctags. 最终结果还是Eclipse. 主要优点有:
有语法分析 (快速准确的类, 方法跳转).
支持C++ (IntelliJ的C++支持做的太慢了).
嵌入了DDMS, View Hierarchy等调试工具.
为了提高效率, 花5分钟背下常用快捷键非常非常值得.
调整好你的classpath, 不要导入无用的代码. 因为AOSP项目代码实在是太多了. 当你还不需要看C++代码时, 不要为项目添加C++支持, 建索引过程会让你崩溃.
Intellij IDEA
开发App必备. 当你要调试系统的某个功能是, 常常需要迅速写出一个调试用App, 这个时候老旧的Eclipse就不好用了. Itellij IDEA的xml自动补全非常给力.
巨人的肩膀
这个一定要先读. 项目介绍, 代码下载, 环境搭建, 刷机方法, Eclipse配置都在这里. 这是一切的基础.
这个其实是给App开发者看的. 但是里面也有不少关于系统机制的介绍, 值得细读.
此老罗非彼老罗. 罗升阳老师的博客非常有营养, 基本可以作为指引你开始阅读AOSP源码的教程. 你可以按照博客的时间顺序一篇篇挑需要的看.但这个系列的博客有些问题:
早期的博客是基于旧版本的Android;
大量的代码流程追踪. 读文章时你一定要清楚你在看的东西在整个系统处于什么样的位置.
邓凡平老师也是为Android大牛, 博客同样很有营养. 但是不像罗升阳老师的那么系统. 更多的是一些技术点的深入探讨.
Android官方Issue列表. 我在开发过程中发现过一些奇怪的bug, 最后发现这里基本都有记录. 当然你可以提一些新的, 有没有人改就是另外一回事了.
一定要能流畅的使用这个工具. 大量的相关知识是没有人系统的总结的, 你需要自己搞定.
其它
代码组织
AOSP的编译单元不是和git项目一一对应的, 而是和Android.mk文件一一对应的. 善用mmm命令进行模块编译将节省你大量的时间.
Binder
这是Android最基础的进程间通讯. 在Application和System services之间大量使用. 你不仅要知道AIDL如何使用, 也要知道如何手写Binder接口. 这对你理解Android的Application和System services如何交互有非常重要的作用. Binder如何实现的倒不必着急看.
HAL
除非你对硬件特别感兴趣或者想去方案公司上班, 否则别花太多时间在这一层.
CyanogenMod
这是一个基于AOSP的第三方Rom. 从这个项目的wiki里你能学到很多AOSP官方没有告诉你的东西. 比如如何支持Nexus以外的设备.
DIA
这是一个Linux下画UML的工具, 能够帮你梳理看过的代码.
XDA
这里有最新资讯和最有趣的论坛.
想到了再补充.
‘捌’ 求《Android源码分析实录李忠良》全文免费下载百度网盘资源,谢谢~
《Android源码分析实录李忠良》网络网盘pdf最新全集下载:
链接: https://pan..com/s/1p1F5-Rb1wcS4XRPz_SJjrQ
简介:Android源码分析实录李忠良pdf全书共分为15章,分别讲述了分析JNI层、Android内存系统分析、Andmid虚拟机系统详解、IPC通信机制详解等,帮助读者能一步一步了解Android系统核心源码核心知识。
‘玖’ Android是什么语言编写看懂源码.它的开源代码是什么语言系统源码来说
简单来说 android 是以 linux kernel 内核为基础的操作系统,你可以看看 linux kernel 是用什么语言的就可以了。
‘拾’ 关于ANDROID自带的联系人CONTACTS源码的分析,求助
The Structure of the Contacts Mole
|——/packages/apps/Contacts/src/com/android/contacts
| |——ContactsListActivity.java
| |——ContactsManagementActivity.java
| |——DialtactsActivity.java
| |——ExportVCardActivity.java
| |——GroupsManagementActivity.java
| |——ImportVCardActivity.java
| |——ViewContactActivity.java
| |
| |——model
| | |——ContactsSource.java
| | |——EntityDelta.java
| | |——FallbackSource.java
| | |——Sources.java
| |
| |——ui
| | |——EditContactActiviry.java
| |
| |——widget
| | |——BaseContactEditorView.java
| | |——ContactEditorView.java
| | |——GenericEditorView.java
| | |——KindSectionView.java
| | |——PhotoEditorView.java
| | |——ReadOnlyContactEditorView.java
| |
| |——util
| |——Constants.java
| |——EmptyService.java
|
|——/packages/apps/Contacts/res
| |——drawable
| |——drawable-finger
| |——drawable-hdpi
| |——drawable-hdpi-finger
| |——drawable-mdpi
| |——drawable-mdpi-finger
| |——layout
| |——menu
| |——values
| |——values-zh-rCN
| |——AndroidManifest.xml
|
|——/packages/providers/ContactsProviders/src/com/android/providers/contacts
| |——ContactsDatabaseHelper.java
| |——ContactsProvider.java
| |——ContactsProvider2.java
| |——SQLiteContentProvider.java
|
|——The database address and name
|——data/data/com.android.providers.contacts/databases/contacts2.db