精华内容
下载资源
问答
  • 功能显示界面
  • Android系统优化从入门到精通_胡郁; Android系统优化从入门到精通_胡郁; Android系统优化从入门到精通_胡郁
  • Android开发入门经典pdf

    2018-11-23 16:08:17
    系统的、循序渐进的学习Android开发所需的知识 n 第一部分:Android入门基础 包括:Android是什么、有什么、能干什么,Android开发的环境构建、 HelloWorld开发,HelloWorld基本分析等 n 第二部分:Android应用核心...
  • android入门到精通,79天项目课程+源代码。不仅带你入门,还含有至少3个项目实战视频教程
  • Android系统开发入门

    2018-09-10 17:00:39
    Android系统开发入门
  • 比较不错的一篇如何搭建Android系统入门级文章。  一.PC工作环境准备   1.从Ubuntu官方主页www.ubuntn.com.cn下载Ubuntu8.04桌面版,然后完全安装。  2.打开ubuntu终端,输入sudo apt-get install命令来通过...
  • Android初学者入门 从入门到精通

    千次阅读 2018-09-26 17:09:01
    Android初学者入门 从入门到精通   学习Android的人越来越多,智能手机也已经深入到我们的工作和生活中去,所以今天给大家分享Android的学习资料,希望能给大家带来帮助,在学习上可以找到技巧,能够运用到项目...

    Android初学者入门 从入门到精通

     

    学习Android的人越来越多,智能手机也已经深入到我们的工作和生活中去,所以今天给大家分享Android的学习资料,希望能给大家带来帮助,在学习上可以找到技巧,能够运用到项目中去。更多项目实例资料可以在U创论坛找到。

     

    Android 开发简介

    Android 是 Google 提供的移动、无线、计算机和通信平台。通过使用 Android Eclipse 插件,可以在强大的 Eclipse 环境中构建 Android 应用程序。本教程介绍如何用 Eclipse 插件 Android Development Tools 进行 Android 应用 程序开发,包括对 Android 平台和 Android Development Tools 的介绍,并开发两个示例应用程序。 ·

     

    用 Eclipse 开发 Android 应用程序

    Android 是一种基于 Linux® V2.6 内核的综合操作环境。最初,Android 的部署目标是移动电话领域,包括智能电话 和更廉价的翻盖手机。但是, Android 全面的计算服务和丰富的功能支持完全有能力扩展到移动电话市场以外。Android 也可以用于其他的平台和应用程序。在本文中,阅读对 Android 平台的简介,并学习如何编写基本的 Android 应用程序。

     

    平台资料对学习也很重要,这里有很多Android的项目实例可以参考借鉴,原文下载地址:

    https://bbs.usoftchina.com/forum.php?mod=forumdisplay&fid=253&filter=typeid&typeid=26

    安卓入门到精通

    图一

     

    Android应用程序架构

    Android 运行在 Linux 内核上。Android 应用程序是用 Java 编程语言编写的,它们在一个虚拟机(VM)中运行。 需要注意的是,这个 VM 并非您想象中的 JVM,而是 Dalvik Virtual Machine,这是一种开源技术。每个 Android 应用程序都 在 Dalvik VM 的一个实例中运行,这个实例驻留在一个由 Linux 内核管理的进程中。

     

     使用 adb shell 命令

    安卓从入门到精通

    图二

     

    在这个 shell 环境中,可以: ·

    显示网络配置,网络配置可显示多个网络连接。注意这多个网络连接: o lo 是本地或 loopback 连接。 o tiwlan0 是 WiFi 连接,该连接由本地 DHCP 服务器提供一个地址。显示 PATH 环境变量的内容。 · 执行 su 命令,以成为超级用户。 · 将目录改为 /data/app,其中存放用户应用程序。 · 列出包含某个应用程序的目录。Android 应用程序文件实际上是归档文件,可通过 WinZip 之类的软件查看。扩展名为 apk。 · 发出 ping 命令,查看 Google.com 是否可用。 从相同的命令提示符环境中,还可以与 SQLite 数据库交互,启动程序以及执行许多其他系统级任务。想像一下您正在连接到电话, 因此这是非常了不起的功能。

     

     

    展开全文
  • 在网络编程中,connect函数通常用于客户端建立tcp连接。使用的步骤如下:  1) 创建流式套接字  int sockfd;  if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) <0)  {  perror(“fail to socket”);...
  • 多年来,安卓系统用久了就会卡顿,这是一项铁律,也是困扰消费者的一大顽疾。相比之下,一台苹果手机用3年或4年也不会卡顿,而安卓系统用2年之后就会感受到卡顿。正因于此,卡顿也是安卓系统公认的硬伤。 最近两年...

      多年来,安卓系统用久了就会卡顿,这是一项铁律,也是困扰消费者的一大顽疾。相比之下,一台苹果手机用3年或4年也不会卡顿,而安卓系统用2年之后就会感受到卡顿。正因于此,卡顿也是安卓系统公认的硬伤。

    4db090553e6992f895e60be51e2ec25d.png

      最近两年,安卓手机硬件配置高了,但系统用久了仍然会卡顿。比如,今年下半年发布的旗舰手机,八核处理器是标配,入门版也有8G内存,高配版本有12G或16G内存。更高的硬件配置,加上全方位的优化,安卓系统流畅度大幅提升。不过,用几年后安卓系统仍然会卡顿。

      此外,对于一些硬件配置比较老的手机,安卓系统可谓是卡成翔。虽说今年很多手机已经标配6G内存,可是一些百元手机或千元机,只有4G内存。试想,安卓系统一直被网友称为资源消耗大户,2G内存跑安卓系统根本没有流畅度可言。

      在实际应用中,安卓系统会消耗多少硬件资源呢?一台拥有8G内存的手机,开机后剩余内存可能不到4G。由此来看,安卓系统开机后就吃掉了一半以上的内存,这确实有点变态。事实上,安卓系统对CPU资源的消耗也很严重。

    04bcb74f74be6825dd99adbdcd2a3cac.png

      最近几年,安卓系统每年至少要有一次大版本的更迭。虽说安卓手机硬件升级也非常快,但安卓系统对硬件配置的要求更高了。正因于此,安卓手机用2年消费者就能感觉到卡顿。如果是5年以上的老款安卓手机,开机后会卡顿更严重。

      最新消息称,谷歌在发布了安卓11后,又面向低配机型推出了Android 11 Go。据介绍,Android 11 Go这是一个专为入门级手机设计的安卓版本,对当前的安卓系统进行简化,使其可以在小内存手机上运行。显然,这是一个阉割版的安卓系统。

      按照官方的说法,阉割版安卓系统可以运行在2G内存的手机上,为用户提供270MB的可用空间,足以让后台运行3-4个应用程序。此外,阉割版安卓系统应用启动速度提升了20%,还可以更快的在多个应用程序之间切换。

    64ff8978707ef323acdea9dec921ad67.png

      不难看出,阉割版安卓系统对内存的占用更少,流畅度也更高了,硬件配置比较低的手机可以重获新生了。不过,阉割版安卓系统仍面临一些问题,最尖锐的问题就是,如何安装阉割版安卓?谷歌官方统一推送,还是各个手机厂商适配后统一推送。

      众所周知,国内手机系统是各个手机厂商深度定制的安卓版本。那么,国内手机厂商是否乐意为那些硬件配置落后的旧手机推送阉割版安卓呢?更何况,旧手机的系统运行流畅了,这会影响新手机的销售。

      总之,为了提升旧手机系统的流畅度,谷歌推出阉割版安卓系统的初衷是好的。只是,国内用户能否用上更流畅的阉割版安卓系统,这仍然是一个未知数。所以,谷歌发布了阉割版安卓系统,这并不意味着旧手机可以远离系统卡顿。

    展开全文
  • 教程名称: Android开发入门资料之基础宝典【】Android中文帮助文档【】Android新手入门 FAQ【】Android系统原理与开发要点详解【技术文档】【】android系统简介【】Linux开发Android系统基础知识大汇总【】...
  • Android开发从入门到精通》系统讲解了Android软件开发的基础知识,图文并茂地帮助读者学习和掌握SDK、开发流程以及常用的API等。书中以讲述实战实例为导向,用一个个典型应用生动地引领读者进行项目开发实践。...
  • Android新手入门2016

    2016-04-01 10:19:45
    这是我编写的Android新手入门教程,word文档方便阅读。网上的资源现在都比较旧了,这是目前最新的入门级教程。想要最新最全的信息可以进入我的csdn博客查看
  • Android开发入门 – 简易开心消消乐界面设计 第一步,点击File->NEW->new module,进入以下界面,选择第一个,即运行在手机和平板电脑上。点击next。 第二步,在第一个和第二个栏中分别输入“开心消消乐”和...
  • xml布局构思 总体是垂直线性布局 里面放6个TextView,5个EditText,5个Button按钮 界面设计效果图 原创文章 17获赞 18访问量 3865 关注 私信 展开阅读全文 作者:时光踏路已久
  • Android开发入门与实战是一本Android应用层开发书籍,对理解Android系统有很大帮助
  • 安卓系统入门到精通,doc格式文档。简单阐述安卓系统结构知识。
  • Android自定义控件开发入门与实战》从自定义控件的动画、绘图、视图三方面入手,分别讲解与自定义控件相关的各种知识,给大家系统地梳理相关知识点,并且通过翔实的案例讲解每个知识点在现实工作中所能实现的功能...
  • Android系统源码Build系统入门详解

    千次阅读 2017-10-16 10:50:11
    那么我们就以上列出的文件,一个个找添加依赖的方法,为了更清晰的了解我们要做什么,我们先来研究...包含C的Android.mk以最简单的Android.mk为例,就是说这个创建的时候啥都没有,脑补一下你刚刚学习安卓的时候写的那

    那么我们就以上列出的文件,一个个找添加依赖的方法,为了更清晰的了解我们要做什么,我们先来研究一下我们在eclipse开发第一个hello-jni的时候写过的Android.mk,这个大概是大部分同学接触的第一个mk文件了吧?因此我们先研究一下Jni下的Android.mk

    ##包含C的Android.mk

    以最简单的Android.mk为例,就是说这个创建的时候啥都没有,脑补一下你刚刚学习安卓的时候写的那个helloworld,没错没错,就是他了,现在要求你的helloworld写在系统源码里面,那么就需要一个包含以下内容的mk文件(不要再偷懒了,这已经是最简化的了):

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := hello-jni
    LOCAL_SRC_FILES := hello-jni.c
    
    include $(BUILD_SHARED_LIBRARY)
    

    别着急,一条一条分析:

    ###第一行

    LOCAL_PATH := $(call my-dir)

    每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。
    宏my-dir 则由Build System提供。返回包含Android.mk的目录路径。

    那么具有批判性思维的同学要问了,这个LOCAL_PATH是个什么鬼,:=是什么鬼,$(call my-dir)又是什么鬼?还有这个my-dir又是怎么来的,为什么不是he-dir或者是she-dir。

    **”:=“**这冒号等号看上去是赋值的意思吧?
    小伙子真机智,你又答对了!

    **"$(XXX)"**这大概是取值把,比如上面的意思就是取系统变量LOCAL_PATH ?
    真机智,你又答对了!

    这个问题问得好,我们一个个找答案。

    **LOCAL_PATH :**根据我们以往的开发经验,这种大写的带下划线的变量一般是编译环境变量,事实上为了方便模块的编译,Build 系统设置了很多的编译环境变量。要编译一个模块,只要在编译之前根据需要设置这些变量然后执行编译即可。它们包括:

    • LOCAL_SRC_FILES:当前模块包含的所有源代码文件。
    • LOCAL_MODULE:当前模块的名称,这个名称应当是唯一的,模块间的依赖关系就是通过这个名称来引用的。
    • LOCAL_C_INCLUDES:C 或 C++ 语言需要的头文件的路径。
    • LOCAL_STATIC_LIBRARIES:当前模块在静态链接时需要的库的名称。
    • LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库的名称。
    • LOCAL_CFLAGS:提供给 C/C++ 编译器的额外编译参数。
    • LOCAL_JAVA_LIBRARIES:当前模块依赖的 Java 共享库。
    • LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的 Java 静态库。
    • LOCAL_PACKAGE_NAME:当前 APK 应用的名称。
    • LOCAL_CERTIFICATE:签署当前应用的证书名称。
    • LOCAL_MODULE_TAGS:当前模块所包含的标签,一个模块可以包含多个标签。标签的值可能是 debug, eng, user,development 或者 optional。其中,optional 是默认标签。标签是提供给编译类型使用的。不同的编译类型会安装包含不同标签的模块,那么这些标签的值有代表什么呢?

    这个问题问得好,这些标签代表编译类型,编译类型的各个标签分别如下(表格略吃藕,凑合看了 ):

    名称说明
    eng默认类型,该编译类型适用于开发阶段。 当选择这种类型时,编译结果将: 安装包含 eng, debug, user,development 标签的模块 安装所有没有标签的非 APK 模块 安装所有产品定义文件中指定的 APK 模块
    user 该编译类型适合用于最终发布阶段。 当选择这种类型时,编译结果将: 安装所有带有 user 标签的模块 安装所有没有标签的非 APK 模块 安装所有产品定义文件中指定的 APK 模块,APK 模块的标签将被忽略
    userdebug 该编译类型适合用于 debug 阶段。 该类型和 user 一样,除了: 会安装包含 debug 标签的模块 编译出的系统具有 root 访问权限


    ###第二行

    include $(CLEAR_VARS)

    从字面意思理解,这大概就是清除之前的变量值吧?有批判性思维的同学就要问了,清除什么变量值,为什么要清除呢?留着不是更好吗?这个CLEAR_VARS里面都有些什么值我们要包含进来?

    嗯,这位同学又提出了一个不错的问题,我们带着疑问猜,会不会是因为安卓系统编译的时候为了防止定义过多的变量,把一些变量定义公用的,但是这些变量在编译上一个模块的时候已经被赋值了,如果下一个模块要继续使用就需要把这些变量清除或者叫做重新初始化?

    恩恩,这位同学真机智,就是这样的。

    ###第三行

    LOCAL_MODULE := hello-jni

    等号前面的我们知道了,那么后面的这个 hello-jni是个什么鬼?
    嗯,我们回到上面看下LOCAL_MODULE的定义。
    LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so.
    但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。

    模块间的依赖关系就是通过这个名称来引用的。

    上面这句话有没有想到什么?对了,模块间的依赖关系,不就是这个文章讲的怎么应用另一个模块嘛?别激动,这个还只是定义,我们继续探索。

    ###第四行

    LOCAL_SRC_FILES := hello-jni.c
    这句话的意思就是说,我这个工程的源码路径只有一个文件,这个文件就是我这个MK文件所在目录下的hello-jni.c

    ###第五行

    include $(BUILD_SHARED_LIBRARY)
    当前模块在静态链接时需要的库的名称。


    ##不含C的Android.mk

    其实上面就是在源码树下我们添加jni文件的mk写法。我们先来研究一下纯不包含C文件的Android.mk,也就是我们写的第一个程序helloworld在安卓源码树中的展现。我们来分析分析Android.mk内容。

      LOCAL_PATH := $(call my-dir)
      include $(CLEAR_VARS)
       
      # Build all java files in the java subdirectory
      LOCAL_SRC_FILES := $(call all-subdir-java-files)
       
      # Name of the APK to build
      LOCAL_PACKAGE_NAME := LocalPackage
       
      LOCAL_CERTIFICATE := platform
       
      # Tell it to build an APK
      include $(BUILD_PACKAGE)
    

    ###第二行

    LOCAL_SRC_FILES := $(call all-subdir-java-files)

    我们看到这里的写法和上面C的写法不相同,all-subdir-java-files代表的是子目录下的所有java文件,上面的jni例子里面是直接指定c文件,那么如果有多个C文件怎么办?是不是也应该all-subdir-java-files这样来一下。

    我找啊找,找到了这个:

    除此以外,Build 系统中还定义了一些便捷的函数以便在 Android.mk 中使用,包括: $(call my-dir):获取当前文件夹路径。

    • $(call all-java-files-under, <src>):获取指定目录下的所有 Java文件。
    • $(call all-c-files-under, <src>):获取指定目录下的所有 C 语言文件。
    • $(call> all-Iaidl-files-under, <src>) :获取指定目录下的所有 AIDL 文件。
    • $(call> all-makefiles-under, <folder>):获取指定目录下的所有 Make 文件。
    • $(call intermediates-dir-for, <class>, <app_name>, <host or target>, <common?> ):获取 Build 输出的目标文件夹路径。

    提示(与本文无关,可忽略):我在编辑这篇文章的时候类似于 <src>的格式直接被浏览器解析掉了,无法显示,所以我才用的是特殊字符编码的形式,比如:

    <   &lt;  <=   &le;
    
    >   &gt;  >=   &ge;
    

    ###第三行

    LOCAL_PACKAGE_NAME := LocalPackage //应用名称

    这个指的是当前 APK 应用的名称,这个和LOCAL_MODULE不一样,它不是是唯一的,就相当于Manifest.xml清单文件里面的appName。

    ###第四行

    LOCAL_CERTIFICATE := platform//签署当前应用的证书名称。

    证书?莫非系统签名和这个有关系?如果是,是不是说只要这个名字对应的系统签名,那么就能使用android:sharedUserId="android.uid.system"并使用系统级别的一些方法?
    带着疑问我查了一下,没想到又被我猜对了,我真是个机智的少年。
    现在我们知道了LOCAL_CERTIFICATE 的作用,那么后面的platform是啥意思呢?哦,原来是签名类型。

    ####**签名类型** android的标准签名key有:
    
    testkey
    
    media
    
    platform
    
    shared
    
    以上的四种,可以在源码的/build/target/product/security里面看到对应的密钥,其中shared.pk8代表私钥,shared.x509.pem公钥,一定是成对出现的。
    
    其中testkey是作为android编译的时候默认的签名key,如果系统中的apk的android.mk中没有设置LOCAL_CERTIFICATE的值,就默认使用testkey。
    
    而如果设置成:
    
    LOCAL_CERTIFICATE := platform
    
    就代表使用platform来签名,这样的话这个apk就拥有了和system相同的签名,因为系统级别的签名也是使用的platform来签名,此时使用android:sharedUserId="android.uid.system"才有用!
    

    ###第五行

    我们来看最后一行

    include $(BUILD_PACKAGE)

    BUILD_PACKAGE是什么呢?编译目标对象?难道说是区分给手机用,还是给平板用的?
    好像没猜对,我们看下资料:

    Android 源码中包含了许多的模块,模块的类型有很多种,例如:Java 库,C/C++ 库,APK 应用,以及可执行文件等
    。并且,Java 或者 C/C++ 库还可以分为静态的或者动态的,库或可执行文件既可能是针对设备(本文的“设备”指的是 Android
    系统将被安装的设备,例如某个型号的手机或平板)的也可能是针对主机(本文的“主机”指的是开发 Android 系统的机器,例如装有
    Ubuntu 操作系统的 PC 机或装有 MacOS 的 iMac 或
    Macbook)的。不同类型的模块的编译步骤和方法是不一样,为了能够一致且方便的执行各种类型模块的编译,在 config.mk
    中定义了许多的常量,这其中的每个常量描述了一种类型模块的编译方式,这些常量有
    BUILD_HOST_STATIC_LIBRARY
    BUILD_HOST_SHARED_LIBRARY
    BUILD_SHARED_LIBRARY
    BUILD_EXECUTABLE
    BUILD_PACKAGE BUILD_PREBUILT
    BUILD_MULTI_PREBUILT
    BUILD_JAVA_LIBRARY
    BUILD_HOST_JAVA_LIBRARY

    通过名称大概就可以猜出每个变量所对应的模块类型。(在模块的 Android.mk
    文件中,只要包含进这里对应的常量便可以执行相应类型模块的编译。

    这些常量的值都是另外一个 Make 文件的路径,详细的编译方式都是在对应的 Make 文件中定义的。这些常量和 Make
    文件的是一一对应的,对应规则也很简单:常量的名称是 Make 文件的文件名除去后缀全部改为大写然后加上“BUILD_”作为前缀。例如常量
    BUILD_HOST_PREBUILT 的值对应的文件就是 host_prebuilt.mk。

    既然讲到了这里那么我们也来看下其他值对应的什么吧
    这里写图片描述

    ##依赖关系

    顺带着我们把mk之间的依赖关系看一下。有些文章一来就给我们看这个,你说谁看得懂。。。

    mk文件包含关系

    展开全文
  • 编译系统入门篇-Android10.0编译系统(一)

    万次阅读 多人点赞 2020-10-14 20:32:39
    专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! [Android取经之路] 的源码都基于Android-Q(10.0) 进行分析 [Android取经之路] 系列文章: 《系统启动篇》 Android系统架构 Android是...

    摘要:本节主要来进行Android10.0 编译系统入门讲解

    阅读本文大约需要花费14分钟。

    文章首发微信公众号:IngresGe

    专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

    欢迎关注我的公众号!

    [Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

    [Android取经之路] 系列文章:

    《系统启动篇》

    1. Android系统架构
    2. Android是怎么启动的
    3. Android 10.0系统启动之init进程
    4. Android10.0系统启动之Zygote进程
    5. Android 10.0 系统启动之SystemServer进程
    6. Android 10.0 系统服务之ActivityMnagerService
    7. Android10.0系统启动之Launcher(桌面)启动流程
    8. Android10.0应用进程创建过程以及Zygote的fork流程
    9. Android 10.0 PackageManagerService(一)工作原理及启动流程
    10. Android 10.0 PackageManagerService(二)权限扫描
    11. Android 10.0 PackageManagerService(三)APK扫描
    12. Android 10.0 PackageManagerService(四)APK安装流程

    《日志系统篇》

    1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
    2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
    3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
    4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

    《Binder通信原理》

    1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
    2. Android10.0 Binder通信原理(二)-Binder入门篇
    3. Android10.0 Binder通信原理(三)-ServiceManager篇
    4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
    5. Android10.0 Binder通信原理(五)-Binder驱动分析
    6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
    7. Android10.0 Binder通信原理(七)-Framework binder示例
    8. Android10.0 Binder通信原理(八)-Framework层分析
    9. Android10.0 Binder通信原理(九)-AIDL Binder示例
    10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
    11. Android10.0 Binder通信原理(十一)-Binder总结

      《HwBinder通信原理》

    1. HwBinder入门篇-Android10.0 HwBinder通信原理(一)
    2.  HIDL详解-Android10.0 HwBinder通信原理(二)
    3. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
    4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
    5. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
    6. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
    7. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
    8. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
    9. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
    10. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
    11. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

    《编译原理》

    1. 编译系统入门篇-Android10.0编译系统(一)
    2. 编译环境初始化-Android10.0编译系统(二)
    3. make编译过程-Android10.0编译系统(三)
    4. Image打包流程-Android10.0编译系统(四)
    5. Kati详解-Android10.0编译系统(五)
    6. Blueprint简介-Android10.0编译系统(六)
    7. Blueprint代码详细分析-Android10.0编译系统(七)

     

    1 概述

      在 Android 7.0 之前,Android 编译系统使用 GNU Make 描述和shell来构建编译规则,模块定义都使用Android.mk进行定义,Android.mk的本质就是Makefile,但是随着Android的工程越来越大,模块越来越多,Makefile组织的项目编译时间越来越长。这样下去Google工程师觉得不行,得要优化。

      因此,在Android7.0开始,Google采用ninja来代取代之前使用的make,由于之前的Android.mk数据实在巨大,因此Google加入了一个kati工具,用于将Android.mk转换成ninja的构建规则文件buildxxx.ninja,再使用ninja来进行构建工作。

      ninja的网址:https://ninja-build.org

      编译速度快了一些,但是既然要干, 那就干个大的,最终目标要把make都取代,于是从Android8.0开始,Google为了进一步淘汰Makefile,因此引入了Android.bp文件来替换之前的Android.mk。

      Android.bp只是一个纯粹的配置文件,不包括分支、循环语句等控制流程,本质上就是一个json配置文件。Android.bp  通过Blueprint+soong转换成ninja的构建规则文件build.ninja,再使用ninja来进行构建工作。

      Android10.0上,mk和bp编译的列表可以从 \out\.module_paths中的Android.bp.list、Android.mk.list中看到,Android10.0还有400多个mk文件没有被替换完,Google任重道远。

      Android编译演进过程:

    • Android7.0之前 使用GNU Make

    • Android7.0 引入ninja、kati、Android.bp和soong构建系统

    • Android8.0 默认打开Android.bp

    • Android9.0 强制使用Android.bp

      Google在 Android 7.0之后,引入了Soong构建系统,旨在取代make,它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

    Make 构建系统得到了广泛的支持和使用,但在 Android 层面变得缓慢、容易出错、无法扩展且难以测试。Soong 构建系统正好提供了 Android build 所需的灵活性。

      Android系统的编译历程:

     

    2 编译流程

    2.1 编译构成

      Android的编译目录在/build 中,看一下Android 10源码中的build目录,现在是这个样子:

     这个目录中可以看到core文件夹被link到了make/core,envsetup.sh被link到make/envsetup.sh,这主要是为了对使用者屏蔽切换编译系统的差异。

      这里重点看四个文件夹:blueprint、kati、make、soong

      blueprint:用于处理Android.bp,编译生成*.ninja文件,用于做ninja的处理

      kati:用于处理Android.mk,编译生成*.ninja文件,用于做ninja的处理

      make:文件夹还是原始的make那一套流程,比如envsetup.sh

      soong:构建系统,核心编译为soong_ui.bash

      Soong编译系统家族成员及各自关系如下图所示:

    在编译过程中,Android.bp会被收集到out/soong/build.ninja.d,blueprint以此为基础,生成out/soong/build.ninja

    Android.mk会由kati/ckati生成为out/build-aosp_arm.ninja

    两个ninja文件会被整合进入out/combined-aosp_arm.ninja

    out/combined-aosp_arm.ninja内容如下所示:

    builddir = out
    pool local_pool
     depth = 42
    build _kati_always_build_: phony
    subninja out/build-aosp_arm.ninja
    subninja out/build-aosp_arm-package.ninja
    subninja out/soong/build.ninja

    2.2 编译步骤

      source build/envsetup.sh

      lunch aosp_arm-eng // 或者 m PRODUCT-aosp_x86_64-eng ,Android10.0不一定需要lunch命令

      make -j8      //编译模块也可以直接用 m libart

        Android10.0编译步骤如下图所示:

    3 编译环境初始化

    3.1 envsetup说明

      编译的第一步需要初始化一下环境变量,通过以下命令完成:

     source build/envsetup.sh

      这里的envsetup.sh被link到了 build/make/envsetup.sh

      envsetup.sh 主要做了下面几个事情:

      在source build/envsetup.sh后,输入hmm可以看到envsetup支持的一些接口:

    说明

    lunch

    lunch <product_name>-<build_variant>

    选择<product_name>作为要构建的产品,<build_variant>作为要构建的变体,并将这些选择存储在环境中,以便后续调用“m”等读取。

    tapas

    交互方式:tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]

    croot

    将目录更改到树的顶部或其子目录。

    m

    编译整个源码,可以不用切换到根目录

    mm

    编译当前目录下的源码,不包含他们的依赖模块

    mmm

    编译指定目录下的所有模块,不包含他们的依赖模块   例如:mmm dir/:target1,target2.

    mma

    编译当前目录下的源码,包含他们的依赖模块

    mmma

    编译指定目录下的所模块,包含他们的依赖模块

    provision

    具有所有必需分区的闪存设备。选项将传递给fastboot。

    cgrep

    对系统本地所有的C/C++ 文件执行grep命令

    ggrep

    对系统本地所有的Gradle文件执行grep命令

    jgrep

    对系统本地所有的Java文件执行grep命令

    resgrep

    对系统本地所有的res目录下的xml文件执行grep命令

    mangrep

    对系统本地所有的AndroidManifest.xml文件执行grep命令

    mgrep

    对系统本地所有的Makefiles文件执行grep命令

    sepgrep

    对系统本地所有的sepolicy文件执行grep命令

    sgrep

    对系统本地所有的source文件执行grep命令

    godir

    根据godir后的参数文件名在整个目录下查找,并且切换目录

    allmod

    列出所有模块

    gomod

    转到包含模块的目录

    pathmod

    获取包含模块的目录

    refreshmod

    刷新allmod/gomod的模块列表

     

    3.2 Lunch 说明

      环境变量初始化完成后,我们需要选择一个编译目标。lunch 主要作用是根据用户输入或者选择的产品名来设置与具体产品相关的环境变量。

      如果你不知道想要编译的目标是什么,直接执行一个lunch命令,会列出所有的目标,直接回车,会默认使用aosp_arm-eng这个目标。

     

    执行命令:lunch 1, 可以看到配置的一些环境变量

      这些环境变量的含义如下:

    lunch结果

    说明

    PLATFORM_VERSION_CODENAME=REL

    表示平台版本的名称

    PLATFORM_VERSION=10                        

    Android平台的版本号

    TARGET_PRODUCT=aosp_arm        

    所编译的产品名称

    TARGET_BUILD_VARIANT=userdebug                

    所编译产品的类型

    TARGET_BUILD_TYPE=release                

    编译的类型,debug和release

    TARGET_ARCH=arm                                

    表示编译目标的CPU架构

    TARGET_ARCH_VARIANT=armv7-a-neon        

    表示编译目标的CPU架构版本

    TARGET_CPU_VARIANT=generic                

    表示编译目标的CPU代号

    HOST_ARCH=x86_64                                

    表示编译平台的架构

    HOST_2ND_ARCH=x86

    表示编译平台的第二CPU架构

    HOST_OS=linux                                

    表示编译平台的操作系统

    HOST_OS_EXTRA=Linux-4.15.0-112-generic-x86_64-Ubuntu-16.04.6-LTS                

    编译系统之外的额外信息

    HOST_CROSS_OS=windows

     

    HOST_CROSS_ARCH=x86

     

    HOST_CROSS_2ND_ARCH=x86_64

     

    HOST_BUILD_TYPE=release

    编译类型

    BUILD_ID=QQ1D.200205.002                

    BUILD_ID会出现在版本信息中,可以利用

    OUT_DIR=out                                

    编译结果输出的路径

     

    4.Make 说明

      执行完lunch命令后,就可以使用make命令来执行编译Build。

      Android10.0上是通过soong执行编译构建,这里执行make命令时,main.mk文件把一些环境变量和目标都配置好后,会执行envsetup.sh中的make()进行编译。

      如果找到“build/soong/soong_ui.bash”,就使用soong_ui.bash 来进行编译,否则使用原始的make命令进行编译。

    function make()
    {
        _wrap_build $(get_make_command "$@") "$@"
    }
    function get_make_command()
    {
        # If we're in the top of an Android tree, use soong_ui.bash instead of make
        if [ -f build/soong/soong_ui.bash ]; then
            # Always use the real make if -C is passed in
            for arg in "$@"; do
                if [[ $arg == -C* ]]; then
                    echo command make
                    return
                fi
            done
            echo build/soong/soong_ui.bash --make-mode
        else
            echo command make
        fi
    }

    配置一些资源环境,得到一些函数命令,例如:soong_build_go,最终回退到根目录,执行out/soong_ui --make-mode进行真正的构建

    soong_build_go soong_ui android/soong/cmd/soong_ui  是通过编译

    android/soong/cmd/soong_ui/main.go来编译生成soong_ui。

    [build/soong/soong_ui.bash]
    # Save the current PWD for use in soong_ui
    export ORIGINAL_PWD=${PWD}
    export TOP=$(gettop)
    source ${TOP}/build/soong/scripts/microfactory.bash
    
    soong_build_go soong_ui android/soong/cmd/soong_ui
    
    cd ${TOP}
    exec "$(getoutdir)/soong_ui" "$@"
    
    “echo build/soong/soong_ui.bash --make-mode ”

    最终会执行 exec  out/soong_ui  --make-mode 进行编译

    soong的编译过程如下图所示:

      执行runKatiBuild时,有个重要的步骤,就是加载build/make/core/main.mk,main.mk文件是Android Build系统的主控文件。从main.mk开始,将通过include命令将其所有需要的.mk文件包含进来,最终在内存中形成一个包括所有编译脚本的集合,这个相当于一个巨大Makefile文件。Makefile文件看上去很庞大,其实主要由三种内容构成: 变量定义、函数定义和目标依赖规则,此外mk文件之间的包含也很重要。

      main.mk的包含关系如下图所示:

    一些关键的mk文件说明:

    文件

    说明

    build/make/core/main.mk

    Build的主控文件,主要作用是包含其他mk,以及定义几个最重要的编译目标,同时检查编译工具的版本,例如如gcc、clang、java等

    build/make/core/config.mk

    Build的配置文件,主要是区分各个产品的配置,并将这些编译器参数引入产品配置 BoardConfig.mk,同时也配置了一些编译器的路径等

    build/make/core/clang/config.mk

    clang编译的配置文件

    build/make/core/definitions.mk

    最重要的 Make 文件之一,在其中定义了大量的函数。这些函数都是 Build 系统的其他文件将用到的。例如:my-dir,all-subdir-makefiles,find-subdir-files,sign-package 等,关于这些函数的说明请参见每个函数的代码注释。

    build/make/core/dex_preopt.mk

    定义了dex优化相关的路径和参数

    build/make/core/pdk_config.mk

    编译pdk的配置文件

    build/make/core/Makefile

    系统最终编译完成所需要的各种目标和规则

    build/make/core/envsetup.mk

    包含进product_config.mk文件并且根据其内容设置编译产品所需要的环境变量,并检查合法性,指定输出路径等

    build/make/core/combo/select.mk

    根据当前编译器的平台选择平台相关的 Make 文件

    build/make/core/ninja_config.mk

    解析makefile的的列表,传给kati,配置传给ninja和kati的目标

    build/make/core/soong_config.mk

    配置soong的环境变量,建立go变量和mk变量的json映射关系,让go变量可以获取到mk中定义的变量值

     

    5.编译工具链说明

      Android10.0的编译系统中,涉及以下一些工具链,由这些工具链相辅相成,才最终编译出了我们所需要的镜像版本。

      Android10.0编译工具链:

    soong\kati\blueprint\ninja 

    5.1.Soong说明

      Soong 构建系统是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

      Soong是由Go语言写的一个项目,从Android 7.0开始,在prebuilts/go/目录下新增了Go语言所需的运行环境,Soong在编译时使用,解析Android.bp,将之转化为Ninja文件,完成Android的选择编译,解析配置工作等。故Soong相当于Makefile编译系统的核心,即build/make/core下面的内容。

      另外Soong还会编译产生一个androidmk命令,可以用来手动将Android.mk转换成Android.bp文件。不过这只对无选择、循环等复杂流程控制的Android.mk生效。

      soong脚本和代码目录:/build/soong

     

    5.2.kati说明

      kati是一个基于Makefile来生成ninja.build的小项目。主要用于把Makefiel转成成ninja file,自身没有编译能力,转换后使用Ninja编译。

      在编译过程中,kati负责把既有的Makefile、Android.mk文件,转换成Ninja文件。在Android 8.0以后,它与Soong一起,成为Ninja文件的两大来源。Kati更像是Google过渡使用的一个工具,等所有Android.mk都被替换成Android.bp之后,Kati有可能退出Android编译过程.

      在单独使用时,它对普通的小项目还能勉强生效。面对复杂的、多嵌套的Makefile时,它往往无法支持,会出现各种各样的问题。当然,也可以理解为,它只为Android而设计。

      kati脚本和代码目录:/build/kati

     

    5.3.blueprint说明

      Blueprint由Go语言编写,是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义。

      在Android编译最开始的准备阶段,会执行build/soong/soong_ui.bash进行环境准备。 

      对blueprint项目编译完成之后会在out/soong/host/linux-x86/bin目录下生成soong编译需要的5个执行文件(bpfix,bpfmt,bpmodify,microfatory,bpmodify)。

      Soong是与Android强关联的一个项目,而Blueprint则相对比较独立,可以单独编译、使用。

      blueprint代码目录:/build/blueprint

     

    5.4.ninja说明

      最开始,Ninja 是用于Chromium 浏览器中,Android 在SDK 7.0 中也引入了Ninja。

      Ninja是一个致力于速度的小型编译系统(类似于Make),如果把其他编译系统比做高级语言的话,Ninja就是汇编语言。通常使用Kati或soong把makefile转换成Ninja files,然后用Ninja编译。

      主要两个特点:

      1)可以通过其他高级的编译系统生成其输入文件;

      2)它的设计就是为了更快的编译;

      ninja核心是由C/C++编写的,同时有一部分辅助功能由python和shell实现。由于其开源性,所以可以利用ninja的开源代码进行各种个性化的编译定制。

      从Android 7开始,编译时默认使用Ninja。但是,Android项目里是没有.ninja文件的。遵循Ninja的设计哲学,编译时,会先把Makefile通过kati转换成.ninja文件,然后使用ninja命令进行编译。这些.ninja文件,都产生在out/目录下,共有三类:

      第一类是build-*.ninja文件,通常非常大,几十到几百MB。对make全编译,命名是build-<product_name>.ninja。如果Makefile发生修改,需要重新产生Ninja文件。

       mm、mma的Ninja文件,命名是build-<product_name>-<path_to_Android.mk>.ninja。而mmm、mmma的Ninja文件,命名是build-<product_name>-_<path_to_Android.mk>.ninja。

      

      第二类是combined-*.ninja文件。在使用了Soong后,除了build-*.ninja之外,还会产生对应的combined-*.ninja,二者的*内容相同。

    这类是组合文件,是把build-*.ninja和out/soong/build.ninja组合起来。所以,使用Soong后,combined-*.ninja是编译执行的真正入口。

      

      第三类是out/soong/build.ninja文件,它是从所有的Android.bp转换过来的。

    build-*.ninja是从所有的Makefile,用Kati转换过来的,包括build/core/*.mk和所有的Android.mk。所以,在不使用Soong时,它是唯一入口。在使用了Soong以后,会新增源于Android.bp的out/soong/build.ninja,所以需要combined-*.ninja来组合一下。

     

    6.工具链的关系

      Android.mk文件、Android.bp、kati、Soong、Blueprint、Ninja之间的关系如下:

    Android.bp --> Blueprint --> Soong --> Ninja 
      Makefile or Android.mk --> kati --> Ninja 
      (Android.mk --> Soong --> Blueprint --> Android.bp)

      Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义。

      Android.mk可以通过Soong提供的androidmk转换成Android.bp,但仅限简单配置。目前Oreo的编译流程中,仍然是使用kati来做的转换。

      现存的Android.mk文件、既有的Android.bp,都会分别被转换成Ninja。从Android.mk与其它Makefile,会生成out/build-<product_name>.ninja文件。而从Android.bp,则会生成out/soong/build.ninja。此外,还会生成一个较小的out/combined-<product_name>.ninja文件,负责把二者组合起来,作为执行入口。

      最终,Ninja文件才是真正直接控制源码编译的工具。

     

    7.总结

      Android10.0中,mk文件通过kati\ckati编译生成 build-aosp_arm.ninja, bp文件通过blueprint-soong解析编译生成为build.ninja ,这些ninja文件会合并成combined-aosp_arm.ninja,最终通过ninja工具进行最终的编译。

      随着Google的不停演进,make的编译会最终退出历史舞台,kati\ckati也会退出,最终全部切到 blueprint-soong的编译。

     

     

    我的微信公众号:IngresGe

    展开全文
  • Android 测试入门

    2020-09-04 13:30:10
    Android本身是一套软件堆叠(Software Stack),或者成为软件叠层架构,叠层主要分成三层:操作系统、中间件和应用程序
  • Android开发入门与实战(第2版)》遵循第一版的写作宗旨,通过本书的学习,让不懂Android开发的人系统地快速掌握Android开发的知识。《Android开发入门与实战(第2版)》主要内容为:Android开发环境搭建、Android...
  • android编程入门很简单这里给大家提供了android编程入门自学方案,希望能够给您带去帮助。一、android移动应用开发基础知识1、Android应用程序是用java语言写的,通过aapt工具把编译好的java代码和应用程序所需要的...
  • 广大的Android应用开发者是不是对Android系统充满着好奇,是不是很想学习Android系统开发,可惜自己学习难度又太大,本课程将手把手教你学Android Framework开发,带你走进Android系统开发的殿堂,全课程以实战为主...
  • Android系统开发入门[定义].pdf
  • ·此系统最初由"安卓之父"Andy Rubin(安迪-鲁宾)开发(2003年) 2、Android能干什么? 3、系统架构 4、DIV和JVM (1) 首要差别 Dalvik:基于寄存器,编译和运行都会更快些.JVM:基于栈,编译和运行都会慢些 (2) ...
  • android入门到精通

    2016-06-02 17:37:04
    孙更新、邵长恒和宾晟等编著的《Android入门到精通》注重实际动手能力的培养,在遵循技术研发知识体系的严密性的同时,在容易产生错误、不易理解的环节配上翔实的开发实例呈现给读者。每一个实例都经过精心挑选,...
  • NULL 博文链接:https://fanfanlovey.iteye.com/blog/2184117
  • 本文整理了Android开发的学习路线和相关的学习资源,非常适合零基础入门Android的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐! 从零基础入门到可以找到工作的程度,大约准备五个月到六个月左右的...
  • Android系统新手入门 50大必备基础知识

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,888
精华内容 28,355
关键字:

安卓系统入门