Android Studio 1.4主工程中使用gradle:1.3.0生成包含NDK的APK没有包含非".so"后缀的文件

Android Studio 1.4主工程中使用gradle:1.3.0,编译NDK,其中生成两个文件,一个是.so的动态链接库,另一个是可执行程序,没有扩展名,在最后生成的APK中没有包含非".so"后缀的文件。这个问题纠结了好久,最后追踪到了Android Studio对应的Gradle代码文件中。发现在

Android Studio\gradle\m2repository\com\android\tools\build\builder\1.3.0\builder-1.3.0-sources.jar!\com\android\builder\internal\packaging\Packager.java

文件中有一个变量

private static final Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",Pattern.CASE_INSENSITIVE);

这个变量决定了最后的打包时候的过滤条件。

具体的代码如下图所示:ndk_build_not_include
最后的解决方案,就是把编译之后的文件重新命名成为“.so”。

这边的build.gradle的配置如下:

(其他配置参考Android Studio 1.2 开发JNI工程

task ndkBuild(type: Exec) {
	def Properties localProps = new Properties()
	localProps.load(new FileInputStream("local.properties"))
	def ndk_dir=localProps['ndk.dir']

	def ndk_build_cmd = "$ndk_dir/ndk-build"
	if (Os.isFamily(Os.FAMILY_WINDOWS)) {
		ndk_build_cmd = "$ndk_dir/ndk-build.cmd"
	}
	if(ndkBuild_Debug_Enabled) {
		commandLine ndk_build_cmd,
				'-j', Runtime.runtime.availableProcessors(),
				"NDK_PROJECT_PATH=$rootDir/app/src/main",
				"NDK_OUT=$buildDir/native/obj",
				"NDK_DEBUG=1"
	} else{
		commandLine ndk_build_cmd,
				'-j', Runtime.runtime.availableProcessors(),
				"NDK_PROJECT_PATH=$rootDir/app/src/main",
				"NDK_OUT=$buildDir/native/obj"
	}
	doLast {
		/* com.android.build.gradle.tasks.PackageApplication->doFullTaskAction->getBuilder().packageApk
		*Android Studio\gradle\m2repository\com\android\tools\build\builder\1.3.0\builder-1.3.0-sources.jar!\com\android\builder\internal\packaging\Packager.java
		*中的过滤变量     private static final Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",Pattern.CASE_INSENSITIVE);
		* 不能包含名字不是SO的其他文件
		*/
		File file = new File("$rootDir/app/src/main/libs");
		File[] files = file.listFiles(new FilenameFilter() {
			/**
			 * 测试指定文件是否应该包含在某一文件列表中。
			 *
			 * @param dir
			 *            被找到的文件所在的目录。
			 * @param name
			 *            文件的名称。
			 * @return 当且仅当该名称应该包含在文件列表中时返回 true;否则返回
			 *         false。返回true时,该文件将被允许添加到文件列表中,否则不能添加到文件列表中。
			 */
			public boolean accept(File dir, String name) {
				File f = new File(dir, name);
				if (f.isDirectory()) {
					File rf = new File(f.getPath(), "Standalone");
					if(rf.exists()){
						return true;
					}
					return false;
				}
				else {
					return false;// 否则返回false。
				}
			}
		});
		for(File f : files) {
			File src_file = new File(f.getAbsolutePath(), "Standalone");
			File dst_file = new File(f.getAbsolutePath(), "Standalone.so");
			dst_file.delete();
			src_file.renameTo(dst_file)
		}
	}
}

发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注