项目中需要将一些使用NDK编译的so库文件放到assets目录打包。因为所有so文件是按照目录存放和查找加载的,libs路径打包有问题,就考虑放到assets下,启动的时候进行拷贝。从网络上找到一个拷贝的类,做了些小的修改,以满足拷贝所有文件及文件夹的需求。
/*******************************************************************************************
*
*FileName: AssetsCopyer.java
*Author: xxx
*Time: 2016年6月28日 下午3:31:49
*
/******************************************************************************************/
package com.xxx.vr.utils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;
import android.util.Log;
public class AssetsCopyer {
private static final String TAG = "AssetsCopyer";
public static void releaseAssets(Context context, String assetsDir,
String releaseDir) {
// Log.d(TAG, "context: " + context + ", " + assetsDir);
if (TextUtils.isEmpty(releaseDir)) {
return;
} else if (releaseDir.endsWith("/")) {
releaseDir = releaseDir.substring(0, releaseDir.length() - 1);
}
if (TextUtils.isEmpty(assetsDir) || assetsDir.equals("/")) {
assetsDir = "";
} else if (assetsDir.endsWith("/")) {
assetsDir = assetsDir.substring(0, assetsDir.length() - 1);
}
AssetManager assets = context.getAssets();
try {
String[] fileNames = assets.list(assetsDir);//只能获取到文件(夹)名,所以还得判断是文件夹还是文件
if (fileNames.length > 0) {// is dir
for (String name : fileNames) {
if (!TextUtils.isEmpty(assetsDir)) {
name = assetsDir + File.separator + name;//补全assets资源路径
}
// Log.i(, brian name= + name);
String[] childNames = assets.list(name);//判断是文件还是文件夹
if (!TextUtils.isEmpty(name) && childNames.length > 0) {
checkFolderExists(releaseDir + File.separator + name);
releaseAssets(context, name, releaseDir);//递归, 因为资源都是带着全路径,
//所以不需要在递归是设置目标文件夹的路径
} else {
InputStream is = assets.open(name);
// FileUtil.writeFile(releaseDir + File.separator + name, is);
writeFile(releaseDir + File.separator + name, is);
}
}
} else {// is file
InputStream is = assets.open(assetsDir);
// 写入文件前, 需要提前级联创建好路径, 下面有代码贴出
// FileUtil.writeFile(releaseDir + File.separator + assetsDir, is);
writeFile(releaseDir + File.separator + assetsDir, is);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean writeFile(String fileName, InputStream in) throws IOException
{
boolean bRet = true;
try {
OutputStream os = new FileOutputStream(fileName);
byte[] buffer = new byte[4112];
int read;
while((read = in.read(buffer)) != -1)
{
os.write(buffer, 0, read);
}
in.close();
in = null;
os.flush();
os.close();
os = null;
// Log.v(TAG, "copyed file: " + fileName);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
bRet = false;
}
return bRet;
}
private static void checkFolderExists(String path)
{
File file = new File(path);
if((file.exists() && !file.isDirectory()) || !file.exists())
{
file.mkdirs();
}
}
}