Google新技术:Instant App全拆解(4)——架构

作者:Darkbug原文标题:Google新技术:Instant App全拆解(4)——架构原文链接:https://segmentfault.com/a/1190000011648067首发地址:http://www.doncc.org转发请注明转载地址,请尊重原创作者权益!


《Google新技术:Instant App全拆解》系列预告:

第五篇:Google新技术:Instant App全拆解(5)——创建


《Google新技术:Instant App全拆解》系列回顾:

第一篇:Google新技术:Instant App全拆解(1)——初探

第二篇:Google新技术:Instant App全拆解(2)——剖析

第三篇:Google新技术:Instant App全拆解(3)——着手


本文着重介绍在进行Instant App程序开发时需要理解的程序架构,同学们需要首先理解架构里的几个基本概念,然后再需要理解如何进行基本的功能模块架构,甚至更为复杂的程序功能模块架构。只有当理解这些后,才能很顺利的进行程序重构,或者进行Instant App程序开发。

有描述不正确的地方,请及时联系我,我将吸取意见并改正。

1.Instant App程序的结构及概念

在之前的课程我们有介绍,要想进行Instant App的程序开发,必须基于Android Studio 3.0集成开发环境。故后面介绍的所有关于代码的书写,以及在集成开发环境内进行程序架构,本人均在Android Studio 3.0 preview版进行(因为写这文章的时候,最新版也就是preview版)。 -_-||



在Instant App内,有几个非常重要的概念。比如feature、feature modules、feature APK。在做之前,必须先搞懂这几个概念,才能做好你的Instant App程序开发。

瞬时加载程序应该起到的作用是,当你在需要一个功能需求时,从Google Play上可以下载这个程序的部分功能,从而体验到App级的用户体验,用户使用完这个应用的功能模块后,系统会丢掉这个功能模块的代码。不难发现,这个功能,肯定和完整App有着某种密切的联系。那么是什么联系呢?

好的,我们开始根据官方的图来进行程序架构分析。想要分析程序的结构,应从大到小、从外向内进行分析。我们会从下面两个方向进行分析,也就是从外到内。

  • 从程序功能划分程序结构

  • 从功能结构划分工程架构

1.1 从程序功能划分程序结构

如果你的应用程序是带有即时应用的话,那么你在构建你的项目之时,会带有一个或多个即时应用程序APK。这是根据你的程序划分程序功能情况而定,每个功能,可以生成对应功能的即时应用程序APK。

好,明白了这个功能APK后,我们再来看看它是怎么架构的。

我们先来从官方的一张图说起:

从图中我们可知,一个Instant App APK程序内,只有一个Base feature APK,而可以有多个feature APK来构成。换句话说,每个即时应用程序,都会有且只有一个基础功能APK。

换个角度想,如果你的即时应用程序只有一个功能,那么你只需有一个基础功能APK就够了;如果你的即时应用程序有多个功能,那么你需要一个基础功能APK,它包含其他功能所需要用到的共有数据即可,比如不同功能间,界面内会有一些公用的控件、基本信息等,那么这些共有数据就可以放在基础功能APK内,而其他功能APK,具备不同功能即可。

还有另外一种情况。用户已经体验了一个功能了,系统已为用户下载了基础功能APK以及功能APK,如果需要在这个功能内请求数据到另外一个功能内的情况下,系统只会为你下载另一项功能的代码,因为这是基础功能的代码已经存在本地了,无需再次下载了。

怎么样,Google大大的这个设计,是不是感觉简直逆天到爆?总结一句话就是,需要的就下载;不需要的,不下载。这为我们在一定程度上节省了很多宝贵的流量,也减少应用程序所占用的系统空间。(土豪请随意)

1.2 从功能结构划分工程架构

从上面的小结我们可以知道,你的程序其实是按照功能的不同进行区分的,所有功能应有一个基础功能,在基础功能之上,将整个程序划分出不同的功能。那么不同的功能之间,该如何进行代码模块的划分架构呢?

我们再来看下官方发布的另外一张结构图:

从上图我们很清楚的知道,一个Instant App 程序内,只会包含一个基本的功能,而自定义的模块,会依赖于基本的功能块。这是一个很典型的瞬时加载程序的一个单一功能模块的程序架构。而Instant app module是瞬时加载程序的入口点,App module是功能程序的完整代码部分。

好的,我们了解了模块该如何划分后,就可以具体来看下,划分模块时需要配置的详细代码了。(不要跟我说看代码头疼,我们都是程序员)

2.构建单个功能模块的Instant App

想要构建单个功能模块,我们假如按照最简单的结构,可以分为如下:

  • Base features module

  • Android Instant Apps module

  • App module (APK)

这三个方面足以说明一个简单的Instant App结构了。下面我们来逐个详细的了解。

2.1 按模块划分

2.1.1 Base features module

Base Features module的说明,我们可以从两方面谈起。

  • manifest文件的修改

在AndroidManifest.xml文件中,你需要修改application标签的内容。像如下内容:

<application>

       <activity android:name=".MainActivity">

           <intent-filter android:order="1">

               <action android:name="android.intent.action.VIEW" />

               <category android:name="android.intent.category.BROWSABLE" />

               <category android:name="android.intent.category.DEFAULT" />

               <data android:host="myfirstinstantapp.doncc.org"

                   android:path="/"

                   android:scheme="https" />

           </intent-filter>

           <intent-filter>

               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />

           </intent-filter>

       </activity>

</application>

在这里,我们需要修改的东西会多一些。如果细心的同学会发现,其实修改的内容,和我们之前接触的App Links的配置是一致的。这就应了我们之前所述的,Instant App的实现是依赖于App Links的。固然在配置上也是一致的。

这到底是为什么呢?

别忘了,我们根据之前的架构可知,base features module是所有module的基础。也就是说,当系统加载程序时,首先加载的就是这个base features module,那么固然基础信息也就被系统读取到了。

所以你也就可以这么修改你的程序。当你需要一些基础信息,比如<activity>uses-permission等基础信息,可以在base feature module的manifest文件中进行声明,作为基础需要的资源。

或许,你应该懂得,不是整个程序的基础信息,都必须加载进base feature module的manifest中,应是需要的就加载,不需要的就不加载。

  • build.gradle的修改

这里指的gradle文件,是base feature的gradle配置文件。你可以在里面找到android的相关配置。在内部,添加baseFeature true这样的配置即可。比如下面的代码所示:

apply plugin: 'com.android.feature'

android {

   ...

       //add this line

    baseFeature true

   ...

       defaultConfig{

        //delete applicationId    

           ...

       }

}

这样系统在读取gradle配置信息时,会知道这个模块是属于base feature,就会继续找它相应的子模块。你看Google大大已经封装得多么简洁了,真心爽啊。

2.1.2 Android Instant Apps module

在这Instant App模块内,情况有些特殊。这个模块内不包含任何的代码,只包含有构建信息的配置。比如下面的build.gradle文件配置:

apply plugin: 'com.android.instantapp'

...

dependencies {

   implementation project(':base')

}

在这里,我们需要把apply plugin这个配置改为'com.android.instantapp',这是告知构建器本模块是Instant App模块。并且在dependencies模块内,需要指定Instant App模块是实现自谁,也就是从结构上它是谁的子结构。关于结构是怎么分,还需读懂上面的【图FeaturesSingle.png】为妙。

在这个模块内,你可以删除掉这个模块代码的src包,因为这个模块内,没有代码,所以即使添加src包也是没用的。故可以将其删除。

2.1.3 App module (APK)

在这个模块里,如果你需要构建你的Instant App的话,那么这个模块需要包含要所有功能的模块内容和产品的APK。在这个模块内也是比较特殊的 , manifest文件内不包含除<manifest>以外的其他配置标签,因为有关于applicationactivityuses-permission等配置信息,已经在base feature module中配置了,所以不用再进行配置。

这里我们也有个配置样例,可参考如下:

<manifest

   xmlns:android="http://schemas.android.com/apk/res/android"

   package="org.doncc.instantapp">

 <!--remove application-->

</manifest>

在上述代码中,manifest内的package值,要和你的base feature module所配置的包名保持一致。并且你需要移除掉生成的<application>标签。

而在build.gradle文件内,我们也需要进行一些修改:

apply plugin: 'com.android.application'

...

dependencies {

   implementation project(':base')

}

不难发现,如果我们需要构建一个完整的Instant App,我们需要在这个模块内添加结构是实现自谁。根据上面的【图FeaturesSingle.png】可知,我们这个模块是实现自base模块,所以我们需要在build.gradle内填写实现自base模块的语句配置。

2.2 总结

在本章内,我们知道了如何将一个已有的项目,变为Instant App程序架构。其最主要的思想,我们可以总结如下:

  • 抽象父feature module:

是将程序架构成拥有一个最顶级的feature module,这个feature module内集合你的Instant App或者其他子module在运行时需要的一些必要资源内容,包括Activity、Fragment等资源。这样能相对减少你的子module的资源大小,从而减少你宝贵的流量消耗。

  • APK module及Instant App module,共同构成base feature module:

同第一条总结的,当你抽象出base级的feature后,他们构成总体的结构,包括apk module及instantapp module。当然这不仅限于这两个!

  • Instant App应使用App Links作为功能的接入口:

因为App Links具有独特的验证方式,能与Google服务进行互通,且瞬时加载程序是依托于Chrome浏览器来进行交互的。所以需要使用App Links作为功能的接入口。如何验证App Links的重要性也就不言而喻了。如果需要回顾这块儿的课程,请翻阅之前我写过的文章,在那里我有详细介绍有关于App Links的使用。

3.多个feature构建你的Instant App

如果想了解多个feature是如何工作的,那么你首先、务必、一定要理解上个章节的内容,也就是单个功能模块是如何工作的,只有这样你才能很快的理解本章节内容。

3.1 按模块划分

多个feature工作起来其实并不复杂,原理跟单个feature其实是一样的。这里我依照贴心的放上google的官方图片来解释:

有人会说,为什么你只会引官方的图,而不自己做图呢。我想说,官方的图已经很简明扼要的阐述了内容,我们为什么还要重复造轮子呢?

好了废话不多说,来看图说话。看上去连线之间交叉复杂,但是这里面包含很清晰的逻辑关系。别急,跟着我的思路,一点一点理解上面的图。

第一,我们抛开浅绿色以上的图先不看,我们只看浅蓝色以下的部分。一个完整的Instant App,依旧有一个Base Feature,那么它可以引伸出两个子feature,分别是Feature 1、Feature 2。这是什么意思呢?这和我们之前讲过的内容正好相匹配上,一个父级的Feature,可能包含很多子级的Feature,而这些诸多的子Feature共同构成了一个完整的App功能。这也就是Instant App架构的精髓,把一个大的功能完全拆分成不同小部分的小功能,从而减少每个功能块的代码量的大小。

第二,我们再来看浅绿色的区域。我们会发现,Instant App module分别指向了Feature 1和Feature 2,并且App module也分别指向了Feature 1和Feature 2。这里有什么腻么?

还记得App Links的特点么,在你要链接到的Activity,会在manifest文件处进行App Links的配置,链接到你想要访问的Activity。而Instant App恰恰就是运用App Links的机制。也就是说,从Instant App程序入口的操作,会在内部识别你请求的到底是哪个Activity,也就是哪个功能Feature。这样你才会看到,浅绿色的Instant App module分别指向了Feature 1和Feature 2。

第三,我们要格外注意的是,浅绿色的Instant app module和app module需要同时实现自深蓝色的Base Feature,这需要在gradle配置文件内进行额外配置。图中并没有进行描述。这一点需要格外注意。

3.2 总结

好了,这次我们就很容易的理解多个Feature是如何构架你的程序的。思路也不是很复杂,我们总结如下:

  • 将你的程序的大功能模块,分为若干个不同的小feature module。注意,我们之前提到过的不要忘记,每个feature module,尽量不要超过4MB大小。当然这仅仅是建议,尽量去满足他。

  • Instant App module、app module,要实现自每个feature,这样才能让App Links找到不同功能的Feature module。

  • 你的instant app module和app module(假设你有这两个模块作为实现feature的子模块),那么你需要分别实现自base feature module。这样你的子feature才能生效。



本文着重对Instant App程序架构的阐述,从基本的架构概念,到单个功能模块的架构,再到复杂的多功能模块架构,很详细的说明了其结构上的关联性,能让你更轻松的理解Instant App程序开发。

不难看出,其实如果搞懂了Instant App程序架构,那么你在进行程序开发时就会变得易如反掌了。相信看完这篇文章后,后续的课程对于聪明的你来讲,简直可以轻松驾驭。

接下来的文章,我会从Instant App程序的实际操作角度来阐述,瞬时加载程序的魅力之处。



广告位:更多、更有料的IT前沿技术课程,尽在顶级云加。详情请持续关注顶级云加的唯一官方网站:https://yunp.top


《Google新技术:Instant App全拆解》系列预告:

第五篇:Google新技术:Instant App全拆解(5)——创建


《Google新技术:Instant App全拆解》系列回顾:

第一篇:Google新技术:Instant App全拆解(1)——初探

第二篇:Google新技术:Instant App全拆解(2)——剖析

第三篇:Google新技术:Instant App全拆解(3)——着手







Google新技术:Instant App全拆解(3)——着手

作者:Darkbug原文标题:Google新技术:Instant App全拆解(3)——着手原文链接:https://segmentfault.com/a/1190000011315286首发地址:http://www.doncc.org转发请注明转载地址,请尊重原创作者权益!


《Google新技术:Instant App全拆解》系列预告:

第四篇:Google新技术:Instant App全拆解(4)——架构


《Google新技术:Instant App全拆解》系列回顾:

第一篇:Google新技术:Instant App全拆解(1)——初探

第二篇:Google新技术:Instant App全拆解(2)——剖析


本文着重介绍在进行Instant App程序开发时,所需要进行的准备工作,包括集成开发环境的准备,以及准备工作的注意事项。准备工作不是非常繁琐,所以内容照前一篇文章相比相对较少。

如有描述不正确的地方,请及时联系我,我将吸取意见并改正。

1.集成开发环境的准备工作

想要进行Instant App的开发,就需要对其开发环境进行准备。在Android官方SDK提供的内容来看,官方已经为我们提供了完整的SDK。我们只需下载使用即可。

在集成开发环境的准备工作一章内,我将分为两个部分进行阐述:

  • Instant App SDK的导入

  • 系统环境要求

1.1 Instant App SDK的导入

对于导入Instant App的SDK,是比较简单的。在我们最为熟悉的Android SDK Manager内,有为我们提供的下载地址。

操作步骤如下:

  1. 启动Android SDK Manager

  2. 选择“SDK Tools”标签

  3. 勾选中“Instant Apps Development SDK”选项,确定导入

  4. 当导入完毕后,点击“OK”关闭Android SDK Manager

操作预览图如下:

当我们成功导入SDK后,我们就可以利用它进行Instant App程序开发了。当然,这一步的完成,仅仅是可以动手开发的第一步。

1.2 系统环境要求

Instant App开发不是在所有的集成开发环境都可以进行的。在Windows、MacOS、Linux下均进行程序开发。

下面我会列举出系统所要求的环境:

  1. 电脑的JDK 1.8以上

  2. Android Studio version 3.0或以上(包含预览版)

  3. 配置好ANDROID_HOME环境变量

  4. Android SDK 6.0+

  5. Android SDK Tools 25.0+

  6. Android SDK Build Tools 26.0+

  7. Android SDK Platform Tools 25.0+

  8. Android Support Library 最新版本

  9. Android Repository 最新版本

这里要格外说明下,想要进行Instant App开发,必须在Android Studio 3.0及以上的版本上进行开发(包括预览版)。目前官方已到最新的预览版为Android Studio Beta 5,官方已经提供预览版的下载地址:https://developer.android.com/studio/preview/index.html?hl=zh-cn

如已发布正式版,请忽略上面链接,下载正式版即可。

2.模拟器&真机的准备工作

同样,Instant App的开发,是有模拟器与真机的环境要求的。下面我来列举出对于真机及模拟器的系统环境要求:

2.1模拟器的准备工作

  • Android 6.0(API Level 23)及以上版本系统

  • Nexus 5X镜像模拟器

  • 带有Google APIs框架结构的镜像

  • CPU为x86架构

创建模拟器的方法这里我就不再赘述了,相信大伙既然能看到本套教程,也会能知道该如何创建Android模拟器。这里注意,CPU的架构方式不能为x86_64的方式,绝对不能!

2.2真机的准备工作

  • 运行于Android 6.0+(API Level 23及以上)的系统

  • 手机厂商:

    • Google亲儿子:Nexus 5X、Nexus 6P、Pixel、Pixel XL

    • 三星:Galaxy S7(S7 edge)

  • Google 服务框架已安装在手机上。

Google的亲儿子系列是天生自带Google服务框架的,至于三星S7(edge),需要xx上网的方式(你懂得),另安装服务框架。

  当你的真机真正具备上述条件后,接下来的操作尤为重要:

2.3开启Google服务

当你的手机已有Google服务框架后,就可以启动Google账号。当开启Google账号服务后,就可以进行下面的步骤了。具体添加Google账号的方法,请参考如下;如已开启Google账号,请跳过本2.3章节,直接跳到2.4章节阅读。

2.3.1 Samsung Galaxy S7(edge)系列

这里手机系统以Android 7.0为例:

  1. 打开手机设置。

  2. 选择云和账户。

  3. 选择账户。

  4. 选择添加账户。

  5. 添加一个Google账户。当然你得需要xx上网,你懂得。

方法截图如下:

然后你就能在设置界面里,看到Google的选项设置了。

2.3.2 Nexus系列

这里手机以Nexus 5X,预装Android 7.1.1系统为例:

  1. 打开手机设置。

  2. 选择账号。

  3. 选择添加账号。

  4. 选择Google。当然这里同样需要xx上网。。。-_-||

所以你看吧,木有xx上网的童鞋,蓝瘦不蓝瘦,香菇不香菇。

然后你就能在设置界面里,看到Google的选项设置了。

2.4开启免安装应用功能

对于默认的Google账户,是没有开启免安装应用功能的开关的。因为Instant App是新技术,Google并没有强制让用户体验到这个功能,而是自由征集用户的选择。所以如果想要进行Instant App程序开发,这一项的功能开关是必不可少的需要打开。

操作步骤如下:

  1. 打开手机设置

  2. 选择Google账户

  3. 滑动到下面,选择免安装应用

  4. 将关闭状态的开关,置为开启

  5. 在开启的时候,会弹出一个询问对话框,确定启用免安装应用服务,就可以成功打开免安装应用功能了。

这里需要同学们注意几点问题:

  • Google Play Services框架需要在10.0.84+的版本,才能正常使用Instant App程序。

  • 需安装Google Play for Services for Instant Apps即时应用程序服务框架。

这样我们就可以进行Instant App程序开发了。怎么样,是不是感觉有点小激动?写到这里,我们确实发现,在进行Instant App程序开发前的准备工作,其实很简单。

接下来的文章,我会从程序架构方面来讲解Instant App程序开发。


《Google新技术:Instant App全拆解》系列预告:

第四篇:Google新技术:Instant App全拆解(4)——架构


《Google新技术:Instant App全拆解》系列回顾:

第一篇:Google新技术:Instant App全拆解(1)——初探

第二篇:Google新技术:Instant App全拆解(2)——剖析







Google新技术:Instant App全拆解(2)——剖析

作者:Darkbug原文标题:Google新技术:Instant App全拆解(2)——剖析原文链接:https://segmentfault.com/a/1190000011169174首发地址:http://www.doncc.org转发请注明转载地址,请尊重原创作者权益!


《Google新技术:Instant App全拆解》系列预告:

第三篇:Google新技术:Instant App全拆解(3)——着手


《Google新技术:Instant App全拆解》系列回顾:第一篇:Google新技术:Instant App全拆解(1)——初探


本文着重介绍在进行Instant App程序开发时,所涉及的Android周边技术,其目的是更好的进行Instant App程序开发。

如有描述不正确的地方,请及时联系我,我将吸取意见并改正。

1.为何引入Deep Links和App Links的概念

肯定有很多童鞋不理解,为什么我要在讲Instant App技术之前,要提及这个“看似不相关”的概念呢?实则真正在进行Instant App程序开发时,是必然涉及到这标题所述的两个概念的。应该先搞清这两个概念的区别,再来进行程序开发,就会变得易如反掌了。

Google为我们提供了一个非常好的操作体验:比如当我的好朋友给我发了一个定位的链接信息,这个信息我们看上去好像不那么直观得看出,我的好朋友在什么具体位置。但是如果我一旦点击了这个链接,如果我直接能在某个地图应用里看到具体图像位置的话,那么这个体验就会变得更好了。

对于一个链接,当点击后,Google为我们预留了两种的处理方式,这就是Deep Links和App Links。这两种方式,在体验上是截然不同的。所以想要采用哪种处理方式,这就取决于我们自己的决定。

注意,我这里只是在处理链接的角度上讲,如何处理是取决于用户自己。但是对于Instant App技术来讲,是要采用App Links的处理方式。所以这里同学们需要注意。

那么好,接下来我要着重讲解Deep Links和App Links这两个处理URL的方式。

2.Deep Links的作用

要想明白Instant App中的精髓,首先要了解Deep Links是什么东西,以及其本身的作用。

我们来回想一个场景。假如你的手机内安装了UC浏览器(UC浏览器并没有给我充值,先声明),并且还同时存在其他浏览器,当你在一个应用程序内点击一个链接,系统会弹出一个对话框,说明的是让你选择一个可以打开链接的应用或方式。你可以选择系统浏览器,也可以选择UC浏览器;如果你的手机内只有一个可以打开链接的程序(比如只有一个浏览器程序),那么系统就会用这个应用程序直接打开这个链接。

那么结果来了,Deep Links是可以来让用户,通过一段类似URL的链接,达到快速用某个应用打开的作用。当然这也需要用户确认,到底是用哪个程序打开。

好,接下来我们再看下官方对于Deep Links工作的阐述。当用户点击一个链接,或者有一个web URI的请求调用,安卓系统会尝试几个操作,直到操作请求成功:

  1. Open the user's preferred app that can handle the URI, if one is designated.

  2. Open the only available app that can handle the URI.

  3. Allow the user to select an app from a dialog.

将上述的操作放入刚刚我们举得例子里,不难发现,系统内部执行了如下的判断过程:

  • 首先系统判断出哪些程序开放了可以处理URL的程序配置;

  • 其次来看下是不是只有这一个应用程序能处理这个URL;

  • 再次来看下有哪些应用可以处理这个URL;

这个判断的过程,完全有系统来进行。所以要懂得它的判断过程,尤为重要。

2.1进行Deep Links的配置

我们来设定一个情景。当我的朋友给我发来一段链接,内容是这样的:

那么这里我们要区分出来,我们需要在VideoActivity上呈现。这段链接对于intent-filter过滤器来说,scheme部分为“http”,而host部分为“doncc.org”,考虑到我的程序可能应对这个链接下面很多其他的视频,所以我可以选定pathPrefix的过滤方式,这样能包括其他视频的链接一并过滤出来(当然你也可以要求更为严格的过滤)。

对于支持Deep Links的程序的配置,很是简单。或许我们来段manifest文件的过滤器配置更为直观:

<activity android:name=".VideoActivity">    <intent-filter>        <action android:name="android.intent.action.VIEW" />        <category android:name="android.intent.category.DEFAULT" />        <category android:name="android.intent.category.BROWSABLE" />        <data            android:host="doncc.org"            android:pathPrefix="/video"            android:scheme="http" />    </intent-filter></activity>

好,当我们的配置配好之后,就可以将程序运行在模拟器上了。然后将程序退出。

2.2进行Deep Links的验证

验证部分需要打开terminal,并输入命令如下:

$ adb shell am start        -W -a android.intent.action.VIEW        -d <URI> <PACKAGE>

注意这里的<URI>,指的是你在程序内指定的地址。那么应对上述文中,<URI>指定的就是http://doncc.org/video/1.mp4(或者尾部为其他的视频资源),而<PACKAGE>指的是你的程序的package包名。所以当你输入正确的命令并执行后,你的模拟器就会直接看到执行后的页面。说明此时Deep Links已奏效。

特别强调一点。这里我们是直接验证Deep Links是否奏效。然而设置支持此Deep Links的Activity,在第一次呈现时,会有一个选择对话框,因为此Activity添加了其他的过滤器,同样系统内也有跟它一致的过滤器,系统默认是不知道你要用哪个程序打开此链接页面的。所以在提示框内呈现提示用什么应用方式打开。

说了这么多,如果还是没太清楚,可以参考我录制的视频:Android 如何使用 Deep Links 处理URL链接

3.App Links的作用

我们再来看一个应用场景。

或许我们有过这样的体验。当你的朋友用短信的形式,给你发了一篇知乎的文章链接给你,如果你点击了链接,假设你的手机内没有安装知乎程序,那么手机会自动通过浏览器,显示出来这个文章的页面信息;如果你的手机内安装了知乎的程序,那么会直接打开知乎程序,显示出这个文章的信息。

我们之前知道了Deep Links的作用,实则你可以理解成App Links是一个特殊的Deep Links。因为Deep Links在第一次使用时,是需要用户主动进行授权的,而App Links的作用是无需这第一次的主动授权,是足够信任这个链接地址的。当然这样开放,势必会带来安全的隐患。没有关系,Google大大已经为我们想到了这一点了,在Android 6.0以后,程序可以支持App Links来让程序处理默认指定的链接。

相比Deep Links而言,App Links具有一定的优势的:

  • 更安全、更严格:相比Deep Links我们不难发现,在制定具体你的域名地址时,如果指定的条件过于宽泛,势必会可能其他的链接地址后缀也可以访问到你应用程序。如果过于严格的约束,那么所制定的业务有太过于麻烦。所以App Links的出现,就为我们更好的解决这一问题;

  • 更为无缝的用户体验:当你点击一个链接的时候,可能会有一个URL链接到你的网站。如果你的手机内没有安装这个应用,那么链接可以很轻松的重定向到你的网站,不至于页面会弹出一个404 not found的错误,给用户带来非常不好的体验;

  • 可支持Android Instant App瞬时加载技术:可以支持瞬时加载技术。用户无需安装应用,凭一个URL链接,就可以体验到同App一样的用户体验。这一点也是至关重要的,我们也会在后续课程内详细介绍。

  • 可从Google Search中搜到你的应用:同上条一样,我们可以通过Google Search来找到你的应用。这一点也是对我们Instant App有所帮助的一点。

从诸多关于App Links的优点来看,我们可以总结出,想要掌握Instant App技术,首先必须掌握App Links是如何配置的,且App Links是基于Deep Links的。所以我们就知道了该如何去学习了。

好,接下来我们要深入学习关于App Links。

3.1App Links的配置

对于支持App Links的程序的配置,要比支持Deep Links的配置稍加复杂一步。总共可分为两个部分:

  • 对manifest过滤器的编写

  • 数字资产链接文件的生成

接下来我们详细说明每个部分。

3.1.1对manifest过滤器的编写

对于过滤器的编写,我们再来一段代码更为直接:

<activity android:name=".BlogActivity"> <intent-filter android:autoVerify="true">  <action android:name="android.intent.action.VIEW" />         <category android:name="android.intent.category.DEFAULT" />          <category android:name="android.intent.category.BROWSABLE" />          <data             android:scheme="http"             android:host="doncc.github.io"             android:pathPrefix="/2017/" /> </intent-filter></activity>

事实上我们不难发现,这个过滤器的编写,要比之前Deep Links的编写内容,只多了一个属性。那就是:

<intent-filter android:autoVerify="true"> ...</intent-filter>

通过android:autoVerify="true"这个属性,就能让系统知道,这个程序是属于可以自动进行验证的。也就为后续进行数字资产链接文件的验证做好了铺垫。

3.1.2数字资产链接文件的生成

对于数字资产链接,其实是一个json文件,里面包括了一些应用程序的信息,而这个文件需要放置在你的网站的特定路径内。

那么数字资产链接文件该如何写呢?下面来看个例子:

[{  "relation": ["delegate_permission/common.handle_all_urls"],  "target": {    "namespace": "android_app",    "package_name": "org.doncc.learnapplinks",    "sha256_cert_fingerprints":    ["01:CD:30:56:A8:5E:EC:18:64:3D:8B:F2:AF:3F:B6:02:85:33:79:13:97:23:E3:FF:99:59:14:E5:03:FC:57:78"]  }}]

从上面的例子可以得出结论,数字资产链接文件配置的要求,有如下内容:

  • 需知道你应用的包名(package_name)

  • 需知道你发布程序的sha256指纹签名证书(sha256_cert_fingerprints)

对于包名,我们肯定知道该如何获得。而对于sha256指纹签名证书,我们可以通过命令来获取到。比如我发布的程序是用release.keystore来签名的,那么你在用命令行获得sha256签名时,就要指定你的key来获得:

$ keytool -list -v -keystore release.keystore

当生成完毕后,需要把这个文件重命名为assetlinks.json,并上传到你的网站的特定目录内:

https://domain.name/.well-known/assetlinks.json

其中domain.name部分为你的具体的网站地址。而需要在你的网站下面的.well-known目录下,新建assetlinks.json文件,也就是刚配置过的数字资产链接文件,来确定你的网址是可信的。

如果我们的网站会忽略隐藏文件,那么强烈建议你写一个取消忽略的配置文件。这个过程就不需要我讲了吧。。。

3.2App Links的验证

同样,对于App Links的验证,总体也可以分为两部分:

  • 对数字资产链接文件配置合法性的验证

  • 通过Shell命令验证

同样,我们详细说明每个部分。

3.2.1对数字资产链接文件配置合法性的验证

在进行App Links的验证过程要注意一点,根据官方说明,在程序安装完毕后,至少等待20秒后再进行链接的验证是最为好的。并且要保证你的网络足够好,因为在验证过程,系统识别一旦超过5秒,那么就会验证失败,以至于会出现和Deep Links同样的用户效果了。

Note: Make sure you wait at least 20 seconds after installation of your app to allow for the system to complete the verification process.

  • 通过网页的验证链接进行验证

我们可以首先来通过网页访问的形式,来确定我们自己的数字资产链接文件是否已经被网站关联上。这里我们给出官方的网页URL:

https://digitalassetlinks.googleapis.com/v1/statements:list?   source.web.site=https://domain.name:optional_port&   relation=delegate_permission/common.handle_all_urls

这里source.web.site是需要替换成我们自己的网站地址的。然后点击回车,如果出现类似下面页面,就说明当前数字资产链接文件已经被网站关联上了:

{  "statements": [    {      "source": {        "web": {          "site": "https://doncc.github.io."        }      },      "relation": "delegate_permission/common.handle_all_urls",      "target": {        "androidApp": {          "packageName": "org.doncc.l02learnapplinks",          "certificate": {            "sha256Fingerprint": "01:CD:30:56:A8:5E:EC:18:64:3D:8B:F2:AF:3F:B6:02:85:33:79:13:97:23:E3:FF:99:59:14:E5:03:FC:57:78"          }        }      }    }  ],  "maxAge": "599.298570247s",  "debugString": "********************* ERRORS *********************\nNone!\n********************* INFO MESSAGES *********************\n* Info: The following statements were considered when processing the request:\n\n---\nSource: Web asset with site https://doncc.github.io. (which is equivalent to 'https://doncc.github.io')\nRelation: delegate_permission/common.handle_all_urls\nTarget: Android app asset with package name org.doncc.l02learnapplinks and certificate fingerprint 01:CD:30:56:A8:5E:EC:18:64:3D:8B:F2:AF:3F:B6:02:85:33:79:13:97:23:E3:FF:99:59:14:E5:03:FC:57:78\nWhere this statement came from:\n  Origin of the statement: Web asset with site https://doncc.github.io. (which is equivalent to 'https://doncc.github.io')\n  Include directives followed (in order):\n    \u003cNone\u003e\nMatches source query: Yes\nMatches relation query: Yes\nMatches target query: Yes\n\n--- End of statement list. ---\n\n\n"}
  • 借助Google Digital Asset Links工具验证

还有一种验证方法,借助Google Digital Asset Links这个工具,就能进行验证。

文中所填写的内容,正是你在配置前面assetlinks.json数字资产链接文件的信息。填写进去,进行验证。如果验证通过,说明你的网站已通过安全验证,可以愉快的使用App Links了。

  • 借助App Links Assistant的测试工具验证

事实上还是有其他方法进行验证,借助App Links Assistant的测试工具进行验证。这部分我们会在后部分讲到。

3.2.2通过Shell命令验证

  • adb命令构建URL Intent:

验证的过程和验证Deep Links类似。我们可以用构建URL Intent的方式来进行模拟链接的验证:

adb shell am start -a android.intent.action.VIEW \    -c android.intent.category.BROWSABLE \    -d "http://domain.name:optional_port"

注意,这里-d的内容需要替换成我们自己的网站地址。

如果成功,那么立即就会在模拟器上看到执行后的效果,直接的跳转到所在的Activity,而无需经过用户点击弹出框的确认过程。

这里我贴出关于App Links在开发时的视频:如何使用 App Links 处理URL链接

4.通过App Links Assistant来协助配置

不难发现,实则Deep Links和App Links都有异曲同工之妙。我们从上面的内容来看,确实配置过程有点繁琐。幸好Google大大们已经为我们着想了这一点,在Android Studio 2.3版本及以上版本,内置了一个App Links Assistant的链接生成助手。根据这个助手的指引,我们就能很快的配置出属于我们自己程序的App Links,甚至是Deep Links。

那么这个助手该如何找到呢?在你的Tools > App Links Assistant,就可以找到了。

这里具体有一些如何使用App Links Assistant进行配置的文章描述,我们就不再赘述了,官方的文档已经很详尽的说明了这一点。如需参考请异步地址:Add Android App Links

5.Deep Links和App Links的对比

这里我们引自官方的对比表格更为直接。(来自:the-difference



Deep LinksApp Links
Intent URL schemehttp, https, or a custom schemeRequires http or https
Intent actionAny actionRequires android.intent.action.VIEW
Intent  categoryAny categoryRequires android.intent.category.BROWSABLE and android.intent.category.DEFAULT
Link verificationNoneRequires a Digital Asset Links file served on you website with HTTPS
User experienceMay show a disambiguation dialog for the user to select which app to open the linkNo dialog; your app opens to handle your website links
CompatiblityAll Android versionsAndroid 6.0 and higher

我们不难看出,App Links的出现是弥补了Deep Links的一些不足。当然使用起来也应该酌情而定,毕竟Deep Links的超高自由度,也是后者望尘莫及的。说了这么多,再结合Instant App,我们就可以总结出以下几点:

  • 在Instant  App内使用App Links,具有更为安全的通信协议,也为协议的验证做好铺垫;

  • 因为使用即时应用的前提,是点击一个链接直接跳转到界面,所以在Intent处理上,严格要求处理动作是android.intent.action.VIEW

  • 同上面描述的,Instant App也需要可以在网络上搜索到,并打开程序,比如Google搜索结果页面上打开。固然需要Intent的种类是android.intent.category.BROWSABLEandroid.intent.category.DEFAULT

  • App Links是可以对URL链接进行安全验证的,而Deep Links是不具有验证功能的。其目的是为了能让Android程序足够信任其URL链接地址,减少让用户选择“xxx方式打开”这种动作歧义的对话框出现,在用户体验上能更让用户觉得是“无缝”的感觉;

  • 对于链接点击处理功能的兼容,Deep Links能兼容所有Android版本,而App Links只兼容Android 6.0及更高的版本。

但是话有说回来,不难发现,在App Links与Deep Links的处理场景是很受局限的。大多数的程序是不经过系统处理的,而是直接内置方式处理。比如某聊天工具。。。这就给其推广造成很大的阻碍,而能实现处理的地方有短信、内置浏览器内等一些原生App内。真是心塞。

好,这回我们就能彻底的了解了这两种URL链接处理方式了。

6.总结

对于Instant App程序开发,是依赖于App Links处理URL的方式,并且App Links又是一种特殊的Deep Links,也就是必须先知道Deep Links的作用,才能知道App Links的作用。

Deep Links的出现,是为了能让用户在不同应用见体验到App级的用户体验,而App Links的出现,是为了让这种体验更加“无缝衔接”;

对于App Links,需要一个数字资产链接文件的验证,这个文件是必须放在网站根目录/.well-known/assetlinks.json这个路径下,才能生效;

对于数字资产链接文件,其内部注意你的程序的签名,如果程序是released版本,那么你的签名指纹也需要换成对应的指纹;

对于App Links,需要在过滤器内添加android:autoVerify="true"属性,保证系统能识别到。





讲到这里,我们就可以初步了解了有关于制作Instant App的周边技术了。接下来我还会有更多的文章来持续讲解Instant App程序开发。


《Google新技术:Instant App全拆解》系列预告:

第三篇:Google新技术:Instant App全拆解(3)——着手


《Google新技术:Instant App全拆解》系列回顾:

第一篇:Google新技术:Instant App全拆解(1)——初探





Google新技术:Instant App全拆解(1)——初探

作者:Darkbug原文标题:Google新技术:Instant App全拆解(1)——初探Segmentfault社区首发地址:https://segmentfault.com/a/1190000010906162转发请注明转载地址,请尊重原创作者权益!


《Google新技术:Instant App全拆解》系列预告:第二篇:Google新技术:Instant App全拆解(2)——剖析


本文开始,接下的几篇文章内,我会从概念、技术等方面,将着重介绍Google发布的最新Android Instant App技术,并描述如何制作属于自己的Instant App。

1.Instant App是什么

记得在2016年的Google大会上,Google大大就已经发布了有关Instant App的最新技术了。然而这款被人们寄予厚望的“黑科技”技术在发布之后,并没有像想象中推广的很好,究其原因我怀疑是因为当时发布的时候,所开发的步骤过于繁琐,才不得不将这个技术的推广拖延至今。

我们先来用下面的动图回顾体验下,Instant App的厉害之处:

从图中我们初步可以看出,当操作者在点击一段Buzzfeed的视频链接时,会自动的加载这个链接所属程序的代码,并且很轻松的在这个“程序的APP内”体验到这个链接视频效果。

其实这就是Instant App,翻译成中文可以称之为瞬时程序加载,也可以称之为即时应用。它出现的目的,就是为了让人们能够像点击链接那么简单,节省掉安装App的痛苦,最快速度、最少流量的消耗,让用户体验到App级的用户体验。

事实上,Instant App的优点不仅如此,我们同样可以在Google的浏览器内,搜索具备Instant App能力的App的名字,也会得到相应的即时应用,同样能够让你体验到App的交互效果。比如下面我想在wish购物App内,购买Valentino Rossi的周边物(谁让我是个罗西粉),只需在Google搜索栏里,输入“wish Rossi”,你就会看到有关在wish中的一些物品,并且会在内容描述处,看到一个“Instant”标识。也就是说,当你点击这个链接后,你就能体验到属于wish应用的Instant App应用体验。下面有个我录制的微视频,简单的描述了下这个过程。

Instant App初体验-youku

怎么样,这个交互效果简直是棒极了吧!

如果细心的朋友肯定会发现,其实早在2015年,Google就已经推出了另外一项技术:App Links。其用意是想当用户点击链接后,能快速链接并打开本地所属应用,而无需经过用户的二次同意。这么做的优点是避免了用户的艰难选择,特别是对于那些选择困难户的童鞋来说。这些内容我会在后面文章着重介绍。

如果这么说比较笼统,那么你肯定遇到过这样情景,你的手机内除了浏览器这个内置App外,如果还安装了类似UC浏览器、360浏览器、各种浏览器。。当你想点击一个链接时,会在手机下方弹出一个对话框,提示你用什么App来打开你的链接。这种让你二次选择的感觉,着实让人感觉有点啰嗦。而App Links的出现,能让你无需再选择,直接选用你已经设定好的方式打开应用进行体验。

说了这么多额外的,我觉得其实Google就是为Instant App的出现做了前期铺垫。真是好大一盘棋啊!

2.Instant App现阶段遇到的困难

从上面的内容,想必大伙已经知道一部分了吧。对于Instant App技术的使用,可以分为如下几个方面来讲:

  • xx上网(你懂的)

  • Google Service不能正常的推广

  • 具有Google Service框架的手机

从这一点,我要格外说明的是,所有谷歌亲儿子手机,都是天生具有Google Service框架的,谁让他是亲儿子。还有一个是三星的s7 edge这款手机,自从升级到7.0系统后,就能让我们自己通过xx上网的方式,同样体验到Google Service框架。这次三星也算是开明了一把。这里想下,s8是不是同样也可以,虽然我没有s8。

  • 完整应用必须提前安装到Google Play上

如果想体验到Instant App的交互效果,首先你要保证的是,你的完整应用程序,需要在Google Play上成功发布。也就是说,要想将你的应用程序变为Instant App所支持效果,需要进行一定的程序修改。有关如何修改,后续我会用文章着重描述。

  • 部署信息验证文件的网站,需具有https方式访问功能的网站。

这个对于一般小众开发者来讲,着实是让人头疼。索性我在实施的时候,干脆将自己的虚拟网站,部署到GitHub上,这样一来能模拟我的网站,不会把大量的时间花费在搭建网站上,又能解决掉SSL证书的问题。一举两得。

3.Instant App瞬时加载程序与微信小程序的对比

2016年的Google I/O大会,发布了Instant App技术,而微信小程序公开内侧的时间是同年9月21日。这其中是否有一些某种不言而喻的关系,我不得而知,我也不想去猜想。你们自己体会好了。

为什么我会拿小程序与Instant App技术相对比呢?很显然,他们共同点都是号称“不用安装,就能体验、使用”。对于程序的热爱,我不得不拿来进行对比一番。我会从各个角度进行中肯的对比,不偏不向。

  • 从部署到手机角度讲:

这一点简直是小程序完胜,毕竟Google Service不能正常的引进大陆,这一点上小程序占尽了天时地利。不知道是不是小龙哥看到了这个痛点。

小程序可以利用微信的小程序功能,添加附近商家的小程序,也可进行搜索小程序;而Google的Instant App,想要使用此项技术,必须要保证你的完整App要在Google Play上有正式发布,用官方的话来说,我们要让用户体验到无缝对接。这一点来看,只能说仁者见仁智者见智罢了。个人感觉还是Google做的更为周到细致,虽然在大陆没什么卵用。

  • 从程序体积来讲:

从这一点来讲,Instant App的控制要比小程序要好。在Google官方要求里,每个Instant App程序最大不得超过4M的大小,一旦超过,必须重新划分模块,再缩减体积;而小程序来讲,没有一个明确的大小上线,如果业务简单,你可以控制在1M-2M的大小,如果业务复杂,包大小也能达到10M都不足为奇。所以这一点对于用户来讲,用户肯定喜欢用最少的开销,体验到业务。我们肯定不希望大把的手机空间,浪费了交给一个程序,特别是对那些手机空间严重不足的用户。我觉得这一点Instant App胜利。

  • 从存储角度来讲:

对于小程序,数据会存储到手机的存取区域,并且每次加载小程序时,是加载本地存储优先。Instant App则是将程序的部分代码下载下来存储到本地存储,同样在每次加载时,也会优先检查本地存储是否有代码。从存储机制来讲,差别不太大。如果从底层实现的方式来看,小程序利用的是H5的存储机制,Instant App利用的是常见的java存储机制。我觉得从这一点来看,没什么比的必要,都还不错。

  • 从页面解析速度来讲:

其实用户关注的这一点是尤为重要。对于小程序而言,毕竟底层是用HTML的实现方式,而Instant App底层用的是java的实现方式。

在小程序的展现过程,首先利用微信小程序特有的编码方式,转换成HTML,再来渲染、解析、展现等操作;而Instant App不需要这么麻烦,它天生就可以用Android来编写,然后通过下载这部分代码到本地,使用Instant App时,显然就是本地应用的用户体验,流畅度要比HTML页面展现的方式顺滑很多。这是Instant App能绝对胜出的一点。



综合对比,Instant App从用户体验角度来看,要比小程序好很多,体验起来让用户感觉,有种“我并没有安装这个程序,就能体验到和程序同样的丝滑体验”的感觉。但是从可实施角度看(我指的是只在大陆范围内),Instant App天生就不如微信小程序,因为啥?你懂得。 -_-||

当然,喜不喜欢这个技术,做不做这个技术,由你来做决定。如果你喜欢这个技术,我假设你是可以来克服这个不可实施的问题,来介绍后面的文章;如果您觉得不可实施,看到此为止就可以了,也没有什么必要往后看去浪费时间。



好了,今天就介绍到这,预告下下一篇文章,我会在技术层面上来着重介绍Instant App这项技术所用到的周边技术。


《Google新技术:Instant App全拆解》系列预告:第二篇:Google新技术:Instant App全拆解(2)——剖析







Docker与宿主之间拷贝文件

参考:https://stackoverflow.com/questions/22907231/copying-files-from-host-to-docker-container

The cp command can be used for that. For example:

docker cp foo.txt mycontainer:/foo.txt
docker cp mycontainer:/foo.txt foo.txt

Reference: Docker CLI docs for cp

Note that docker cp is not new in Docker 1.8. In older versions of Docker, the docker cp command only allowed copying files from a container to the host



导入导出Docker镜像

转自:https://www.jamescoyle.net/how-to/1512-export-and-import-a-docker-image-between-nodes

One of the driving forces behind Docker is to create a consistent environment across all Docker enabled machines and to create portable templates, or images, which can be ran on any Docker enabled server.

It would, therefore, make perfect sense that Docker have made it very easy for us to export a running container and re-import it on another Docker server.

Lets assume, for this example, that you have a running container that you would like to move to another host. The summary of the process is to save the container to an image, save it to a tar file, move it to your new host and load the image into the new docker server.

Find the ID of the container that you would like to move.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f4b0d7285fec        ubuntu:14.04        /bin/bash           38 minutes ago      Exit 0                                  hungry_thompson
8ae64c0faa34        ubuntu:14.04        /bin/bash           41 minutes ago      Exit 0                                  jovial_hawking
3a09b2588478        ubuntu:14.04        /bin/bash           45 minutes ago      Exit 0                                  kickass_lovelace

I’m going to use the above 3a09b2588478 ID for this example.

Commit your changes and save the container to an image called mynewimage.

$ docker commit 3a09b2588478 mynewimage
4d2eab1c0b9a13c83abd72b38e5d4b4315de3c9967165f78a7b817ca99bf191e

Save the mynewimage image to a tar file. I will use the /tmp/ directory to save the image but you could easily use a NFS share to make it easier to move the completed tar file.

$ docker save mynewimage > /tmp/mynewimage.tar

Copy the mynewimage.tar file to your new Docker instance using whatever method works in your environment, for example FTP, SCP, etc.

Run the docker load command on your new Docker instance and specify the location of the image tar file.

$ docker load < /tmp/mynewimage.tar

Finally, run the docker images command to check that the image is now available.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mynewimage          latest              4d2eab1c0b9a        5 minutes ago       278.1 MB
ubuntu              14.04               ad892dd21d60        11 days ago         275.5 MB
<none>              <none>              6b0a59aa7c48        11 days ago         169.4 MB
<none>              <none>              6cfa4d1f33fb        7 weeks ago         0 B



Kotlin Native调用C语言

示例代码下载:https://github.com/plter/SimpleKotlinNativeCallCDemo

Kotlin Native 调用C语言的简单示例

  1. 下载并编译Kotlin native https://github.com/JetBrains/kotlin-native

  2. 创建hello.h文件,在其中输入如下代码

    void sayHello();



  3. 创建hello.c文件,在其中输入如下代码

    #include "hello.h"
    #include <stdio.h>
    
    void sayHello(){
        printf("Hello Kotlin Native\n");
    }
  4. 创建hello.def文件,在其中输入如下代码

    headers = hello.h 
    headerFilter = hello.h



    在默认情况下cinterop会分析引入所有的头文件,而此时并无必要,所以配置headerFilter属性为hello.h目的是只分析引入该文件

  5. 执行如下命令用以分析hello.h文件,并自动生成kotlin定义

    cinterop -def hello.def -copt -I. -o hello



    其中-I指的是头文件目录,-o指的是输出名字,该命令执行后将生成目录结构如下图所示

    1320273508802494391648.png

  6. 执行如下命令用于生成本机库(native library)文件

    clang -c hello.c -o hello.bc -emit-llvm



    该命令将生成hello.bc文件,如下图所示

    1321245209542364981074.png

  7. 创建main.kt文件,在其中输入如下代码

    import hello.*
    
    fun main(args: Array<String>) {
        sayHello()
    }



  8. 执行如下命令编译该程序

    kotlinc main.kt -library hello -nativelibrary hello.bc -o main



    该代码将生成main.kexe文件

  9. 执行该文件,将会看到输出信息,效果如下图所示

    13221725847208876626.png



下载及编译Android源码

说明

本教程演示如何编译 Android 源码,目的是教会你如何基于aosp(Android open source project)定制Android系统。教程演示所使用的手机是Nexus6,但本教程是通用教程,并不局限于Nexus6,只要你有合适的驱动包,你就可以面向任意机型做定制。

源码及相关资源归档https://pan.baidu.com/s/1kUAj9kF

观看视频教程http://yunp.top/m/course/v/2 

推荐学习机型

  • Nexus 5X

  • Nexus 6

  • Nexus 6P

  • Nexus 9

  • Nexus Player

  • Pixel

  • Pixel C

  • Pixel XL

基本硬件要求

名称需求
电脑CPU双核4线程2GHz或者更高配置的CPU
电脑内存16G物理内存
电脑磁盘至少200G可用的磁盘空间,固态硬盘更好
电脑操作系统Ubuntu 16.04
Android手机Google Nexus 6

准备Ubuntu环境

  1. 全新安装Ubuntu 16.04 操作系统(安装到虚拟机也可以,至少为虚拟机分配16G内存,否则容易出错,这可能要求你的宿主计算机具有24G以上的物理内存)

  2. 执行如下命令进行更新

    sudo apt-get update
  3. 执行如下命令安装jdk8

    sudo apt-get install openjdk-8-jdk
  4. 执行如下命令安装依赖项

    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 x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
  5. 如果想使用SELinux tool 则还应该安装 python-networkx ,通过执行如下命令进行安装

    sudo apt-get install python-networkx
  6. 如果使用LDAP,则还应该安装 libnss-sss:i386 ,通过如下命令进行安装

    sudo apt-get install libnss-sss:i386
  7. Ubuntu默认不允许普通用户使用USB,所以还应该配置Android USB设备能够被当前用户访问到,则需要执行如下命令

    wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules

    注意:执行该命令需要翻墙

    国内用户可执行如下命令

    wget -S -O - http://yunpstatic.oss-cn-beijing.aliyuncs.com/res/android/source/51-android.txt | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules

安装并配置代码管理工具 repo

  1. 在当前用户目录下创建 bin 目录,可通过如下命令创建

    mkdir ~/bin
  2. 通过如下命令下载 repo ,并将其放在 ~/bin 目录中

    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

    注意:执行该命令需要翻墙

    国内用户可以使用这条命令来执行

    curl http://yunpstatic.oss-cn-beijing.aliyuncs.com/res/android/source/repo > ~/bin/repo
  3. 通过如下命令给repo添加可执行权限

    chmod a+x ~/bin/repo
  4. 通过如下命令初始化git用户名

    git config --global user.name "Your Name"
  5. 通过如下命令初始化git邮箱

    git config --global user.email "you@example.com"

下载Android源代码

  1. 创建一个目录用于存放Android源码,如我存放的路径是 /Work/AndroidSource/Nexus6/source ,并使用终端进入该目录

  2. 通过如下代码初始化 Nexus 6 源码仓库

    repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.1_r28

    其中 -b 参数指明将下载的代码分支 如果要下载master分支,则不需要加任何参数,则执行的命令如下

    repo init -u https://android.googlesource.com/platform/manifest

    您也可以根据自己的需要来选择合适的分支进行下载,分支与匹配机型参考表网址是



    http://source.android.com/source/build-numbers.html#source-code-tags-and-builds



    注意:访问该网址需要翻墙

  3. 执行如下命令下载(同步)代码

    repo sync

    目前默认使用4个任务同步代码,如果你的机器足够好,可以指定更多的任务,如下命令演示使用8个任务同步代码

    repo sync -j8

    说明:同步代码可能需要很长时间,你需要一个较好的网络环境和一个较稳定的翻墙工具,按平均状况来看大约需要2天时间,视频教程里有介绍如何使用我已经下载好的用百度云共享的代码,好的网络环境和好的电脑配置可在2小时内完成该任务

配置厂商提供的驱动

  1. 访问页面 https://developers.google.com/android/drivers 查找配置自己机型的驱动(我这里查找的是Nexus 6的驱动)



    注意:访问该页面需要翻墙

  2. 下载 Nexus6 驱动包,如下图所示这三项均需下载



    0838069700842164411014.png



  3. 驱动包文件都是压缩包,在压缩包中包括一个sh文件,该sh文件为自解压脚本,分别将这3个sh文件放在Android源码树的根目录,比如/Work/AndroidSource/Nexus6/source,并执行依次执行这3个文件以自动配置驱动包,配置完成后将在源码树根目录中多出一个vendor目录。



    注意:在执行3个sh文件时会呈现协议条款,请慢慢看,不要跳过I ACCEPT那一步,否则不解压



编译Android源码

  1. 执行如下命令进行清理

    make clobber
  2. 执行如下命令加载环境变量

    source build/envsetup.sh
  3. 执行如下命令选择构建目标

    lunch aosp_shamu-userdebug

    如果想选择其它目标,请直接执行 lunch ,将会呈现一个目标列表,可根据自己的手机型号进行选择,如果只想运行在模式器中,可以选择第一项或者直接执行 lunch aosp_arm-eng

  4. 执行如下命令进行编译

    make -j4

    该命令使用4个任务进行编译,如果电脑不够好,编译过程可能会持续10小时或更久,如果电脑足够好,也可以指定更多任务,如 make -j32 是指定32个任务进行编译。

编译必备的工具

说明:如果你已经安装Android sdk,也可以使用sdk内置的命令。

  1. 执行如下命令编译 adb

    make adb
  2. 执行如下命令编译 fastboot

    make fastboot

运行

  1. 进入手机 设置 -> 开发者选项 (如果没有该选项,请进入 设置 -> 关于手机,连续点击 Build number 7次以启用开发者模式),启用USB调试和OEM解锁

  2. 将手机通过USB连接电脑,执行命令 adb reboot bootloader 以进入手机的Bootloader模式,也可以通过手机硬键操作进入Bootloader模式,查看不同手机操作方式列表请访问 http://source.android.com/source/running.html注意:访问该网址需要翻墙)。

  3. 解锁Bootloader,执行命令 fastboot flashing unlock ,2014年或更老的手机请执行 fastboot oem unlock ,你必须通过手机屏幕确认该操作。

  4. 执行如下命令格式化缓存

    fastboot format cache
  5. 执行如下命令格式化用户数据

    fastboot format userdata
  6. 执行如下命令将系统写入手机

    fastboot flashall -w

    写入成功后手机将重启进入您编译的操作系统

  7. 如果您想长期安全的使用该手机,可以通过命令 fastboot flashing lock 锁定Bootloader,2014年或更老的手机请执行 fastboot oem lock ,之后进入手机系统,在开发者选项中取消OEM解锁。

git保存用户名和密码

在 .git/config 文件中加入如下内容即可

[credential]
    helper = store