[rk3399][Android 6.0] 使用系统签名APP应用

如需要深入了解make文件的编写和build系统,可以先看看这篇文章《Android系统源码Build入门详解》,本篇文章不对make文件进行深入的解释,但是会在make文件上做相当部分的注释。如果你是刚接触系统源码移植,强烈建议按照以下阅读顺序一个一个Demo自己写,然后测试运行,在确保理解的前提下提高自己的编码水平和源码认知水平。

文章思路大致为:

  1. 最简单的android源码移植HelloWorld
  2. 含有jni本地代码的源码移植
  3. 含有第三方jar包的源码移植
  4. 往系统源码中添加自己的纯java源码并打包成jar
  5. 含有第三方so文件的源码移植
  6. 既有so又有第三方jar的源码移植
  7. 自有java源码包+so+三方jar+本地源码的综合项目
  8. 添加公用so共享库并打包进system.img

移植HelloWorld

相信我们接触Android第一个练手项目就是HelloWorld,不过那是在IDE上开发的,这次我们需要把这个HelloWorld工程移植到系统源码中,并编译成目标Apk。关于不带jni的项目也可以参考源码树中/development/samples/HelloActivity工程,可以说,google为开发者考虑的还是很周到的。

(一)修改mk文件。
1.在Android内核源码中选择一个目录来存放HelloWorld应用的源码,比如放到/packages/apps目录下。
2.在HelloWorld目录下新建Android.mk文件,示例如下:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> LOCAL_PATH:= $(call my-dir)</pre>

2

<pre class="CodeMirror-line"> #清理缓存变量</pre>

3

<pre class="CodeMirror-line"> include $(CLEAR_VARS)</pre>

4

<pre class="CodeMirror-line"> #表示目标模式</pre>

5

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS := samples</pre>

6

<pre class="CodeMirror-line"> #表示源文件编译路径 这个应用里面只有java源文件</pre>

7

<pre class="CodeMirror-line"> LOCAL_SRC_FILES := $(call all-java-files-under, src)</pre>

8

<pre class="CodeMirror-line"> #表示项目包名也就是模块名,在项目中唯一</pre>

9

<pre class="CodeMirror-line"> LOCAL_PACKAGE_NAME := HelloWorld</pre>

10

<pre class="CodeMirror-line"> #指定编译sdk版本为当前版本</pre>

11

<pre class="CodeMirror-line"> LOCAL_SDK_VERSION := current</pre>

12

<pre class="CodeMirror-line"> # 使用该指令编译目标Apk.</pre>

13

<pre class="CodeMirror-line"> include $(BUILD_PACKAGE)</pre>

14

<pre class="CodeMirror-line"> #搜索编译该源码目录下所有的mk文件,如果没有可以不写</pre>

15

<pre class="CodeMirror-line"> include $(call all-makefiles-under,$(LOCAL_PATH))</pre>

16

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

注:LOCAL_MODULE_TAGS的备选值有user,eng,tests,optional,本示例中使用的TAGS值为eng(工程模式,自带root),因此,仅当用户指定的编译选项为eng时才会编译该工程。否则会停止编译,默认值为optional。具体可以参考文章《Android系统源码Build入门详解》

(二).配置makefile,添加新的项目

注意,这是很关键的一步,如果忽略了你是没办法在编译成的system.img里面找到这个工程的。

选择 /device// /xxxx.mk,或者从 build/target/product/ 目录下选择一个被“引用”的.mk,比如我用的是build/target/product/core.mk ,如果是在/devices/下指定产品下修改添加,则只会在指定目标产品生效,如果你的工程对所有产品有效,建议添加在/build/target/product/core.mk中。

最重要的是在其中的PRODUCT_PACKAGES参数列表中添加本工程:如果不添加的话整编出来的竞相里面是没有添加到源码树的应用的。下面要提到的添加公用so文件也是需要在这个地方添加,添加的方式则是把mk文件中的标识名填上(LOCAL_PACKAGE_NAME或者LOCAL_MODULE)。

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> PRODUCT_PACKAGES := \ </pre>

2

<pre class="CodeMirror-line"> DeskClock \ </pre>

3

<pre class="CodeMirror-line"> Calculator \ </pre>

4

<pre class="CodeMirror-line"> Calendar \ </pre>

5

<pre class="CodeMirror-line"> Camera2 \ </pre>

6

<pre class="CodeMirror-line"> Email \ </pre>

7

<pre class="CodeMirror-line"> HelloWorld//这个是我的工程</pre>

8

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

(三)编译
在HelloWorld目录下输入mm命令,或者切换到Android源码根目录下执行下面任意一条命令即可:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">make HelloWorld</pre>

2

<pre class="CodeMirror-line">mmm package/apps/HelloWorld</pre></wiz_code_mirror>

编译生成的apk会放到在out/target/product/《your product》/system/app/目录下。

含有第三方jar

Android开发中经常会用到一些开源库,使用Eclipse作为开发工具的时代,第三方库基本都是jar包的形式存在的。现在我们讨论一下怎么在源码中使用第三方库。
使用第三方库其实也是很简单,只需要修改mk文件,按照如下方式修改即可,有一些公用的库可能在你的系统远吗工程需要多次引用,你可以把这些库单独做一个Android.mk并对每一个要使用的库添加标识。

第三方库包括两个部分,一个是引用,一个是模块定义。正如上面所说,这两个是可以放在不同的mk文件中的,假设我们的apk程序名为SayhelloFromJar,在这个apk里面引用了一个叫testlib.jar的第三方库。我们这么写:
Android.mk

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PATH:= $(call my-dir)</pre>

2

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

3

<pre class="CodeMirror-line">​</pre>

4

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional</pre>

5

<pre class="CodeMirror-line">​</pre>

6

<pre class="CodeMirror-line">LOCAL_STATIC_JAVA_LIBRARIES := testlib</pre>

7

<pre class="CodeMirror-line">​</pre>

8

<pre class="CodeMirror-line"># Only compile source java files in this apk.</pre>

9

<pre class="CodeMirror-line">LOCAL_SRC_FILES := $(call all-java-files-under, src)</pre>

10

<pre class="CodeMirror-line">​</pre>

11

<pre class="CodeMirror-line">LOCAL_PACKAGE_NAME := SayhelloFromJar</pre>

12

<pre class="CodeMirror-line">LOCAL_PRIVILEGED_MODULE := true</pre>

13

<pre class="CodeMirror-line">​</pre>

14

<pre class="CodeMirror-line">#LOCAL_SDK_VERSION := current</pre>

15

<pre class="CodeMirror-line">​</pre>

16

<pre class="CodeMirror-line">include $(BUILD_PACKAGE)</pre>

17

<pre class="CodeMirror-line">​</pre>

18

<pre class="CodeMirror-line">#############################################</pre>

19

<pre class="CodeMirror-line">##上面这部分和前面的HelloWorld基本是没区别的,唯一的区别就是添加了一句</pre>

20

<pre class="CodeMirror-line">##LOCAL_STATIC_JAVA_LIBRARIES := testlib</pre>

21

<pre class="CodeMirror-line">##下面则是对于这个jar的定义,假设这个jar在libs/testlib.jar</pre>

22

<pre class="CodeMirror-line">##################### add third part library #######################</pre>

23

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

24

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=testlib:/libs/testlib.jar</pre>

25

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional</pre>

26

<pre class="CodeMirror-line">include $(BUILD_MULTI_PREBUILT)</pre></wiz_code_mirror>

上面是合并的写法,前面说过,这个jar很可能要被多个apk引用,为了管理方便,我们可以分开来写:
Apk的Android.mk

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PATH:= $(call my-dir)</pre>

2

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

3

<pre class="CodeMirror-line">​</pre>

4

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional</pre>

5

<pre class="CodeMirror-line">​</pre>

6

<pre class="CodeMirror-line">LOCAL_STATIC_JAVA_LIBRARIES := testlib</pre>

7

<pre class="CodeMirror-line">​</pre>

8

<pre class="CodeMirror-line"># Only compile source java files in this apk.</pre>

9

<pre class="CodeMirror-line">LOCAL_SRC_FILES := $(call all-java-files-under, src)</pre>

10

<pre class="CodeMirror-line">​</pre>

11

<pre class="CodeMirror-line">LOCAL_PACKAGE_NAME := SayhelloFromJar</pre>

12

<pre class="CodeMirror-line">LOCAL_PRIVILEGED_MODULE := true</pre>

13

<pre class="CodeMirror-line">​</pre>

14

<pre class="CodeMirror-line">#LOCAL_SDK_VERSION := current</pre>

15

<pre class="CodeMirror-line">​</pre>

16

<pre class="CodeMirror-line">include $(BUILD_PACKAGE)</pre></wiz_code_mirror>

那么,jar的mk文件怎么写呢?其实就是挪到了两个不同的make文件中了而已。

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

2

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=testlib:/libs/testlib.jar</pre>

3

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional</pre>

4

<pre class="CodeMirror-line">#实际上就是一个copy的过程,把jar包放到了out/...obj/下</pre>

5

<pre class="CodeMirror-line">include $(BUILD_MULTI_PREBUILT)</pre></wiz_code_mirror>


错误提示:

错误1:
如果有引用第三方jar包但是没有进行以上配置,则会出现类似如下错误:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">make: *** No rule to make target 'out/target/common/obj/JAVA_LIBRARIES/BaiduLBS_Android_intermediates/javalib.jar', needed by 'out/target/common/obj/APPS/Voice_intermediates/classes-full-debug.jar'. Stop.</pre>

2

<pre class="CodeMirror-line">make: *** Waiting for unfinished jobs....</pre></wiz_code_mirror>

错误2:
还有一点需要注意,:=和+=是不一样的:=是赋值操作,也就是如果你要引用多个jar包,就不能都用:=了,有两种方式:
第一种就是不同的jar的定义用 \ 隔开,比如这样:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := android-support-v4:/libs/android-support-v4.jar </pre>

2

<pre class="CodeMirror-line">BaiduLBS_Android:/libs/BaiduLBS_Android.jar </pre>

3

<pre class="CodeMirror-line">bugly_crash_release:/libs/bugly_crash_release.jar</pre></wiz_code_mirror>

或者这样写:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := android-support-v4:/libs/android-support-v4.jar</pre>

2

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += BaiduLBS_Android:/libs/BaiduLBS_Android.jar</pre>

3

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += bugly_crash_release:/libs/bugly_crash_release.jar</pre></wiz_code_mirror>

虽然是很细微的区别,但是很容易在这里踩坑,切记切记;

添加自己的源码包依赖

不知道怎么形容,所以就暂时称之为源码包依赖把,所谓源码包依赖,就是还没有打包成jar包的java源码,也就是源代码,Android系统远吗中是没有jar包的,都是使用源码的方式,这充分体现了Android系统开源的本质。这个源码包就是可以用来编译成jar文件的源码文件夹。我们需要把这个源码文件夹在系统源码中通过编写make文件的方式编译成所需要的jar,从而被apk使用。

假如我们要使用的源码的模块名定义为testlib,那么Android.mk文件可以这样写:
jar的Android.mk

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PATH := $(call my-dir)</pre>

2

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

3

<pre class="CodeMirror-line">#jar标识,被其他模块引用的时候就是直接饮用这个标识</pre>

4

<pre class="CodeMirror-line">LOCAL_MODULE := testlib</pre>

5

<pre class="CodeMirror-line">#可以写可以不写,这里写8就是说这个代码班一起的版本号为8</pre>

6

<pre class="CodeMirror-line">LOCAL_SDK_VERSION := 8</pre>

7

<pre class="CodeMirror-line">#源码所在目录,这里表示包含了所有当前目录下所有的java文件</pre>

8

<pre class="CodeMirror-line">LOCAL_SRC_FILES := $(call all-java-files-under, src/java)</pre>

9

<pre class="CodeMirror-line">#把这个jar包编译成java静态代码库的方式</pre>

10

<pre class="CodeMirror-line">include $(BUILD_STATIC_JAVA_LIBRARY)</pre>

11

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

含有jni本地代码(不包含So文件)

对于含有jni的项目但是不含有so文件或者.a或者其他目标文件,则需要修改上述新建的Android.mk,如下(也可以参照源码树中的SimpleJNI工程,位于development/samples/SimpleJNI):

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> TOP_LOCAL_PATH:= $(call my-dir)</pre>

2

<pre class="CodeMirror-line"> # 定义LOCAL_PATH,这两句的意思相当于LOCAL_PATH:= $(call my-dir)</pre>

3

<pre class="CodeMirror-line"> LOCAL_PATH:= $(TOP_LOCAL_PATH)</pre>

4

<pre class="CodeMirror-line"> #清理缓存变量</pre>

5

<pre class="CodeMirror-line"> include $(CLEAR_VARS)</pre>

6

<pre class="CodeMirror-line"> #表示目标模式,sample表示是示例代码,我们根据实际需要修改</pre>

7

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS := samples</pre>

8

<pre class="CodeMirror-line"> #编译java文件</pre>

9

<pre class="CodeMirror-line"> LOCAL_SRC_FILES := $(call all-subdir-java-files)</pre>

10

<pre class="CodeMirror-line"> #模块名称</pre>

11

<pre class="CodeMirror-line"> LOCAL_PACKAGE_NAME := SimpleJNI</pre>

12

<pre class="CodeMirror-line"> #编译成的so文件名称,so文件会安装到输出目录的system/lib下</pre>

13

<pre class="CodeMirror-line"> LOCAL_JNI_SHARED_LIBRARIES := libmynative</pre>

14

<pre class="CodeMirror-line"> #去掉代码混淆,默认是混淆的</pre>

15

<pre class="CodeMirror-line"> LOCAL_PROGUARD_ENABLED := disabled</pre>

16

<pre class="CodeMirror-line"> #使用当前sdk版本编译</pre>

17

<pre class="CodeMirror-line"> LOCAL_SDK_VERSION := current</pre>

18

<pre class="CodeMirror-line"> #编译目标apk</pre>

19

<pre class="CodeMirror-line"> include $(BUILD_PACKAGE)</pre>

20

<pre class="CodeMirror-line">​</pre>

21

<pre class="CodeMirror-line"> # ============================================================</pre>

22

<pre class="CodeMirror-line"> # 如果该目录下还有其他的mk文件也进行编译,因为这个项目里面jni相关的文件放在了jni目录下编译</pre>

23

<pre class="CodeMirror-line"> # 推荐大家熟练以后也这么做,看起来好看很多,当然你也可以把mk文件合并为一个。</pre>

24

<pre class="CodeMirror-line"> include $(call all-makefiles-under,$(LOCAL_PATH))</pre>

25

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

jni目录下的Android.mk如下(假设jni目录下有inc和src目录,inc下):

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> LOCAL_PATH := $(call my-dir)</pre>

2

<pre class="CodeMirror-line"> include (CLEAR_VARS)</pre>

3

<pre class="CodeMirror-line"> # 目标模式,可以不写</pre>

4

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS := samples</pre>

5

<pre class="CodeMirror-line"> # 编译成的莫表模块名称,引用的时候就是引用这个</pre>

6

<pre class="CodeMirror-line"> LOCAL_MODULE := libmynative</pre>

7

<pre class="CodeMirror-line"> # 原文件所在路径,这里只有一个c文件</pre>

8

<pre class="CodeMirror-line"> LOCAL_SRC_FILES := src/mynative.c</pre>

9

<pre class="CodeMirror-line"> # jni里面链接到的共享库,没有可以不写</pre>

10

<pre class="CodeMirror-line"> LOCAL_SHARED_LIBRARIES := libutils liblog</pre>

11

<pre class="CodeMirror-line"> # 引用的静态哭,没有可以不写或者像下面这样</pre>

12

<pre class="CodeMirror-line"> LOCAL_STATIC_LIBRARIES :=</pre>

13

<pre class="CodeMirror-line"> # jni头文件通过这种方式包含进来</pre>

14

<pre class="CodeMirror-line"> LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)</pre>

15

<pre class="CodeMirror-line"> # 同上</pre>

16

<pre class="CodeMirror-line"> LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc</pre>

17

<pre class="CodeMirror-line"> # 编译共享库,生成的so文件呗安装到输出目录的system/lib下</pre>

18

<pre class="CodeMirror-line"> include $(BUILD_SHARED_LIBRARY)</pre>

19

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

注意:所有jni相关的代码产生的目标文件和的使用和jar包不一样,因为它是在system目录下,因此如果不把so文件刷到设备,设备是没有这个本地库的。如果没有则需要PRODUCT_PACKAGES添加

含有so文件不含C文件

这种情况在引用第三方sdk的时候经常用到,比如百度地图高德地图,比如腾讯bugly,为了叙述简单,这里只提添加so文件,后面会有一个整合的例子,大家明白就好。这里我就把自己的项目中使用到的代码贴出来了。
这个里面涉及到三处需要注意,一个是目标apk的Android.mk文件的修改,这里是引用so文件的主体工程,引用的方式则是通过指定LOCAL_SHARED_LIBRARIES,第二处是so文件对应的Android.mk文件的编写,第三处是PRODUCT_PACKAGES添加so的标识名。

(1) 在主apk工程的mk文件里面加上 LOCAL_SHARED_LIBRARIES,多个库引用之间空格隔开。假设我们引用的so库文件有三个,分别为libBaiduMapBase libBaiduMapSDK libBaiduLocation,位置则是在AppPath/jni/下。

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> LOCAL_SHARED_LIBRARIES := libBaiduMapBase libBaiduMapSDK libBaiduLocation</pre></wiz_code_mirror>

如果你的百度地图的库放在你的工程目录下,需要你编译制定的mk文件则可以在主apk工程的mk文件后面加上:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> #假设so对应的mk文件在jni目录下</pre>

2

<pre class="CodeMirror-line"> include $(LOCAL_PATH)/jni/Android.mk</pre>

3

<pre class="CodeMirror-line"> #或者</pre>

4

<pre class="CodeMirror-line"> include $(call all-makefiles-under,$(LOCAL_PATH))</pre>

5

<pre class="CodeMirror-line"> #其中,这个调用当前目录所有的make文件则会自动搜索不需要指定目录</pre></wiz_code_mirror>

(2) So文件对应的Android.mk文件

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> LOCAL_PATH := $(call my-dir)</pre>

2

<pre class="CodeMirror-line">​</pre>

3

<pre class="CodeMirror-line"> ##################### add libBaiduMapSDK_map_v4_5_0 library #######################</pre>

4

<pre class="CodeMirror-line"> include $(CLEAR_VARS)</pre>

5

<pre class="CodeMirror-line"> LOCAL_MODULE:=libBaiduMapSDK_map_v4_5_0</pre>

6

<pre class="CodeMirror-line"> LOCAL_SRC_FILES:=libBaiduMapSDK_map_v4_5_0.so</pre>

7

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS:=optional</pre>

8

<pre class="CodeMirror-line"> LOCAL_MODULE_CLASS:=SHARED_LIBRARIES</pre>

9

<pre class="CodeMirror-line"> LOCAL_MODULE_SUFFIX:=.so</pre>

10

<pre class="CodeMirror-line"> include $(BUILD_PREBUILT)</pre>

11

<pre class="CodeMirror-line">​</pre>

12

<pre class="CodeMirror-line"> ##################### add liblocSDK7a library #######################</pre>

13

<pre class="CodeMirror-line"> include $(CLEAR_VARS)</pre>

14

<pre class="CodeMirror-line"> LOCAL_MODULE:=liblocSDK7a</pre>

15

<pre class="CodeMirror-line"> LOCAL_SRC_FILES:=liblocSDK7a.so</pre>

16

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS:=optional</pre>

17

<pre class="CodeMirror-line"> LOCAL_MODULE_CLASS:=SHARED_LIBRARIES</pre>

18

<pre class="CodeMirror-line"> LOCAL_MODULE_SUFFIX:=.so</pre>

19

<pre class="CodeMirror-line"> include $(BUILD_PREBUILT)</pre>

20

<pre class="CodeMirror-line">​</pre>

21

<pre class="CodeMirror-line"> ##################### libBaiduMapSDK_base_v4_5_0 #######################</pre>

22

<pre class="CodeMirror-line"> include $(CLEAR_VARS)</pre>

23

<pre class="CodeMirror-line"> LOCAL_MODULE:=libBaiduMapSDK_base_v4_5_0</pre>

24

<pre class="CodeMirror-line"> LOCAL_SRC_FILES:=libBaiduMapSDK_base_v4_5_0.so</pre>

25

<pre class="CodeMirror-line"> LOCAL_MODULE_TAGS:=optional</pre>

26

<pre class="CodeMirror-line"> LOCAL_MODULE_CLASS:=SHARED_LIBRARIES</pre>

27

<pre class="CodeMirror-line"> LOCAL_MODULE_SUFFIX:=.so</pre>

28

<pre class="CodeMirror-line"> include $(BUILD_PREBUILT)</pre>

29

<pre class="CodeMirror-line">​</pre></wiz_code_mirror>

注意,不建议你修改LOCAL_MODULE:=libBaiduMapSDK_base_v4_5_0
因为生成so文件的时候就是按照这个来生成的,可能java调用jni的时候需要对应上so文件名,这个我没验证,但是为了保险起见建议不要修改,不过也说不定,因为这个LOCAL_MODULE只是用来在build系统中标识的,改了也应该没关系,有兴趣的朋友可以试试。


网上还有一种写法,这里也写出来供大家参考,实现的效果是一样的。

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line"> ##################### add third part library #######################</pre>

2

<pre class="CodeMirror-line"> #include $(CLEAR_VARS)</pre>

3

<pre class="CodeMirror-line"> #LOCAL_MODULE := libBaiduMapSDK_base_v4_5_0</pre>

4

<pre class="CodeMirror-line"> #LOCAL_SRC_FILES := libBaiduMapSDK_base_v4_5_0.so</pre>

5

<pre class="CodeMirror-line"> #include $(PREBUILT_SHARED_LIBRARY)</pre></wiz_code_mirror>

既有so又有第三方jar

这种场景也很常见,很多厂商的sdk不仅带有jar,jar里面还有本地代码的引用,有些是为了加密防止核心代码泄露,有些使用到了自定义的底层库,不管怎么样,我们来搞一搞;
因为前面有介绍单独关于so文件的移植和第三方jar的移植,这个例子只是对这两个做一个合并,其实合并起来也是非常简单,在哪个里面引用到了就在哪个里面添加引用的代码,可能有些朋友被前面的东西搞晕了,因此我还是写出来,帮助大家梳理一下;

这是一个既有so引用又有jar引用的apk的Android.mk,以百度地图为例

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">LOCAL_PATH:= $(call my-dir) </pre>

2

<pre class="CodeMirror-line">include $(CLEAR_VARS) </pre>

3

<pre class="CodeMirror-line">​</pre>

4

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional </pre>

5

<pre class="CodeMirror-line">​</pre>

6

<pre class="CodeMirror-line">LOCAL_STATIC_JAVA_LIBRARIES := libbaidumapapi </pre>

7

<pre class="CodeMirror-line">​</pre>

8

<pre class="CodeMirror-line">LOCAL_SRC_FILES := $(call all-subdir-java-files) </pre>

9

<pre class="CodeMirror-line">​</pre>

10

<pre class="CodeMirror-line">LOCAL_PACKAGE_NAME := MyMaps </pre>

11

<pre class="CodeMirror-line">​</pre>

12

<pre class="CodeMirror-line">include $(BUILD_PACKAGE) </pre>

13

<pre class="CodeMirror-line">​</pre>

14

<pre class="CodeMirror-line">###########有人说可以这样写,我没试过,有兴趣可以试试############# </pre>

15

<pre class="CodeMirror-line">#include $(CLEAR_VARS) </pre>

16

<pre class="CodeMirror-line">#LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs/baidumapapi.jar </pre>

17

<pre class="CodeMirror-line">#LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so </pre>

18

<pre class="CodeMirror-line">#LOCAL_MODULE_TAGS := optional </pre>

19

<pre class="CodeMirror-line">#include $(BUILD_MULTI_PREBUILT) </pre>

20

<pre class="CodeMirror-line">###########################################################</pre>

21

<pre class="CodeMirror-line">​</pre>

22

<pre class="CodeMirror-line">###########我自己是这么写的###################################</pre>

23

<pre class="CodeMirror-line">#添加so文件依赖(So的写法参照《含有so文件不含C文件》)</pre>

24

<pre class="CodeMirror-line">LOCAL_SHARED_LIBRARIES := libBMapApiEngine_v1_3_1</pre>

25

<pre class="CodeMirror-line">include $(CLEAR_VARS)</pre>

26

<pre class="CodeMirror-line">LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs:/libs/baidumapapi.jar</pre>

27

<pre class="CodeMirror-line">LOCAL_MODULE_TAGS := optional</pre>

28

<pre class="CodeMirror-line">include $(BUILD_MULTI_PREBUILT)</pre>

29

<pre class="CodeMirror-line">​</pre>

30

<pre class="CodeMirror-line">######## Use the following include to make our testapk. </pre>

31

<pre class="CodeMirror-line">include $(callall-makefiles-under,$(LOCAL_PATH)) </pre></wiz_code_mirror>

含有So文件且含有jni文件

这里我就不写了,因为我自己没有这样实现,但是我相信这个思路是正确的。Android在make的时候,根据mk文件来编译的,mk中可以制定编译成的共享库或者java库或者apk或者其他的,但是不管怎么样,没有mk生成的目标文件都是有指定module名称的,要引用这个module或者库,只需要指定引用的名称和方式即可,所以,建议给具体的库单独写一个mk文件以方便其他应用使用。

注意和总结

前面提醒过的一天我这里在强调一下,因为很多朋友看文章的时候不仔细,常常漏掉在core.mk中配置apk或者so库,从而导致刷如手机后没有这个应用或者应用打开后崩溃说没有满足的库或者本地方法。

因此不仅仅是编写项目的mk文件就行了,一定要在/build/target/product/core.mk下的PRODUCT_PACKAGES添加自己的模块,或者在devices下添加(表示只在编译指定target的时候生效,我这里是6735的代码,因此目录是device/lentek/lentk6735_35gc_l1/device.mk)

一定不要忘记把PRODUCT_PACKAGES加进去。

注意2
如果只是在源码上局部编译,且只需要使用编译成功的apk(而不是把整个系统重新刷写),则需要注意的是,apk中有使用so文件,则需要把这个so文件推送到手机的对应目录中:

<wiz_code_mirror><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="padding:0px; width:1000px; height:1em;" tabindex="0"></textarea>

1

<pre class="CodeMirror-line">#进入到生成so文件的目录(所有生成的so都在这里,而不是在apk中,并安装到system.img)</pre>

2

<pre class="CodeMirror-line">cd <source_root>\out\target\product<productname>\system\lib</pre>

3

<pre class="CodeMirror-line">#如果手机没有root</pre>

4

<pre class="CodeMirror-line">adb root</pre>

5

<pre class="CodeMirror-line">#不执行这一步则push会被拒绝</pre>

6

<pre class="CodeMirror-line">adb remount</pre>

7

<pre class="CodeMirror-line">#把文件推送到设备</pre>

8

<pre class="CodeMirror-line">adb push xxx.so /system/lib/xxx.so</pre>

9

<pre class="CodeMirror-line">#可能需要重启,非系统应用则不需要</pre>

10

<pre class="CodeMirror-line">adb reboot</pre></wiz_code_mirror>

  1. 注意和总结
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容