安卓上能够编译so吗
⑴ android 怎么把多个so文件编译成jar
一共分为2步:
1.在java中编写要调用的静态方法和需要加载的库,并生成头文件。
2.配置gradle
3.配置Android.mk文件和application.mk文件
下面一步步的走:
首先需要在Java类中声明要调用的方法,以及要加载的库,我们在包下新建一个jniUtil类,如下所示
[plain]view plain
publicclassjniUtil{
//要加载的库,生成的库格式为:lib+库名.so
static{System.loadLibrary("hello-jni");}
//要调用的本地方法,在c文件中该方法名称格式为:java_包名_类名_方法名
();
}
注意:在编译时该类中不能有汉字,包括注释,否则会出现编码GBK的不可映射字符错误。
接下来就是利用external Tools生成头文件.h,这里可参考点击打开链接
然后就会在main目录下生成Jni文件夹,并且包含.h文件。下面就是编写C文件,或者可以拷贝已经写好的C文件放置在该jni文件夹中.
2.配置gradle
我们这里不用gradle 去编译,而是只让他去加载已经生成的so库,改用android.mk 去编译(稍后配置android.mk)
在app的build.gradle 下的android 标签下添加:
[plain]view plain
sourceSets{
main{
jni.srcDirs=[]//禁止gradle自动编译,使用已经编译好的So库
jniLibs.srcDirs=['src/main/jniLibs','libs']//指向要使用的库文件//的路径,前边的是自己项目的,后边的是第三方的so
}
}
从上面可以看出,我们生成的库是放在
src/main/jniLibs
目录下面的,那么这个是如何配置呢?还是在该gradle下面配置ndk的编译脚本,注意放在android标签外面:
[plain]view plain
tasks.withType(JavaCompile){
compileTask->compileTask.dependsOnCopyToJniLibs
}
taskndkBuild(type:Exec,description:'CompileJNIsourceviaNDK'){
Propertiesproperties=newProperties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
defndkDir=properties.getProperty('ndk.dir')
commandLine"$ndkDir/ndk-build.cmd","NDK_PROJECT_PATH=$projectDir.absolutePath\build","APP_BUILD_SCRIPT=$projectDir.absolutePath\src\main\jni\Android.mk","NDK_APPLICATION_MK=$projectDir.absolutePath\src\main\jni\Application.mk"
//你自己的mk文件目录
}
在ndkbuild完成后把生成的so文件复制到jniLibs,这里和上面配置的加载so文件路径要一致哦
[plain]view plain
taskCopyToJniLibs(type:Copy,dependsOn:'ndkBuild',description:'thenativelibstojniLibs'){
fromfileTree(dir:file(buildDir.absolutePath+'/libs'),include:'**/*.so')
intofile('src/main/jniLibs')
}
新建Android.mk和application.mk,这里我把Android.mk和application.mk放在jni文件夹下了,具体可以自己修改。默认生成的SO文件会在build下面的libs中,我们拷贝出来放到src/main/jniLibs下面。
3.配置Android.mk和Application.mk
⑵ android studio开发工具编译C、c++代码生成so文件
目前android studio 还不支持 ndk开发,如下图是官网的说明:

⑶ android开发,怎么使用ndk编译成.so文件
一、首先下载android-ndk,官方网站是:http://developer.android.com/tools/sdk/ndk/index.html
目前最新的版本是android-ndk-r8e-windows-x86.zip,下载地址:
http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86.zip
下载后把压缩包解压出来,例如:D:\ndk,目录下的ndk-build.cmd就是用来编译的批处理命令。
二、编译,打开cmd命令行窗口,cd进入目录:D:\ndk\samples\hello-jni,
然后执行命令:D:\ndk\ndk-build.cmd(如果设置过环境变量则直接使用ndk-build.cmd)来编译hello-jni,如果没有错误会输出:
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
三、创建android应用程序并使用so文件
打开eclipse创建一个android应用程序HelloJni,默认的com.example.hellojni包下面有一个MainActivity.java,
在此包下添加一个HelloJni.java,
⑷ Android常见的预编译(prebuilt)
android常用的预编译方法(prebuilt)
1.framework引入静态jar包
2.编译共享jar包
3.编译so库
方法1 : 单独编译
方法2 : 轮询编译
4.预编译apk
预置apk至系统,如果apk含有so库的话,也需要提前编译到系统中,解压apk文件,将so提取出来放置某一文件夹中,通过LOCAL_PREBUILT_JNI_LIBS将so编译至system/app/package/lib/arm目录
⑸ android studio怎么生成.so文件
1、编译环境的搭建
正所谓:“工欲善其事必先利其器”嘛,所以先把改准备工具准备一下,因为是在studio下编译的,所以啊,什么studio、什么sdk、什么jdk,这些都自己去弄吧,这里说一下ndk这个编译C文件工具怎么下载安装;
下载完了之后直接是一个zip的压缩包,解压即可;
然后你会在local.properties文件中看到:
不要急,还没有完,ndk环境搭建还有最后一步,在gradle.properties的文件末尾加上android.useDeprecatedNdk=true这段代码:
好了,到此处环境就搭建完毕了。
2、java代码和C代码的编写步骤及过程
首先新建一个java类JNIUtils.java
public class JNIUtils {
static {
System.loadLibrary("huazict");
}
//java调C中的方法都需要用native声明且方法名必须和c的方法名一样
public native String getString();
}
然后如下图所示重新Make Project一下工程:
会在工程目录E:\work\MyApplication\stujni\build\intermediates\classes\debug\com\huazi\stujni\jni中看到自己编译后的class文件JNIUtils.class
其次就是生成.h文件了
在studio打开Terminal命令行工具,打开步骤是View->Tool Windows->Terminal
(或直接按Alt+F12
然后在命令行中先进入到工程的main目录下
输入命令:javah -d jni -classpath 自己编译后的class文件的绝对路径
例如:javah -d jni -classpath
E:\work\MyApplication\stujni\build\intermediates\classes\debug
com.huazi.stujni.jni.JNIUtils(注意debug后的空格)
看到上图,图中命令行中是直接进入到了工程的main目录下(在哪个目录下运行就会在哪个目录下自动生成jni文件夹),按回车之后就会在main目录下生成jni文件夹,同时生成.h文件,
这个文件.h文件不需要做任何修改,默认即可。
现在我们来写一个test的C文件huazict.c同.h文件一样放到jni文件夹下,代码如下:
#include "com_huazi_stujni_jni_JNIUtils.h"
/**
* 上边的引用标签一定是.h的文件名家后缀,方法名一定要和.h文件中的方法名称一样
*/
JNIEXPORT jstring JNICALL Java_com_huazi_stujni_jni_JNIUtils_getString
(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "这是我测试的jni");
}
最后在构建文件中的默认配置中加上:
//ndk编译生成.so文件
ndk {
moleName "huazict" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。
}
到这里,通过jni调C就完成了,现在我们来测试一下,写个TextView显示一下调用的C:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(new JNIUtils().getString());
}
}
ok,没问题,可以调用,其实也没有想象中的那么难,是吧!
三、调用编译过的.so库
上边编译完成了,有人会问:我要的是编译后的.so库,别人用的时候直接拿来用就可以了,那编译后的.so库在哪呢?
根据这个路径就可以找到指定输出的三种体系结构下的.so库文件,然后把.so文件复制出来,如下图所示的放到相应的文件夹下就ok了:
再次运行,结果还是一样的,跟上边贴的那张图的显示效果是是一样的,同样能调用到,代码我就不上传了,都在上边贴上去了,而且也上传不了,公司的所有文件都是加密的,想上传都上传不了。
到这里,整个jni的调用过程就结束了,包括调用jni需要的环境以及调用的过程,最后.so文件的导出,都在上边了,如果上边的jni调用过程有什么问题,欢迎留言,谢谢。
⑹ android中如何编译出64位so文件
如果是在Linux下编译Android源码,有可能是两个原因:
1. lunch命令有32位和64位的区别,注意选能够编译64位so的命令
2. mk文件中有LOCAL_MODULE_PATH的值比如为$(TARGET_OUT_SHARED_LIBRARIES)/hw的改为LOCAL_MODULE_RELATIVE_PATH := hw,后一种可以分别在lib和lib64下分别生成32位和64位的so文件,这个看看编译后的信息就知道了.
⑺ android 怎么编译so文件
android NDK编译多个so文件
android编译系统的makefile文件Android.mk写法如下
(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。由于一般情况下
Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:
LOCAL_PATH:=$(call my-dir)
上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。
(2)Android.mk中可以定义多个编译模块,每个编译模块都是以include $(CLEAR_VARS)开始
以include $(BUILD_XXX)结束。
include $(CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除除LOCAL_PATH以外的所有LOCAL_XXX变量,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示编译成静态库
include $(BUILD_SHARED_LIBRARY)表示编译成动态库。
include $(BUILD_EXECUTABLE)表示编译成可执行程序
(3)举例如下(frameworks/base/libs/audioflinger/Android.mk):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) 模块一
ifeq ($(AUDIO_POLICY_TEST),true)
ENABLE_AUDIO_DUMP := true
endif
LOCAL_SRC_FILES:= \
AudioHardwareGeneric.cpp \
AudioHardwareStub.cpp \
AudioHardwareInterface.cpp
ifeq ($(ENABLE_AUDIO_DUMP),true)
LOCAL_SRC_FILES += AudioDumpInterface.cpp
LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
endif
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_CFLAGS += -DGENERIC_AUDIO
endif
LOCAL_MODULE:= libaudiointerface
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_SRC_FILES += A2dpAudioInterface.cpp
LOCAL_SHARED_LIBRARIES += liba2dp
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_C_INCLUDES += $(call include-path-for, bluez)
endif
include $(BUILD_STATIC_LIBRARY) 模块一编译成静态库
include $(CLEAR_VARS) 模块二
LOCAL_SRC_FILES:= \
AudioPolicyManagerBase.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libmedia
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudiopolicybase
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_A2DP
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
include $(BUILD_STATIC_LIBRARY) 模块二编译成静态库
include $(CLEAR_VARS) 模块三
LOCAL_SRC_FILES:= \
AudioFlinger.cpp \
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioResamplerSinc.cpp.arm \
AudioResamplerCubic.cpp.arm \
AudioPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
LOCAL_CFLAGS += -DGENERIC_AUDIO
else
LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
endif
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudioflinger
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_SHARED_LIBRARIES += liba2dp
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(HOST_OS),linux)
LOCAL_LDLIBS += -lrt -lpthread
endif
endif
ifeq ($(BOARD_USE_LVMX),true)
LOCAL_CFLAGS += -DLVMX
LOCAL_C_INCLUDES += vendor/nxp
LOCAL_STATIC_LIBRARIES += liblifevibes
LOCAL_SHARED_LIBRARIES += liblvmxservice
# LOCAL_SHARED_LIBRARIES += liblvmxipc
endif
include $(BUILD_SHARED_LIBRARY) 模块三编译成动态库
(4)编译一个应用程序(APK)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory-->直译(建立在java子目录中的所有Java文件)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build-->直译(创建APK的名称)
LOCAL_PACKAGE_NAME := LocalPackage
# Tell it to build an APK-->直译(告诉它来建立一个APK)
include $(BUILD_PACKAGE)
(5)编译一个依赖于静态Java库(static.jar)的应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# List of static libraries to include in the package
LOCAL_STATIC_JAVA_LIBRARIES := static-library
# 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
# Tell it to build an APK
include $(BUILD_PACKAGE)
(6)编译一个需要用平台的key签名的应用程序
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)
(7)编译一个需要用特定key前面的应用程序
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 := vendor/example/certs/app
# Tell it to build an APK
include $(BUILD_PACKAGE)
(8)添加一个预编译应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Mole name should match apk name to be installed.
LOCAL_MODULE := LocalMoleName
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)
(9)添加一个静态JAVA库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Any libraries that this library depends on
LOCAL_JAVA_LIBRARIES := android.test.runner
# The name of the jar file to create
LOCAL_MODULE := sample
# Build a static jar file.
include $(BUILD_STATIC_JAVA_LIBRARY)
(10)Android.mk的编译模块中间可以定义相关的编译内容,也就是指定相关的变量如下:
LOCAL_AAPT_FLAGS
LOCAL_ACP_UNAVAILABLE
LOCAL_ADDITIONAL_JAVA_DIR
LOCAL_AIDL_INCLUDES
LOCAL_ALLOW_UNDEFINED_SYMBOLS
LOCAL_ARM_MODE
LOCAL_ASFLAGS
LOCAL_ASSET_DIR
LOCAL_ASSET_FILES 在Android.mk文件中编译应用程序(BUILD_PACKAGE)时设置此变量,表示资源文件,
通常会定义成LOCAL_ASSET_FILES += $(call find-subdir-assets)
LOCAL_BUILT_MODULE_STEM
LOCAL_C_INCLUDES 额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录
举例如下:
LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_CC 指定C编译器
LOCAL_CERTIFICATE 签名认证
LOCAL_CFLAGS 为C/C++编译器定义额外的标志(如宏定义),举例:LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1
LOCAL_CLASSPATH
LOCAL_COMPRESS_MODULE_SYMBOLS
LOCAL_COPY_HEADERS install应用程序时需要复制的头文件,必须同时定义LOCAL_COPY_HEADERS_TO
LOCAL_COPY_HEADERS_TO install应用程序时复制头文件的目的路径
LOCAL_CPP_EXTENSION 如果你的C++文件不是以cpp为文件后缀,你可以通过LOCAL_CPP_EXTENSION指定C++文件后缀名
如:LOCAL_CPP_EXTENSION := .cc
注意统一模块中C++文件后缀必须保持一致。
LOCAL_CPPFLAGS 传递额外的标志给C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection
LOCAL_CXX 指定C++编译器
LOCAL_DX_FLAGS
LOCAL_EXPORT_PACKAGE_RESOURCES
LOCAL_FORCE_STATIC_EXECUTABLE 如果编译的可执行程序要进行静态链接(执行时不依赖于任何动态库),则设置LOCAL_FORCE_STATIC_EXECUTABLE:=true
目前只有libc有静态库形式,这个只有文件系统中/sbin目录下的应用程序会用到,这个目录下的应用程序在运行时通常
文件系统的其它部分还没有加载,所以必须进行静态链接。
LOCAL_GENERATED_SOURCES
LOCAL_INSTRUMENTATION_FOR
LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME
LOCAL_INTERMEDIATE_SOURCES
LOCAL_INTERMEDIATE_TARGETS
LOCAL_IS_HOST_MODULE
LOCAL_JAR_MANIFEST
LOCAL_JARJAR_RULES
LOCAL_JAVA_LIBRARIES 编译java应用程序和库的时候指定包含的java类库,目前有core和framework两种
多数情况下定义成:LOCAL_JAVA_LIBRARIES := core framework
注意LOCAL_JAVA_LIBRARIES不是必须的,而且编译APK时不允许定义(系统会自动添加)
LOCAL_JAVA_RESOURCE_DIRS
LOCAL_JAVA_RESOURCE_FILES
LOCAL_JNI_SHARED_LIBRARIES
LOCAL_LDFLAGS 传递额外的参数给连接器(务必注意参数的顺序)
LOCAL_LDLIBS 为可执行程序或者库的编译指定额外的库,指定库以"-lxxx"格式,举例:
LOCAL_LDLIBS += -lcurses -lpthread
LOCAL_LDLIBS += -Wl,-z,origin
LOCAL_MODULE 生成的模块的名称(注意应用程序名称用LOCAL_PACKAGE_NAME而不是LOCAL_MODULE)
LOCAL_MODULE_PATH 生成模块的路径
LOCAL_MODULE_STEM
LOCAL_MODULE_TAGS 生成模块的标记
LOCAL_NO_DEFAULT_COMPILER_FLAGS
LOCAL_NO_EMMA_COMPILE
LOCAL_NO_EMMA_INSTRUMENT
LOCAL_NO_STANDARD_LIBRARIES
LOCAL_OVERRIDES_PACKAGES
LOCAL_PACKAGE_NAME APK应用程序的名称
LOCAL_POST_PROCESS_COMMAND
LOCAL_PREBUILT_EXECUTABLES 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用,指定需要复制的可执行文件
LOCAL_PREBUILT_JAVA_LIBRARIES
LOCAL_PREBUILT_LIBS 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用, 指定需要复制的库.
LOCAL_PREBUILT_OBJ_FILES
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
LOCAL_PRELINK_MODULE 是否需要预连接处理(默认需要,用来做动态库优化)
LOCAL_REQUIRED_MODULES 指定模块运行所依赖的模块(模块安装时将会同步安装它所依赖的模块)
LOCAL_RESOURCE_DIR
LOCAL_SDK_VERSION
LOCAL_SHARED_LIBRARIES 可链接动态库
LOCAL_SRC_FILES 编译源文件
LOCAL_STATIC_JAVA_LIBRARIES
LOCAL_STATIC_LIBRARIES 可链接静态库
LOCAL_UNINSTALLABLE_MODULE
LOCAL_UNSTRIPPED_PATH
LOCAL_WHOLE_STATIC_LIBRARIES 指定模块所需要载入的完整静态库(这些精通库在链接是不允许链接器删除其中无用的代码)
LOCAL_YACCFLAGS
OVERRIDE_BUILT_MODULE_PATH
⑻ 在linux操作系统上封装的.so库能在安卓上直接使用库里的函数么
linux下的.so文件为共享库,相当于windows下的dll文件,使用方法如下:
在你的工程源代码里包含.h头文件,然后可以调用动态库里的函数,在链接的时候加上如下编译器参数:
-l xx.so
如果你的so文件是以lib开头的,还可以直接这样使用:
-lxx
xx是你的.so文件名
其实使用方法和你使用数学库函数是一样的,源代码中添加
#include ,编译的时候,加上-lm参数。
