项目中需要将一些使用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(); } } }