动态加载so文件方案实现
This commit is contained in:
240
common/src/main/java/com/yunbao/common/utils/LoadSoUtil.java
Normal file
240
common/src/main/java/com/yunbao/common/utils/LoadSoUtil.java
Normal file
@@ -0,0 +1,240 @@
|
||||
package com.yunbao.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class LoadSoUtil {
|
||||
|
||||
public static void loadSo(Context context, onLoadSoListener listener) {
|
||||
try {
|
||||
String path = context.getFilesDir().getAbsolutePath() + "/dynamic_so";
|
||||
File file = new File(path);
|
||||
AssetManager assetManager = context.getAssets();
|
||||
String[] files = assetManager.list("libso");
|
||||
if (!file.exists()) {
|
||||
boolean b = file.mkdir();
|
||||
Log.i("mLog", "创建文件 " + b);
|
||||
}
|
||||
if (file.listFiles().length != files.length) {//说明之前已经保存了
|
||||
file.delete();
|
||||
file.mkdir();
|
||||
Log.i("mLog", "需要拷贝so文件 ");
|
||||
// 获取AssetManager对象
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
loadLibrary(context, "libso/" + files[i], files[i]);
|
||||
}
|
||||
}
|
||||
listener.ok();
|
||||
Log.i("mLog", "拷贝so成功------------------------");
|
||||
} catch (IOException e) {
|
||||
Log.e("mLog", "拷贝so错误++++++++++++++++++++");
|
||||
e.printStackTrace();
|
||||
listener.error();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadSo2(Context context, onLoadSoListener listener) {
|
||||
String path = context.getFilesDir().getAbsolutePath() + "/so_zip";
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
file.mkdir();
|
||||
} else if (isLoadSo(context)) {
|
||||
listener.ok();
|
||||
return;
|
||||
}
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.readTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10 * 5, TimeUnit.SECONDS)
|
||||
.cookieJar(new CookieJar() {
|
||||
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void saveFromResponse(@NotNull HttpUrl httpUrl, @NotNull List<Cookie> list) {
|
||||
cookieStore.put(httpUrl.host(), list);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Cookie> loadForRequest(@NotNull HttpUrl httpUrl) {
|
||||
List<Cookie> cookies = cookieStore.get(httpUrl.host());
|
||||
return cookies != null ? cookies : new ArrayList<>();
|
||||
}
|
||||
});
|
||||
builder.hostnameVerifier((hostname, session) -> true);
|
||||
//开始下载文件
|
||||
downloadFile(builder.build(), "https://downs.yaoulive.com/x86.zip", new File(path + "/" + "libSo.zip"), new onLoadSoListener() {
|
||||
@Override
|
||||
public void ok() {
|
||||
//下载完成开始解压 解压完成之后 区初始化声网数据
|
||||
zip(context, path + "/" + "libSo.zip", listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error() {
|
||||
listener.error();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void zip(Context context, String path, onLoadSoListener listener) {
|
||||
ZipInputStream zis = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
zis = new ZipInputStream(new FileInputStream(path));
|
||||
ZipEntry ze;
|
||||
String soPath = context.getFilesDir().getAbsolutePath() + "/dynamic_so";
|
||||
File file = new File(soPath);
|
||||
if (!file.exists()) {
|
||||
file.mkdir();
|
||||
}
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
String fileName = ze.getName();
|
||||
File newFile = new File(soPath + File.separator + fileName);
|
||||
fos = new FileOutputStream(newFile);
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
zis.closeEntry();
|
||||
}
|
||||
listener.ok();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
listener.error();
|
||||
} finally {
|
||||
try {
|
||||
if (zis != null) zis.close();
|
||||
if (fos != null) fos.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFile(OkHttpClient mOkHttpClient, String url, File file, onLoadSoListener listener) {
|
||||
Request request = new Request.Builder()
|
||||
.get()
|
||||
.url(url)
|
||||
.build();
|
||||
mOkHttpClient.newCall(request)
|
||||
.enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
if (listener != null) listener.error();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) {
|
||||
if (response.isSuccessful()) {
|
||||
InputStream is = null;
|
||||
BufferedOutputStream bos = null;
|
||||
try {
|
||||
is = response.body().byteStream();
|
||||
bos = new BufferedOutputStream(new FileOutputStream(file));
|
||||
byte[] bytes = new byte[10240];
|
||||
int len;
|
||||
while ((len = is.read(bytes)) != -1) {
|
||||
bos.write(bytes, 0, len);
|
||||
}
|
||||
bos.flush();
|
||||
if (listener != null) listener.ok();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (listener != null) listener.error();
|
||||
} finally {
|
||||
try {
|
||||
if (bos != null) bos.close();
|
||||
if (is != null) is.close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isLoadSo(Context context) {
|
||||
String pathSo = context.getFilesDir().getAbsolutePath() + "/dynamic_so";
|
||||
File fileSo = new File(pathSo);
|
||||
if (fileSo.listFiles().length == 22) {//说明之前已经保存了
|
||||
Log.i("mLog", "已经下载了so 所有直接加载就行 ");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean loadLibrary(Context context, String oldFileName, String libName) throws IOException {
|
||||
// 获取应用的私有模式的libs目录(真实的目录是app-libs)
|
||||
String path = context.getFilesDir().getAbsolutePath() + "/dynamic_so/";
|
||||
// 可以获取到assets资源文件的数据流
|
||||
InputStream open = context.getAssets().open(oldFileName);
|
||||
String new_file_name = path + libName;
|
||||
// 把资源文件的数据流写入到app-libs目录下
|
||||
if (!copyLibrary(open, new_file_name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//从assets资源目录下复制到app-libs目录下
|
||||
public static boolean copyLibrary(InputStream fileInputStream, String new_file) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
File file = new File(new_file);
|
||||
fos = new FileOutputStream(file);
|
||||
int dataSize;
|
||||
byte[] dataBuffer = new byte[2048];
|
||||
|
||||
while ((dataSize = fileInputStream.read(dataBuffer)) != -1) {
|
||||
fos.write(dataBuffer, 0, dataSize);
|
||||
}
|
||||
fos.flush();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("mLog", e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (fos != null) fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface onLoadSoListener {
|
||||
void ok();
|
||||
|
||||
void error();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user