由于工作需要大量修改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
这里有最新资讯和最有趣的论坛.
想到了再补充.
2. Android操作系统是基于Linux Kernel是什么意思
每一个操作系统都有不同的内核。像Windows每个版本的内核都不同,而Mac OX用的是Unix的内核,Linux用的是Linux内核。而Android操作系统的内核是Linux,但是他不是一种Linux操作系统。
3. 如何编译android手机源码
编译android系统源码准备工作:
下载android源码
在windows上用gitbash ,git clone 下载代码
在linux上这样下载
创建~/bin目录,用来存放repo程序,如下:
$ cd ~
$ mkdir bin
初始化repo
repo是android对git的一个封装,简化了一些git的操作。
创建工程目录:
$ mkdir android
$ cd android
下载repo脚本并使其可执行:
$ curl http://android.git.kernel.org/repo >~/bin/repo
$ chmod a+x ~/bin/repo
repo初始化:
$ repo init -u git://android.git.kernel.org/platform/manifest.git
在此过程中需要输入名字和email地址。初始化成功后,会显示:
repo initialized in /android
在~/android下会有一个.repo的隐藏目录。
5)同步源代码
$ repo sync
这一步要很久很久。
安装linux系统,推荐ubuntu,图形界面
安装编译需要的支持包
$ sudo apt-get install git-core gnupg sun-java5-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev
安装java6.0
$ sudo apt-get install sun-java6-jdk
配置java环境
sudo gedit ~/.bashrc
末尾加上
JAVA_HOME=/usr/lib/jvm/java-6-sun
JRE_HOME=${JAVA_HOME}/jre
export ANDROID_JAVA_HOME=$JAVA_HOME
export CLASSPATH=.:${JAVA_HOME}/lib:$JRE_HOME/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export JAVA_HOME;
export JRE_HOME;
export CLASSPATH;
HOME_BIN=~/bin/
export PATH=${PATH}:${JAVA_PATH}:${HOME_BIN};
sudo source ~/.bashrc
是环境变量生效
编译android源码,并得到~/android/out目录
$ cd ~/andoird
$ make
这一过程很久。
这就编译结束了
4. 按android官网下载的android源码里面有linux内核kernel吗
从源代码树下载下来的最新Android源代码,是不包括内核代码的,也就是Android源代码工程默认不包含Linux Kernel代码,而是使用预先编译好的内核,也就是prebuilt/android-arm/kernel/kernel-qemu文件。
5. 如何将android linux烧到Raspberry Pi及其调试
一.Raspberry Pi入门向导。
首先下载Raspberry向导
二.准备工作
在进行以下步骤之前,需要先安装essential 工具包:
sudo apt-get install git-core gnupg flex bison gperf
build-essential zip curl zlib1g-dev gcc-multilib g++-multilib
libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev
libx11-dev lib32z-dev uboot-mkimage
三.怎样为Raspberry Pi构建android内核?
1.下载源代码
从ssh://<username>@elastos.org:29418/RaspberryPi/AndroidLinux.git下载源代码到<your_AndroidLinux_path>
此源代码来自https://github.com/Mathijsz/razdroid-kernel。
git clone ssh://<username>@elastos.org:29418/RaspberryPi/AndroidLinux.git kernel
2.下载ARM工具链
从ssh://<username>@elastos.org:29418/RaspberryPi/tools.git下载工具链
git clone ssh://<username>@elastos.org:29418/RaspberryPi/tools.git
3.编译内核
复制内核到config文件里
cd <your_AndroidLinux_path>
cp -v kernel.14.img.config .config
make -j8 ARCH=arm CROSS_COMPILE=$PWD/../tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
四.如何为Raspberry Pi构建android framework?
1.下载源代码
从ssh://<username>@elastos.org:29418/RaspberryPi/android4.git下载源代码到<your_android_path>
git clone ssh://<username>@elastos.org:29418/RaspberryPi/android4.git
2.构建android framework
命令如下:
cd <your_android_path>
source build/envsetup.sh
lunch
显示lunch菜单如下:
You’re building on Linux
Lunch menu… pick a combo:
1. full-eng
2. full_x86-eng
3. simulator
4. full_rpi-eng
5. cyanogen_generic-eng
6. cyanogen_rpi-eng
选择第6个菜单。
然后进行编译
make -j8
等待编译成功,这可能需要几十分钟。
编译成功之后将”system”目录复制到root目录下,接下来我们可能会用到。
命令如下:
cd <your_android_path>
cp -r system out/target/proct/rpi/root
ps:编译时如果jdk版本不对,可将其改成jdk1.6
五.如何在Raspberry Pi上跑android linux内核?
1.准备一张存储空间2G以上的SD卡及相应读卡器。
2.下载arch linux镜像文件
用wget工具下载镜像文件:
wget http://files.velocix.com/c1410/images/archlinuxarm/archlinux-hf-2012-09-18/archlinux-hf-2012-09-18.zip
解压:
unzip archlinux-hf-2012-09-18.zip
成功之后,你会在当前目录下发现一个镜像文件。
3.烧linux镜像文件。
sudo dd bs=4M if=archlinux-hf-2012-09-18.img of=/dev/sdb
sudo sync
ps:/dev/sdb是SD卡在主机上的设备文件。不同的电脑可能不同。
4.用android linux内核代替这个内核。
做完上述步骤之后,当你把SD卡插在电脑上,你会发现有两个分区:一个是引导区,另一个是文件系统区。
用android linux内核代替引导区的kernel.img。
cp -uv <your_android_linux_path>/arch/arm/boot/zImage <your_sdcard_boot_partition>/kernel.img
5.用android linux文件系统代替这个linux文件系统
rm -rf <your_sdcard_file_system_partition>
cp -r <your_android_source_code_path>/out/target/proct/rpi/root/* <your_sdcard_file_system_partition>
6.配置内核命令行cmdline.txt
Edit the <your_sdcard_boot_partition>/cmdling.txt, and replace “init=/…” with “init=/init”
7.做完这些之后就可以在Raspberry Pi上跑这个android linux内核。
六.如何为Android linux做一张可引导的SD卡
1.删除已有分区,如果没有就不用删了。
Command(m for help):p
Disk /dev/sdb: 15.7 GB, 15707668480 bytes
64 heads, 32 sectors/track, 14980 cylinders, total 30668085 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0×00000000
sudo fdisk/dev/sdb
Command(m for help):d
Partition number(1-4):1
Command(m for help):d
Selected partition 2
Command (m for help): p
Disk /dev/sdb: 15.7 GB, 15707668480 bytes
64 heads, 32 sectors/track, 14980 cylinders, total 30679040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0×00000000
Device Boot Start End Blocks Id System
Command(m for help):w
ps:确定删除之后,卸掉SD卡,然后再装上。
以bytes问单位记下SD卡的大小。后面的步骤会用到。
然后进入”Expert mode”。
Command(m for help):x
将这个SD卡设置为255个磁面,63个扇区和磁柱数量(不同的SD/mmc卡有着不同的此柱数量)
Expert command (m for help): h
Number of heads (1-256, default 64): 255
Expert command (m for help): s
Number of sectors (1-63, default 32): 63
ps:在下一步开始前,先要计算磁柱数量,计算过程如下:
B:SD卡以bytes为单位的大小(前面已经记住了即:15707668480)
C:磁柱的数量
C=B/255/63/512
例如:我的SD卡大小是16G(15707668480)
C=15707668480/255/63/512=1909.68191721,约等于1909.
Expert command (m for help): c
Number of cylinders (1-1048576, default 14980): 1909
Expert command (m for help): r
2.新建分区
如果你的SD卡已经分区,请按照上述步骤删除分区。接下来,我们将创建两个分区,一个是引导区,用来存放内核镜像等文件;另一个文件系统区存放android linux文件系统。
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-30679039, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-30679039, default 30679039): +128M
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))
Command (m for help): a
Partition number (1-4): 1
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): p
Partition number (1-4, default 2):
Using default value 2
First sector (264192-30679039, default 264192):
Using default value 264192
Last sector, +sectors or +size{K,M,G} (264192-30679039, default 30679039):
Using default value 30679039
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
ok,分区成功,现在我们有两个分区,接下我们对分区进行格式化。
3.格式化分区
对引导区进行格式化:
sudo mkfs.msdos -F 32 /dev/sdb1 -n BOOT
mkfs.msdos 3.0.12 (29 Oct 2011)
对文件系统区进行格式化:
sudo mkfs.ext3 /dev/sdb2 -L ROOTFS
mke2fs 1.42 (29-Nov-2011)
Filesystem label=ROOTFS
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
950976 inodes, 3801856 blocks
190092 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=3896508416
117 block groups
32768 blocks per group, 32768 fragments per group
8128 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
4.设置引导区
引导区必须包含以下文件,你可以从官方镜像里获取(bootable/fat32 partition)也可以从书面步骤中复制过来:
bootcode.bin:第二阶段的引导程序,
loader.bin:第三阶段的引导程序,
start.elf:GPU二进制固件映像,
kernel.img操作系统的内核镜像文件,
cmdline.txt:传递给内核的参数.
5.设置root文件系统分区
ROOTFS分区包含android文件系统,是从<your_android_framework_path>/out/target/proct/rpi/root复制过来的。
cp -r <your_android_framework_path>/out/target/proct/rpi/root/* /media/ROOTFS/
6.完成上述步骤之后,将其放在Raspberry Pi上跑。
七.如何在Raspberry Pi使用adb?
1.查看网络
当android linux在Raspberry Pi运行时,切换到控制台,执行以下命令:
ifconfig eth0
记下ip地址。
如果不能找到ip,可以输入以下命令:/system/xbin/dhcp-eth0,来启动网络连接程序。
ps:如果屏幕没有显示控制台,只要按CTRL+ALT+F2即可切换到控制台。如果你想要切换到Android界面,只要按CTRL+ALT+F7即可。
2.远程连接adb服务器
在主机上执行以下命令即可与同一局域网的Raspberry Pi相连
adb connect ip
连接成功后,你就可以用adb工具输出日志,执行shell命令等。
3.也可以用数据线连接主机,直接在主机上调试。
进入调试的命令为:
screen /dev/ttyUSB0 115200
6. 自己可以编译安卓源码吗
用最新的Ubuntu 16.04,请首先确保自己已经安装了Git.没安装的同学可以通过以下命令进行安装:
sudo apt-get install git git config –global user.email “[email protected]” git config –global user.name “test”
其中[email protected]为你自己的邮箱.
简要说明
android源码编译的四个流程:1.源码下载;2.构建编译环境;3.编译源码;4运行.下文也将按照该流程讲述.
源码下载
由于某墙的原因,这里我们采用国内的镜像源进行下载.
目前,可用的镜像源一般是科大和清华的,具体使用差不多,这里我选择清华大学镜像进行说明.(参考:科大源,清华源)
repo工具下载及安装
通过执行以下命令实现repo工具的下载和安装
mkdir ~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo
补充说明
这里,我来简单的介绍下repo工具,我们知道AOSP项目由不同的子项目组成,为了方便进行管理,Google采用Git对AOSP项目进行多仓库管理.在聊repo工具之前,我先带你来聊聊多仓库项目:
我们有个非常庞大的项目Pre,该项目由很多个子项目R1,R2,...Rn等组成,为了方便管理和协同开发,我们为每个子项目创立自己的仓库,整个项目的结构如下:
这里写图片描述
执行完该命令后,再使用make命令继续编译.某些情况下,当你执行jack-admin kill-server时可能提示你命令不存在,此时去你去out/host/linux-x86/bin/目录下会发现不存在jack-admin文件.如果我是你,我就会重新repo sync下,然后从头来过.
错误三:使用emulator时,虚拟机停在黑屏界面,点击无任何响应.此时,可能是kerner内核问题,解决方法如下:
执行如下命令:
通过使用kernel-qemu-armv7内核 解决模拟器等待黑屏问题.而-partition-size 1024 则是解决警告: system partion siez adjusted to match image file (163 MB >66 MB)
如果你一开始编译的版本是aosp_arm-eng,使用上述命令仍然不能解决等待黑屏问题时,不妨编译aosp_arm64-eng试试.
结束吧
到现在为止,你已经了解了整个android编译的流程.除此之外,我也简单的说明android源码的多仓库管理机制.下面,不妨自己动手尝试一下.
7. 打电话对方呼叫转移怎么回事
8. 怎样查看 Android APP 源代码
用压缩软件打开apk文件,解压出根目录中的classes.dex文件
使用cmd ,dex2jar.bat classes.dex命令将classes.dex转换为jar
再用jd-gui打开该jar就可以查看源码了,如果apk安全性好的话,有些代码是看不到的
9. android系统是开源去哪里下载源代码
他这不是编程原代码对外公开,而是系统外部接口对外公开,简单说,开源就好比是,英特尔生产一个CPU 然后告诉你所有的脚都是干吗用的,这个告诉你干吗用的就等于是安桌的开源了, 你知道CPU那些脚干吗用的后,然后再根据这些脚的功能生产主板,针对这些脚所生产出来的主板就好比那些为因安桌开源后,别人针对安桌所编写出来的软件了,
10. 怎样用git获取指定的Android Linux Kernel
进入kernel/common,这里不需要用到repo,直接用Git即可。
git clone git://android.git.kernel.org/kernel/common.git
这可能需要不少的时间,因为它会把整个Linux Kernel的代码复制下来。
如果需要某个branch的代码,用git checkout即可。比如我们刚刚拿了kernel/common.git的代码,那就先进入到common目录,然后用下面的命令:
git checkout origin/android-goldfish-2.6.27 -b goldfish
这样我们就在本地建立了一个名为goldfish的android-goldfish-2.6.27分支,代码则已经与android- goldgish-2.6.27同步。我们可以通过git branch来列出本地的所有分支。
root@localhost mydroid]#git clone git://android.git.kernel.org/kernel/common.git kernel
//把服务器上的所有kernel都下载到本地kernel目录,想只下载一个版本的kernel是不可能的因为服务器上只有一个包含kernel的common.git文件,而没有单个版本kernel的.git文件
[root@localhost mydroid]#cd kernel
[root@localhost kernel]# ls
arch CREDITS drivers include Kbuild MAINTAINERS net samples sound
block crypto firmware init kernel Makefile README scripts usr
COPYING Documentation fs ipc lib mm REPORTING-BUGS security virt
[root@localhost kernel]# git branch -a
* android-2.6.27
diff
remotes/origin/HEAD -> origin/android-2.6.27
remotes/origin/archive/android-2.6.25
remotes/origin/archive/android-2.6.27
remotes/origin/archive/android-2.6.29
remotes/origin/archive/android-2.6.32