Skip to content

Commit edcb960

Browse files
committed
1、添加对so的支持。2、demo中在webview测试页添加用于测试的hello-jni.so
1 parent 8db5dd0 commit edcb960

File tree

7 files changed

+181
-28
lines changed

7 files changed

+181
-28
lines changed

PluginCore/src/com/plugin/core/PluginCreator.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ private PluginCreator() {
2828
*/
2929
public static DexClassLoader createPluginClassLoader(String absolutePluginApkPath, boolean isStandalone) {
3030
if (!isStandalone) {
31-
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
31+
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(),
32+
new File(absolutePluginApkPath).getParent() + File.separator + "lib",
3233
PluginLoader.class.getClassLoader());
3334
} else {
34-
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
35+
return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(),
36+
new File(absolutePluginApkPath).getParent() + File.separator + "lib",
3537
PluginLoader.class.getClassLoader().getParent());
3638
}
3739

PluginCore/src/com/plugin/core/PluginLoader.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.Hashtable;
1313
import java.util.Iterator;
1414
import java.util.Map.Entry;
15+
import java.util.Set;
1516

1617
import android.app.Application;
1718
import android.content.Context;
@@ -94,9 +95,18 @@ public static synchronized boolean installPlugin(String srcPluginFile) {
9495

9596
String destPluginFile = genInstallPath(pluginDescriptor.getPackageName(), pluginDescriptor.getVersion());
9697
boolean isCopySuccess = FileUtil.copyFile(srcPluginFile, destPluginFile);
97-
98-
// 第四步 添加到已安装插件列表
9998
if (isCopySuccess) {
99+
100+
//第四步,复制插件so到插件so目录, 在构造插件Dexclassloader的时候,会使用这个so目录作为参数
101+
File tempDir = new File(new File(destPluginFile).getParentFile(), "temp");
102+
Set<String> soList = FileUtil.unZipSo(srcPluginFile, tempDir);
103+
if (soList != null) {
104+
for (String soName : soList) {
105+
FileUtil.copySo(tempDir, soName, new File(destPluginFile).getParent() + File.separator + "lib");
106+
}
107+
}
108+
109+
// 第五步 添加到已安装插件列表
100110
pluginDescriptor.setInstalledPath(destPluginFile);
101111
PluginDescriptor previous = sInstalledPlugins.put(pluginDescriptor.getPackageName(), pluginDescriptor);
102112
isInstallSuccess = saveInstalledPlugins(sInstalledPlugins);
@@ -232,7 +242,7 @@ public static Context getNewPluginContext(@SuppressWarnings("rawtypes") Class cl
232242
/**
233243
* 构造插件信息
234244
*
235-
* @param pluginClassBean
245+
* @param
236246
*/
237247
private static void initPlugin(PluginDescriptor pluginDescriptor) {
238248

@@ -384,7 +394,9 @@ public static synchronized void remove(String pluginId) {
384394

385395
boolean isSuccess = saveInstalledPlugins(sInstalledPlugins);
386396

387-
new File(old.getInstalledPath()).delete();
397+
boolean deleteSuccess = FileUtil.deleteAll(new File(old.getInstalledPath()).getParentFile());
398+
399+
LogUtil.d("delete old", isSuccess, deleteSuccess, old.getInstalledPath(), old.getPackageName());
388400

389401
if (isSuccess) {
390402
Intent intent = new Intent(ACTION_PLUGIN_CHANGED);

PluginCore/src/com/plugin/util/FileUtil.java

Lines changed: 157 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,40 @@
11
package com.plugin.util;
22

3+
import android.os.Build;
4+
5+
import java.io.BufferedInputStream;
6+
import java.io.BufferedOutputStream;
37
import java.io.BufferedReader;
8+
import java.io.ByteArrayOutputStream;
49
import java.io.File;
510
import java.io.FileInputStream;
611
import java.io.FileNotFoundException;
712
import java.io.FileOutputStream;
813
import java.io.IOException;
914
import java.io.InputStream;
1015
import java.io.InputStreamReader;
16+
import java.util.ArrayList;
17+
import java.util.Enumeration;
18+
import java.util.HashSet;
19+
import java.util.Set;
1120
import java.util.jar.JarEntry;
1221
import java.util.jar.JarFile;
22+
import java.util.zip.ZipEntry;
23+
import java.util.zip.ZipException;
24+
import java.util.zip.ZipFile;
25+
import java.util.zip.ZipInputStream;
1326

1427
public class FileUtil {
15-
28+
29+
public static boolean copyFile(String source, String dest) {
30+
try {
31+
return copyFile(new FileInputStream(new File(source)), dest);
32+
} catch (FileNotFoundException e) {
33+
e.printStackTrace();
34+
}
35+
return false;
36+
}
37+
1638
public static boolean copyFile(final InputStream inputStream, String dest) {
1739
LogUtil.d("copyFile to " + dest);
1840
FileOutputStream oputStream = null;
@@ -50,16 +72,129 @@ public static boolean copyFile(final InputStream inputStream, String dest) {
5072
return false;
5173
}
5274

53-
public static boolean copyFile(String source, String dest) {
75+
public static boolean copySo(File sourceDir, String so, String dest) {
76+
5477
try {
55-
return copyFile(new FileInputStream(new File(source)), dest);
56-
} catch (FileNotFoundException e) {
78+
79+
String name = "lib" + File.separator + Build.CPU_ABI + File.separator + so;
80+
File sourceFile = new File(sourceDir, name);
81+
82+
if (!sourceFile.exists() && Build.CPU_ABI2 != null) {
83+
name = "lib" + File.separator + Build.CPU_ABI2 + File.separator + so;
84+
sourceFile = new File(sourceDir, name);
85+
86+
if (!sourceFile.exists()) {
87+
name = "lib" + File.separator + "armeabi" + File.separator + so;
88+
sourceFile = new File(sourceDir, name);
89+
}
90+
}
91+
92+
if (sourceFile.exists()) {
93+
copyFile(sourceFile.getAbsolutePath(), dest + File.separator + so);
94+
}
95+
} catch(Exception e) {
5796
e.printStackTrace();
5897
}
59-
return false;
98+
99+
return true;
60100
}
61101

62-
public static String readFileFromJar(String jarFilePath, String metaInfo) {
102+
103+
public static Set<String> unZipSo(String apkFile, File tempDir) {
104+
105+
HashSet<String> result = null;
106+
107+
if (!tempDir.exists()) {
108+
tempDir.mkdirs();
109+
}
110+
111+
LogUtil.d("开始解压到", tempDir.getAbsolutePath());
112+
113+
ZipFile zfile = null;
114+
boolean isSuccess = false;
115+
BufferedOutputStream fos = null;
116+
BufferedInputStream bis = null;
117+
try {
118+
zfile = new ZipFile(apkFile);
119+
ZipEntry ze = null;
120+
Enumeration zList = zfile.entries();
121+
while (zList.hasMoreElements()) {
122+
ze = (ZipEntry) zList.nextElement();
123+
String relativePath = ze.getName();
124+
125+
if (!relativePath.startsWith("lib" + File.separator)) {
126+
LogUtil.d("不是lib目录,跳过", relativePath);
127+
continue;
128+
}
129+
130+
if (ze.isDirectory()) {
131+
File folder = new File(tempDir, relativePath);
132+
LogUtil.d("正在创建目录", folder.getAbsolutePath());
133+
if (!folder.exists()) {
134+
folder.mkdirs();
135+
}
136+
137+
} else {
138+
139+
if (result == null) {
140+
result = new HashSet<String>(4);
141+
}
142+
143+
File targetFile = new File(tempDir, relativePath);
144+
LogUtil.d("正在解压文件", targetFile.getAbsolutePath());
145+
if (!targetFile.getParentFile().exists()) {
146+
targetFile.getParentFile().mkdirs();
147+
}
148+
targetFile.createNewFile();
149+
150+
fos = new BufferedOutputStream(new FileOutputStream(targetFile));
151+
bis = new BufferedInputStream(zfile.getInputStream(ze));
152+
byte[] buffer = new byte[2048];
153+
int count = -1;
154+
while ((count = bis.read(buffer)) != -1) {
155+
fos.write(buffer, 0, count);
156+
fos.flush();
157+
}
158+
fos.close();
159+
fos = null;
160+
bis.close();
161+
bis = null;
162+
163+
result.add(relativePath.substring(relativePath.lastIndexOf(File.separator) +1));
164+
}
165+
}
166+
isSuccess = true;
167+
} catch (IOException e) {
168+
e.printStackTrace();
169+
} finally {
170+
if (fos != null) {
171+
try {
172+
fos.close();
173+
} catch (IOException e) {
174+
e.printStackTrace();
175+
}
176+
}
177+
if (bis != null) {
178+
try {
179+
bis.close();
180+
} catch (IOException e) {
181+
e.printStackTrace();
182+
}
183+
}
184+
if (zfile != null) {
185+
try {
186+
zfile.close();
187+
} catch (IOException e) {
188+
e.printStackTrace();
189+
}
190+
}
191+
}
192+
193+
LogUtil.d("解压结束", isSuccess);
194+
return result;
195+
}
196+
197+
public static void readFileFromJar(String jarFilePath, String metaInfo) {
63198
LogUtil.d("readFileFromJar:", jarFilePath, metaInfo);
64199
JarFile jarFile = null;
65200
try {
@@ -68,9 +203,7 @@ public static String readFileFromJar(String jarFilePath, String metaInfo) {
68203
if (entry != null) {
69204
InputStream input = jarFile.getInputStream(entry);
70205

71-
String info = streamToString(input);
72-
73-
return info;
206+
return;
74207
}
75208

76209
} catch (IOException e) {
@@ -84,22 +217,24 @@ public static String readFileFromJar(String jarFilePath, String metaInfo) {
84217
}
85218
}
86219
}
87-
return null;
220+
return;
88221

89222
}
90223

91-
private static String streamToString(InputStream input) throws IOException {
92-
93-
InputStreamReader isr = new InputStreamReader(input);
94-
BufferedReader reader = new BufferedReader(isr);
95-
96-
String line;
97-
StringBuffer sb = new StringBuffer();
98-
while ((line = reader.readLine()) != null) {
99-
sb.append(line);
224+
/**
225+
* 递归删除文件及文件夹
226+
* @param file
227+
*/
228+
public static boolean deleteAll(File file) {
229+
if (file.isDirectory()) {
230+
File[] childFiles = file.listFiles();
231+
if (childFiles != null && childFiles.length > 0) {
232+
for (int i = 0; i < childFiles.length; i++) {
233+
deleteAll(childFiles[i]);
234+
}
235+
}
100236
}
101-
reader.close();
102-
isr.close();
103-
return sb.toString();
237+
return file.delete();
104238
}
239+
105240
}
5.54 KB
Binary file not shown.

PluginTest/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ android {
2828
java.srcDirs = ['src']
2929
resources.srcDirs = ['src']
3030
aidl.srcDirs = ['src']
31+
jniLibs.srcDirs = ['libs']
3132
renderscript.srcDirs = ['src']
3233
res.srcDirs = ['res']
3334
assets.srcDirs = ['assets']
13.1 KB
Binary file not shown.

PluginTest/src/com/example/plugintest/activity/PluginWebViewActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.widget.Button;
1818
import android.widget.Toast;
1919

20+
import com.example.hellojni.HelloJni;
2021
import com.example.plugintest.R;
2122

2223
public class PluginWebViewActivity extends Activity implements OnClickListener {
@@ -34,6 +35,8 @@ public void onCreate(Bundle savedInstanceState) {
3435
web = (WebView) findViewById(R.id.webview);
3536
setUpWebViewSetting();
3637
setClient();
38+
39+
Toast.makeText(this, "Test Jni so libaray 4 + 7 = "+ HelloJni.calculate(4, 7), Toast.LENGTH_LONG).show();
3740
}
3841

3942
@Override

0 commit comments

Comments
 (0)