导航:首页 > 源码编译 > mk编译成共享库

mk编译成共享库

发布时间:2025-05-10 16:50:14

A. android.mk解析与使用看这篇就够了

背景图来源:

争取每一篇文章都是精华,每一篇文章都能做到后期维护,本篇内容也可通过本人唯一 〖阿里云地址 (点我跳转)〗 查看

写在前面:

官网对Android.mk的介绍 (点我跳转);注意新的源码中很多app已经切换到了Android.bp,不过目前Android.mk还是兼容的

一、Android.mk理解:

Android.mk是一个向Android NDK构建系统描述NDK项目的GNU makefile片段(可以理解为Android工程管理文件的说明书)。将源文件分组为模块或编译生成以下几种:

1、库是写好的现有的,成熟的,可以复用的代码。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)

2、静态库和动态库的理解(可选):

静态库在编译时会将依赖的所有代码合并到一个可执行文件中,而动态库在运行时才加载依赖的代码,通常用于模块化设计和代码复用。

二、Android.mk详细解析:

1、LOCAL_PATH := $(call my-dir):

定义当前模块的路径

2、include $(CLEAR_VARS):

清理变量,为新模块的配置做准备

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

指定需要编译的Java文件

4、LOCAL_MODULE := Bgwan:

定义模块名称

5、LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT):

设置模块生成的目标路径

6、include $(BUILD_SHARED_LIBRARY):

指示构建系统生成共享库

7、LOCAL_MODULE_TAGS := optional:

设置编译标签

8、LOCAL_CERTIFICATE := platform:

设置签名属性

9、LOCAL_STATIC_JAVA_LIBRARIES := jar1 jar2:

引用静态jar库

10、LOCAL_STATIC_JAVA_AAR_LIBRARIES := aar_alias:

引用静态aar库

11、需要进行预编译的库:

定义静态库别名和路径

12、include $(BUILD_MULTI_PREBUILT):

预编译库

13、GNU Make系统变量:

收集其他系统变量

三、Android.mk案例实战:

1、项目目录结构(新增内容):

便于理解内容,新增目录结构示例

2、引用aar包:

在源码环境中,通过Android.mk将aar导入APK

3、解决运行时找不到so的问题:

源码下编译的APK不含so文件,解决方案

4、编译静态库、动态库和多个共享库:

5、使用/引用静态库和动态库:

6、使用/引用第三方文件:

7、共享通用模块:

8、拷贝文件到指定目录:

9、编译apk和生成目录:

10、编译jar包:

11、源码环境下引用jar包:

12、使用预编译库:

13、编译独立可执行文件:

14、apk生成目录:

15、编译特定目录下的apk:

16、引用jar包:

17、预编译jar包:

18、Android.mk中的判断语句:

19、开启混淆:

20、指定资源目录:

21、引用so库:

22、Android.mk文件配置签名:

四、总结:重要的注意事项:

请根据实际项目使用和理解

1、Android.mk可以引用Android.bp中的模块,反之Android.bp不能引用Android.mk中的模块。

2、Android.bp模块不支持../../去寻找上层路径的文件。

3、本地库依赖于其他so时,需注意加载顺序。

4、Android 6.0版本之前,加载本地库前需先加载依赖的so。

5、Android 6.0版本后,预编译的动态库不再推荐使用。

致谢(引用和推荐)(可选):

感谢各位前辈的开源精神和分享,以下文章提供参考。

B. 怎么样将自己开发的Android应用程序编译到系统Image中

1. 搭建编译环境
编译环境: Ubuntu 10.10
Android版本:Android 2.2

编译过程中可能需要在Ubuntu上安装必要的一些软件,我安装过的包含如下软件,不同的系统可能会有差别:
jdk6(Android官方建议装jdk5,但是我在编译时会遇到Java override问题,改用6没有任何问题), bison, lib64z1-dev, libasound2-dev, flex, gperf, libncurses5-dev

2. 应用程序存放目录
SimpleJNI是采用Android NDK和Java编写的程序,包含apk和so库文件,它的源代码在source tree的development/samples/目录下。
实际上package在编译时所放的目录并没有明确限定,编译后apk和so存放的位置是根据目录下Android.mk所指定的编译类型所决定的,例如:
SimpleJNI根目录下的Android.mk中有一行include $(BUILD_PACKAGE),表示将该目录下的模块编译成package,即apk文件,默认存放的位置为/system/app。
SimpleJNI/jni目录下的Android.mk中有一行为include $(BUILD_SHARED_LIBRARY),表示将该目录下的native.cpp编译为共享库文件,即so文件,默认存放的位置为/system/lib

因此,如果我们想要将自己编写的程序编译至image中,只需要将Eclipse下完成的整个工程到source tree下的某个目录即可,我一般习惯放到packages/apps下。

3. 添加Android.mk
完成了上一步,可以知道,Android.mk在编译中起着至关重要的作用,这其实就是Android编译环境中的make file。为了完成我们的工作,需要在源代码中添加Android.mk。添加自己的Android.mk可以仿照SimpleJNI中的Android.mk,稍微修改即可。我们首先看看SimpleJNI目录下的两个Android.mk的内容:
根目录下的Android.mk

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

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

LOCAL_PACKAGE_NAME := SimpleJNI

LOCAL_JNI_SHARED_LIBRARIES := libsimplejni

LOCAL_PROGUARD_ENABLED := disabled

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

根目录下的Android.mk决定了整个工程编译的配置,其中,

LOCAL_PATH 定义了当前的目录

LOCAL_MUDULE_TAGS 定义了当前模块的类型,编译器在编译时会根据类型的不同有些差别,有些tags的mole甚至不会被编译至系统中。LOCAL_MUDULE_TAGS主要有如下几种:user debug eng tests optional samples shell_ash shell_mksh。optional表示在所有版本的编译条件下都被编译至image中,剩下的表示在该版本中才会被编译只image中,如user表示在user版本下才会被编译至image中。
对于包含LOCAL_PACKAGE_NAME的mk文件,该项默认为optinal,具体可以参看build/core/package.mk。SimpleJNI中定义为samples的具体作用我也不太清楚,为了保险起见,我自己的apk一般定义为optional。

LOCAL_SRC_FILES 定义了编译apk所需要的java代码的目录

LOCAL_PACKAGE_NAME 这里需要改成自己的package的名字

LOCAL_JNI_SHARED_LIBRARIES 定义了要包含的so库文件的名字,如果你的程序没有采用JNI,这行不需要。

LOCAL_PROGUARD_ENABLED 定义了Java开发中的ProGuard压缩方法,主要用来分析压缩程序的,在我自己的应用中我没有加这行。

include $(BUILD_PACKAGE) 这行是build的关键,表示当前java代码build成apk

include $(call all-makefiles-under,$(LOCAL_PATH)) 表示需要build该目录下的子目录的文件,这样编译系统就会在当前目录下的子目录寻找Android.mk来编译so等其它程序。

根据上述所写,创建我自己的Android.mk如下:

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

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

LOCAL_PACKAGE_NAME := TestJniApp

LOCAL_JNI_SHARED_LIBRARIES := libtestjniapp

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))
看起来很简单吧,基本不需要改动即可。

Jni目录下的Android.mk

由于我们的TestJniApp是用JNI完成的,包含C源代码,因此也需要一个jni目录下的Android.mk。同样首先看看SimpleJNI中jni目录下的Android.mk的内容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

# This is the target being built.
LOCAL_MODULE:= libsimplejni

# All of the source files that we will compile.
LOCAL_SRC_FILES:= /
native.cpp

# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := /
libutils

# No static libraries.
LOCAL_STATIC_LIBRARIES :=

# Also need the JNI headers.
LOCAL_C_INCLUDES += /
$(JNI_H_INCLUDE)

# No special compiler flags.
LOCAL_CFLAGS +=

# Don't prelink this library. For more efficient code, you may want
# to add this library to the prelink map and set this to true. However,
# it's difficult to do this for applications that are not supplied as
# part of a system image.

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULE 当前模块的名字,即编译后的so文件的名字

LOCAL_SRC_FILES 所要编译的文件

LOCAL_SHARED_LIBRARIES, LOCAL_STATIC_LIBRARIES 该模块要链接的动态库和静态库。

LOCAL_C_INCLUDES 要包含的头文件

LOCAL_CFLAGS C语言编译选项

LOCAL_PRELINK_MODULE 定义是否使用prelink工具,它用事先链接代替运行时链接的方法来加速共享库的加载,不仅可以加快起动速度,还可以减少部分内存开销。

经过修改后,我自己的TestJniApp中jni目录下的Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libtestjniapp
LOCAL_SRC_FILES := com_test_app_Jni.c
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

这里有一点需要注意,如果要将so文件编译入image,必须要修改LOCAL_MODULE_TAGS,将原有的值samples修改为user,或者可以直接删掉 。删掉是因为对于包含LOCAL_MODULE的mk文件,如果没有指定LOCAL_MODULE_TAGS,该项默认为user,而只有定义为user的情况下,才会将so文件编译入image,具体定义可以参看build/core/base_rule.mk。

4. 修改/bulid/target/proct/generic.mk 把工程编译到系统中
至此,还有最后一部工作。为了将工程编译进入image,还需要在/bulid/target/proct/generic.mk文件中将package name添加进去

PRODUCT_PACKAGES := /
AccountAndSyncSettings /
CarHome /
DeskClock /
……
SyncProvider /
TestJniApp

完成上面这些步骤后,在source tree根目录下编译image就可以了。

C. android.mk是在什么情况下生成的

当你需要使用JNI的时候,你需要创建一个native工程。Android.mk就是一个makefile配置文件,帮你把C/C++的代码编译成动态库so的。

创建的方式有两种:

在工程根目录里手动创建一个目录叫jni,在里面新建一个Android.mk,然后创建c,cpp文件,把他们配置到Android.mk里。

右键工程,选择Android Tools->Add Native Support自动生成。



(3)mk编译成共享库扩展阅读:

创建Android库

Android 库在结构上与 Android 应用模块相同。可以提供构建应用所需的一切内容,包括源代码、资源文件和 Android 清单。

不过,Android 库将编译到可以用作 Android 应用模块依赖项的 Android 归档 (AAR:Android Archive Resource) 文件,而不是在设备上运行的 APK。

与 JAR 文件不同,AAR 文件可以包含 Android 资源和一个清单文件,这样,除了 Java 类与方法外,还可以捆绑布局和可绘制对象等共享资源。

库模块在以下情况下非常有用:

构建使用某些相同组件(例如 Activity、服务或 UI 布局)的多个应用。

构建存在多个 APK 变体(例如免费版本和付费版本)的应用并且需要在两种版本中使用相同的核心组件。

D. 编译找不到prebuilt_shared_library的库

编译找不到prebuilt_shared_library的库解决方法。必须将自己使用的每个预编译库差和敬声明为棚庆一个独虚慎立模块。为此,执行以下步骤。
1、为模块提供名称。此名称不需要与预编译库本身的名称相同。
2、在模块的Android.mk文件中,将指向您提供的预编译库的路径分配到LOCAL_SRC_FILES。指定LOCAL_PATH变量的值的相对路径。注意:请务必选择与您的目标ABI对应的预编译库版本。要详细了解如何确保库支持ABI,请参阅为预编译库选择ABI。
3、根据您使用的是共享库(.so)还是静态库(.a),添加PREBUILT_SHARED_LIBRARY或PREBUILT_STATIC_LIBRARY。

E. android.mk文件怎么写

一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。例如,你不需要在你的Android.mk中列出头文件和依赖文件。NDK编译系统将会为你自动处理这些问题。这也意味着,在升级NDK后,你应该得到新的toolchain/platform支持,而且不需要改变你的Android.mk文件。
先看一个简单的例子:一个简单的"hello world",比如下面的文件:
sources/helloworld/helloworld.c
sources/helloworld/Android.mk
相应的Android.mk文件会象下面这样:
---------- cut here ------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE
:= helloworld
LOCAL_SRC_FILES := helloworld.c
include $(BUILD_SHARED_LIBRARY)
---------- cut here ------------------
我们来解释一下这几行代码:
LOCAL_PATH := $(call my-dir)
一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
include $( CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。
LOCAL_MODULE := helloworld
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。
LOCAL_SRC_FILES := helloworld.c
LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

在Android中增加本地程序或者库,这些程序和库与其所载路径没有任何关系,只和它们的Android.mk文件有关系。Android.mk和普通的Makefile有所不同,它具有统一的写法,主要包含一些系统公共的宏。
在一个Android.mk中可以生成多个可执行程序、动态库和静态库。
1,编译应用程序的模板:
#Test Exe
LOCAL_PATH := $(call my-dir)
#include $(CLEAR_VARS)
LOCAL_SRC_FILES:= main.c
LOCAL_MODULE:= test_exe
#LOCAL_C_INCLUDES :=
#LOCAL_STATIC_LIBRARIES :=
#LOCAL_SHARED_LIBRARIES :=
include $(BUILD_EXECUTABLE)
(菜鸟级别解释::=是赋值的意思,$是引用某变量的值)LOCAL_SRC_FILES中加入源文件路径,LOCAL_C_INCLUDES 中加入所需要包含的头文件路径,LOCAL_STATIC_LIBRARIES加入所需要链接的静态库(*.a)的名称,LOCAL_SHARED_LIBRARIES中加入所需要链接的动态库(*.so)的名称,LOCAL_MODULE表示模块最终的名称,BUILD_EXECUTABLE表示以一个可执行程序的方式进行编译。
2,编译静态库的模板:
#Test Static Lib
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
helloworld.c
LOCAL_MODULE:= libtest_static
#LOCAL_C_INCLUDES :=
#LOCAL_STATIC_LIBRARIES :=
#LOCAL_SHARED_LIBRARIES :=
include $(BUILD_STATIC_LIBRARY)
一般的和上面相似,BUILD_STATIC_LIBRARY表示编译一个静态库。
3,编译动态库的模板:
#Test Shared Lib
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
helloworld.c
LOCAL_MODULE:= libtest_shared
TARGET_PRELINK_MODULES := false
#LOCAL_C_INCLUDES :=
#LOCAL_STATIC_LIBRARIES :=
#LOCAL_SHARED_LIBRARIES :=
include $(BUILD_SHARED_LIBRARY)
一般的和上面相似,BUILD_SHARED_LIBRARY表示编译一个静态库。
以上三者的生成结果分别在如下,generic依具体target会变:
out/target/proct/generic/obj/EXECUTABLE
out/target/proct/generic/obj/STATIC_LIBRARY
out/target/proct/generic/obj/SHARED_LIBRARY
每个模块的目标文件夹分别为:
可执行程序:XXX_intermediates
静态库: XXX_static_intermediates
动态库: XXX_shared_intermediates
另外,在Android.mk文件中,还可以指定最后的目标安装路径,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的宏进行选择:
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:表示system文件系统。
TARGET_OUT_DATA:表示data文件系统。
用法如:
CAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

F. Android 怎么自定义共享库

在Android源码根目录下的vendor目录下,有一个专门存放各种供应商代码的sample目录。其中的PlatformLibrary目录展示了如何编写自定义共享库。为了让大家更好地理解如何封装Java共享库,我们可以通过PlatformLibrary目录来学习。

PlatformLibrary目录下的Android.mk文件用于定义构建规则,它默认继承Android的make框架。在该目录下,我们还需要编写com.example.android.platform_library.xml文件,该文件用于模块注册,需要将其放置到/system/etc/permissions目录下。

接下来,我们可以在java目录下编写Java源代码,如PlatformLibrary.java。然后编写Android.mk文件来定义如何编译该模块。内容如下:

# 获得当前目录,清空环境变量
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 源码所在目录,all-subdir-java-files表示所有了目录中的Java文件。
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# 该模块是可选的。
LOCAL_MODULE_TAGS := optional
# Java模块名称
LOCAL_MODULE:= com.example.android.platform_library
# 编译为Java库。最近以jar的形式而不是apk的形式存在。
include $(BUILD_JAVA_LIBRARY)
# 构建该库的API文档
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= platform_library
# 文档对应的库
LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library
# 库的类型
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true
# 编译为Java API。
include $(BUILD_DROIDDOC)

完成上述步骤后,我们需要编写com.example.android.platform_library.xml文件,内容如下:

现在我们已经基本完成了Java库的封装,接下来需要对框架中的其他文件进行配置。我们可以在sample/frameworks/Android.mk文件中添加如下内容:

# 包含子目录中的所有make文件
include $(call all-subdir-makefiles)

在sdk_addon目录下编写manifest.ini文件,内容如下:

# 该模块的名称、供应商及描述
name=Sample Add-On
vendor=Android Open Source Project
description=sample add-on
# 构建该模块的Android平台代号
api=3
# 模块的版本号。必须为整数。
revision=1
# 该模块中包括的共享库列表
libraries=com.example.android.platform_library
# 对每个库的详细定义,格式如下:
# =.jar;
# : 通过前面libraies定义的库的名称。
# .jar:包含库API的jar文件。该文件放在libs/add-on下面。
com.example.android.platform_library=platform_library.jar;Sample optional plaform library

至此,我们已经完成了Java库的封装,接下来我们再来看如何通过JNI的方式对C代码进行封装。

在sample/frameworks/PlatformLibrary目录下添加一个文件夹,用于放置JNI本地代码。然后在jni目录下编写PlatformLibrary.cpp文件,实现PlatformLibrary.java中规定本地调用的具体实现。

在jni目录下编写Android.mk文件,定义本地库的名字、依赖、编译选项及编译方式。

最后,修改sdk_addon/sample_addon.mk文件,在PRODUCT_PACKAGES中添加该JNI本地库。

至此,我们已经完成了JNI库的添加。接下来我们再看看如何添加原生应用程序。添加原生应用程序就很简单了,只需要按照Android应用开发的基本方法,写好一个应用即可。

在应用根目录中添加一个Android.mk文件,内容如下:

# 获得当前目录,清空环境变量
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 目标名称
LOCAL_MODULE_TAGS := user
# 目标名称
LOCAL_PACKAGE_NAME := PlatformLibraryClient
# 只编译这个apk包中的java文件
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# 使用当前版本的SDK
LOCAL_SDK_VERSION := current
# 依赖使用刚才编写的扩展
LOCAL_JAVA_LIBRARIES := com.example.android.platform_library
include $(BUILD_PACKAGE)

在AndroidManifest.xml中添加一句:

然后修改sdk_addon/sample_addon.mk文件,在PRODUCT_PACKAGES中添加该JNI本地库。

至此,我们已经完成了JNI库的添加。

G. 关于android NDK开发中application.mk文件的疑惑

介绍:
Android SDK是一个允许Android应用开发人员使用C或C++源文件编译并嵌入到本机源代码中的应用程序包的一组工具。
重要说明:
Android NDK只能用于android 1.5以上版本
1.Android NDK的目的:
Android虚拟机允许你的应用程序源代码通过JNI调用在本地实现的源代码,简单的说,这就意味着:
你的应用程序将声明一个或多个用’native’关键字的方法用来指明它们是通过本地代码实现的
例如:native byte[] loadFile(String filePath)
你必须提供包含实现这些方法的共享库(就是.so),将共享库打包到你的应用程序包apk中,这些库文件必须根据标准的Unix约定来命名为 lib<something>.so,并且是需要包含一个标准的JNI的接口,例如
libFileLoader.so
你的应用程序必须明确的装载这些库文件(.so文件),比如,在程序的开始装载它,只需要简单的添加几句源代码:
java代码:
static {
System.loadLibrary(“FileLoader”);
}
注意:这里你不必再将前缀lib和后缀.so写入。
Android NDK对于Android SDK只是个组件,它可以帮你:
生成的JNI兼容的共享库可以在大于Android1.5平台的ARM CPU上运行
将生成的共享库拷贝到合适的程序工程路径的位置上,以保证它们自动的添加到你的apk包中(并且签名的)
在以后的版本中,我们将提供来帮助你的源代码通过远程gdb连接和尽可能多的源代码的信息。
而且,Android NDK还提供:
一组交叉编译链(编译器、链接器等)来生成可以在Linux,OS X和Windows(用Cygwin)运行的二进制文件
一组与由Android平台提供的稳定的本地API列表的头文件
它们在docs/STABLE-APIS.html中有说明
重要提示:
记住,在以后的更新和发布平台中,Android系统镜像中的大多数本地系统库并不是一成不变的,而是可以彻底改变,甚至删除的
一个编译系统(build system)可以允许开发者写一个非常短的编译文件(build files)去描述哪个源代码需要编译,并且怎样编译。编译系统可以解决所有的toolchain/platform/CPU/ABI细节的问题。并且,较晚的NDK版本中还添加了更多的可以不用改变开发者的编译文件的情况下的toolchains,platforms,系统接口。
2.Android NDK的缺点
NDK并不是一个可以编写通用的源代码并且可以在Android设备上运行的方法,你的应用程序还是需要使用JAVA程序,适当的处理系统事件来避免“应用程序没有反应”的对话框或者处理Android应用程序的生命周期
注意:可以适当的在源代码中写一个复杂的应用程序,用于启动/停止一个小型的“应用程序包”
强烈建议很好地理解的 JNI,因为许多操作在这种环境要求的开发人员,都采取具体的行动,不一定在常典型的本机代码。这些措施包括:
不能通过指针直接访问VM的对象。比如:你不能安全的得到一个指向String对象的16位char数组的循环遍历
需要显示引用管理本机代码时候要保持处理JNI调用之间的VM对象
NDK在Android平台仅仅提供了有限的本地API和库文件的支持的系统头文件,然而一个标准的Android系统镜像包括许多本地共享库,这些都应该被考虑在更新和发行版本的可以彻底改变的实现细节
如果Android系统库没有明确的被NDK明确的支持,然后应用程序不应该依赖于它提供的,或者打破了将来在各种设备上的无线系统更新
选定的系统库将逐渐被添加到稳定的NDK API中。
3.NDK开发实践
下面将给出一个怎样用Android NDK开发本地代码的粗略的概述
(1) 把本地代码放在$PROJECT/jni/…下,比如将hello.c放到apps/hello/jni/目录下
(2) 在你的NDK编译系统中在$PROJECT/jni/Android.mk来描述你的源代码
(3) 可选:在$PROJECT/jni/Application.mk到你的编译系统中来详细描述你的项目,尽管你开始的话不一定需要它,但是它允许你使用更多的CPU或者覆盖编译器/链接器的标记
(4) 从你的项目的目录开始通过运行”$NDK/ndk-build”来编译你的代码,或者从子目录开始
(5) 最后一步可以,万一成功,剥离共享库的应用层序需要你的应用程序的项目根目录。然后你通过通常的方法来生成最终的apk。

阅读全文

与mk编译成共享库相关的资料

热点内容
加密会议什么意思 浏览:34
ubuntu命令行联网 浏览:7
37选7中奖概率及算法 浏览:593
加密狗哪个版本好 浏览:619
cisco命令手册 浏览:501
omp算法c 浏览:128
上海浦东机场源码 浏览:885
扣扣加密了忘记密码如何打开 浏览:508
单片机中的地址 浏览:510
去抖动在单片机的作用 浏览:53
陆上赛艇app怎么报名 浏览:110
app内页面的网址怎么提取 浏览:286
安卓升级包pkg文件如何打开 浏览:77
id3算法原理 浏览:602
骑手通app怎么输入不了保单号 浏览:988
82一56的筒便算法 浏览:404
数控机床fanuc编程 浏览:607
天刀mode不是内部或外部命令 浏览:854
长城c30压缩机价格 浏览:1000
java打开图片文件 浏览:410