NDK-创建工程
如果创建的是 application工程,则编译之后无法生成.jar \ .aar文件所以需要创建library模块。
第一步创建:在原有的app project 工程里面new Module
选择library 下一步。。finish
第二步:编译libraay工程,生成aar
增加两个测试类
然后build-> make module‘mylibrary’ 或者使用rebuild project
build/intermediates/bundles/debug/classes.jar 就是我们需要的jar文件。
第三步:怎么编译release版本的.aar文件
配置release文件
buildTypes {
release {
minifyEnabled true //混淆
zipAlignEnabled true//Zipalign优化
shrinkResources true// 移除无用的resource文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //加载默认混淆配置文件
}
}
备注:1.默认生成的mylibrary-debug.aar,
打开terminal使用gradlew assembleRelease指令顺利生成了才能生成mylibrary.release.aar文件
2.如果遇到生成的的release.aar无法使用,检查混淆文件 proguard-rules.pro。
#不要压缩(这个必须,因为开启混淆的时候 默认 会把没有被调用的代码 全都排除掉)
-dontshrink
第四步:怎么编译.jar文件
//=======生成jar包脚本 start============================================= def SDK_BASENAME = "myLibrary"; def sdkDestinationPath = "build/outputs/";//生成jar存放目录 //打包release目录下的classes.jar(开启混淆后这个jar就是混淆的源码)----注意由于as版本原因有的在default目录 def releaseJar = file('build/intermediates/bundles/release/classes.jar') //打包debug目录下的classes.jar def debugJar = file('build/intermediates/bundles/debug/classes.jar') //将libs目录下的other.jar,打入jar包 def thirdPartyJar = file('libs/other.jar') //打包jar前先删除原先的jar task deleteBuild(type: Delete) { delete sdkDestinationPath + SDK_BASENAME + ".jar" } task makeJar(type: Jar) { from zipTree(releaseJar)//导出混淆的jar //from zipTree(debugJar)//导出未混淆的jar //from zipTree(thirdPartyJar)将第三方jar包打入jar包 //from fileTree(dir: 'src/main', includes: ['assets/**'])//将assets目录打入jar包 exclude('**/BuildConfig.class')//排除不必要的class文件 baseName = SDK_BASENAME destinationDir = file(sdkDestinationPath) } makeJar.dependsOn(deleteBuild, build) //在AndroidStudio的Terminal窗口中输入gradlew makeJar //=======生成jar包脚本 end=============================================
备注:在AndroidStudio的Terminal 窗口输入 gradlew makeJar
如果只是想生成一个jar文件或者aar文件上面这些内容已经实现了功能,先继续介绍如果生产.so文件
第五步:生成so文件
(1):创建jni\cpp文件夹,所有的C/C++文件都放在这里:mylibrary\src\main\jni
(2):在libraay工程根目录增加CMakeLists.txt :CMake配置文件
(3):在CMakeLists.txt文件里面增加要编译的cpp文件
CMakeLists不会创建的可以参考上一篇文章的介绍:http://blog.****.net/jtzp007/article/details/79484250
(4)在build.gadle增加extenrnalNativeBuild{ }
(5)使用 gradlew assembleRelease编译release版本
\build\intermediates\cmake\release 生成so文件路径
第五步:使用ndk-build方式编译so文件
问题:使用cmake编译生成的cmke/release/obj/下面的so文件很大(1MB),不知道为什么cmke/release目录下面没有生成最终的so库文件。即使在CmakeLists里面增加以下代码优化生成的so文件,可是文件还是有点大,于是只能使用ndk-build方式编译so文件
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
ndk-build编译so文件修改如下:
(1)gradle.properties增加 android.useDeprecatedNdk=true
(2)在defaultConfig里面增加
ndk {
moduleName "NativeExample" //so文件名称
ldLibs "log", "z", "m" //添加log依赖库文件
abiFilters "armeabi", "arm64-v8a" //abi体系结构下的so库
}
(3)屏蔽 externalNativeBuild{ cmake { path "CMakeLists.txt" } }
使用gradlew assembleRelease编译之后 以下两个路径都会生成release版本的so文件,大小是一样的只有6kb
build\intermediates\bundles\release\jni
build\intermediates\ndk\release\lib
备注:上面这个方式会自动编译mylibrary\src\main\jni 目录下面所有的C/C++文件,自动在build\intermediates\ndk\release生成Android.mk,如果想自己设置Android.mk需要做如下修改:
(1) 在 src\main\jni目录增加两个文件: Android.mk 、Application.mk
/*
ndk {
moduleName "NativeExample" //so文件名称
ldLibs "log", "z", "m" //添加log依赖库文件
abiFilters "armeabi", "arm64-v8a" //abi体系结构下的so库
}
*/
(3)build.gradle 增加
externalNativeBuild {
ndkBuild{
path file("src/main/jni/Android.mk")
}
}
(4)编译: 在terminal到jni目录 然后执行ndk-build.cmd
编译完之后会在jni同一级目录生成Application 配置的 so文件
以下是build.gradle的整个配置内容 apply plugin: 'com.android.library' android { compileSdkVersion 25 buildToolsVersion "26.0.2" defaultConfig { minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } signingConfigs { release { File strFile = new File("/release.jks") storeFile file(strFile) storePassword "123456" keyPassword "123456" keyAlias "Appkey" } } buildTypes { debug { // signingConfig signingConfigs.release //签名,不是必须的 minifyEnabled false //混淆 zipAlignEnabled true//Zipalign优化 shrinkResources true// 移除无用的resource文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//加载默认混淆配置文件 } release { // signingConfig signingConfigs.release//签名,不是必须的 minifyEnabled true //混淆 zipAlignEnabled true//Zipalign优化 shrinkResources true// 移除无用的resource文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //加载默认混淆配置文件 } } externalNativeBuild { cmake { path "CMakeLists.txt" } } /* task makeJar(type: Copy) { //删除存在的 delete 'build/outputs/mylibrary.jar' //设置拷贝的文件 from('build/intermediates/bundles/release/') //打进jar包后的文件目录 into('build/outputs/') //将classes.jar放入build/outputs/目录下 //include ,exclude参数来设置过滤 //(我们只关心classes.jar这个文件) include('classes.jar') //重命名 rename ('classes.jar', 'mylibrary.jar') } makeJar.dependsOn(build) //在AndroidStudio的Terminal窗口中输入gradlew makeJar */ //=======生成jar包脚本 start============================================= def SDK_BASENAME = "myLibrary"; def sdkDestinationPath = "build/outputs/";//生成jar存放目录 //打包release目录下的classes.jar(开启混淆后这个jar就是混淆的源码)----注意由于as版本原因有的在default目录 def releaseJar = file('build/intermediates/bundles/release/classes.jar') //打包debug目录下的classes.jar def debugJar = file('build/intermediates/bundles/debug/classes.jar') //将libs目录下的other.jar,打入jar包 def thirdPartyJar = file('libs/other.jar') //打包jar前先删除原先的jar task deleteBuild(type: Delete) { delete sdkDestinationPath + SDK_BASENAME + ".jar" } task makeJar(type: Jar) { from zipTree(releaseJar)//导出混淆的jar //from zipTree(debugJar)//导出未混淆的jar //from zipTree(thirdPartyJar)将第三方jar包打入jar包 //from fileTree(dir: 'src/main', includes: ['assets/**'])//将assets目录打入jar包 exclude('**/BuildConfig.class')//排除不必要的class文件 baseName = SDK_BASENAME destinationDir = file(sdkDestinationPath) } makeJar.dependsOn(deleteBuild, build) //在AndroidStudio的Terminal窗口中输入gradlew makeJar //=======生成jar包脚本 end============================================= } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' testCompile 'junit:junit:4.12' }
C:\MyNDKTest\mylibrary\build\intermediates\classes\release>javah -jni ndk.example.com.mylibrary.One