Skip to content

Commit 1b7cfbf

Browse files
committed
Optimized process of copying native libs.
1 parent ad024b1 commit 1b7cfbf

File tree

6 files changed

+91
-98
lines changed

6 files changed

+91
-98
lines changed

CoreLibrary/src/main/java/com/didi/virtualapk/internal/LoadedPlugin.java

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import android.graphics.Rect;
4848
import android.graphics.drawable.Drawable;
4949
import android.os.Build;
50-
import android.os.Bundle;
5150
import android.os.Process;
5251
import android.os.UserHandle;
5352
import android.support.annotation.NonNull;
@@ -147,22 +146,7 @@ private static ResolveInfo chooseBestActivity(Intent intent, String s, int flags
147146

148147
private Application mApplication;
149148

150-
// void dumpClass(Class cls) {
151-
// Log.w(TAG, "########################################");
152-
// Log.w(TAG, "cls: " + cls.getName());
153-
// Log.w(TAG, "cls.super: " + cls.getSuperclass());
154-
// Log.w(TAG, "field size: " + cls.getDeclaredFields().length);
155-
// Log.w(TAG, "method size: " + cls.getDeclaredMethods().length);
156-
//
157-
// for (Field f : cls.getDeclaredFields()) {
158-
// Log.w(TAG, "field: " + f.getType().getName() + " " + f.getName());
159-
// }
160-
// for (Method m : cls.getDeclaredMethods()) {
161-
// Log.w(TAG, "method: " + m.getReturnType() + " " + m.getName() + " " + Arrays.toString(m.getParameterTypes()));
162-
// }
163-
// }
164-
165-
LoadedPlugin(PluginManager pluginManager, Context context, File apk) throws PackageParser.PackageParserException {
149+
LoadedPlugin(PluginManager pluginManager, Context context, File apk) throws Exception {
166150
this.mPluginManager = pluginManager;
167151
this.mHostContext = context;
168152
this.mLocation = apk.getAbsolutePath();
@@ -172,14 +156,6 @@ private static ResolveInfo chooseBestActivity(Intent intent, String s, int flags
172156
this.mPackageInfo.applicationInfo = this.mPackage.applicationInfo;
173157
this.mPackageInfo.applicationInfo.sourceDir = apk.getAbsolutePath();
174158

175-
// dumpClass(PackageParser.class);
176-
// dumpClass(this.mPackage.getClass());
177-
// try {
178-
// dumpClass(Class.forName("android.content.pm.PackageParser$SigningDetails"));
179-
// } catch (ClassNotFoundException e) {
180-
// Log.w(TAG, e);
181-
// }
182-
183159
if (Build.VERSION.SDK_INT == 27 && Build.VERSION.PREVIEW_SDK_INT != 0) { // Android P Preview
184160
this.mPackageInfo.signatures = this.mPackage.mSigningDetails.signatures;
185161
} else {
@@ -239,25 +215,18 @@ private static ResolveInfo chooseBestActivity(Intent intent, String s, int flags
239215
Map<ComponentName, ActivityInfo> receivers = new HashMap<ComponentName, ActivityInfo>();
240216
for (PackageParser.Activity receiver : this.mPackage.receivers) {
241217
receivers.put(receiver.getComponentName(), receiver.info);
242-
243-
try {
244-
BroadcastReceiver br = BroadcastReceiver.class.cast(getClassLoader().loadClass(receiver.getComponentName().getClassName()).newInstance());
245-
for (PackageParser.ActivityIntentInfo aii : receiver.intents) {
246-
this.mHostContext.registerReceiver(br, aii);
247-
}
248-
} catch (Exception e) {
249-
e.printStackTrace();
218+
219+
BroadcastReceiver br = BroadcastReceiver.class.cast(getClassLoader().loadClass(receiver.getComponentName().getClassName()).newInstance());
220+
for (PackageParser.ActivityIntentInfo aii : receiver.intents) {
221+
this.mHostContext.registerReceiver(br, aii);
250222
}
251223
}
252224
this.mReceiverInfos = Collections.unmodifiableMap(receivers);
253225
this.mPackageInfo.receivers = receivers.values().toArray(new ActivityInfo[receivers.size()]);
254226
}
255227

256-
private void tryToCopyNativeLib(File apk) {
257-
Bundle metaData = this.mPackageInfo.applicationInfo.metaData;
258-
if (metaData != null && metaData.getBoolean("VA_IS_HAVE_LIB")) {
259-
PluginUtil.copyNativeLib(apk, mHostContext, mPackageInfo, mNativeLibDir);
260-
}
228+
private void tryToCopyNativeLib(File apk) throws Exception {
229+
PluginUtil.copyNativeLib(apk, mHostContext, mPackageInfo, mNativeLibDir);
261230
}
262231

263232
public String getLocation() {

CoreLibrary/src/main/java/com/didi/virtualapk/utils/PluginUtil.java

Lines changed: 80 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@
2323
import android.content.pm.ActivityInfo;
2424
import android.content.pm.ApplicationInfo;
2525
import android.content.pm.PackageInfo;
26-
import android.content.pm.PackageManager;
2726
import android.content.pm.ServiceInfo;
28-
import android.content.res.Configuration;
2927
import android.content.res.Resources;
3028
import android.os.Build;
3129
import android.os.Bundle;
3230
import android.os.IBinder;
33-
import android.support.annotation.Keep;
3431
import android.text.TextUtils;
32+
import android.util.Log;
3533
import android.view.ContextThemeWrapper;
3634

3735
import com.didi.virtualapk.PluginManager;
@@ -46,10 +44,6 @@
4644
import java.io.InputStream;
4745
import java.io.OutputStream;
4846
import java.util.Enumeration;
49-
import java.util.HashMap;
50-
import java.util.List;
51-
import java.util.Locale;
52-
import java.util.Map;
5347
import java.util.zip.ZipEntry;
5448
import java.util.zip.ZipFile;
5549

@@ -186,68 +180,98 @@ public static IBinder getBinder(Bundle bundle, String key) {
186180
return null;
187181
}
188182
}
189-
190-
public static void copyNativeLib(File apk, Context context, PackageInfo packageInfo, File nativeLibDir) {
183+
184+
public static void copyNativeLib(File apk, Context context, PackageInfo packageInfo, File nativeLibDir) throws Exception {
185+
long startTime = System.currentTimeMillis();
186+
ZipFile zipfile = new ZipFile(apk.getAbsolutePath());
187+
191188
try {
192-
String cpuArch;
193189
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
194-
cpuArch = Build.SUPPORTED_ABIS[0];
190+
for (String cpuArch : Build.SUPPORTED_ABIS) {
191+
if (findAndCopyNativeLib(zipfile, context, cpuArch, packageInfo, nativeLibDir)) {
192+
return;
193+
}
194+
}
195+
195196
} else {
196-
cpuArch = Build.CPU_ABI;
197-
}
198-
boolean findSo = false;
199-
200-
ZipFile zipfile = new ZipFile(apk.getAbsolutePath());
201-
ZipEntry entry;
202-
Enumeration e = zipfile.entries();
203-
while (e.hasMoreElements()) {
204-
entry = (ZipEntry) e.nextElement();
205-
if (entry.isDirectory())
206-
continue;
207-
if(entry.getName().endsWith(".so") && entry.getName().contains("lib/" + cpuArch)){
208-
findSo = true;
209-
break;
197+
if (findAndCopyNativeLib(zipfile, context, Build.CPU_ABI, packageInfo, nativeLibDir)) {
198+
return;
210199
}
211200
}
212-
e = zipfile.entries();
213-
while (e.hasMoreElements()) {
214-
entry = (ZipEntry) e.nextElement();
215-
if (entry.isDirectory() || !entry.getName().endsWith(".so"))
201+
202+
findAndCopyNativeLib(zipfile, context, "armeabi", packageInfo, nativeLibDir);
203+
204+
} finally {
205+
zipfile.close();
206+
Log.d("NativeLib", "Done! +" + (System.currentTimeMillis() - startTime) + "ms");
207+
}
208+
}
209+
210+
private static boolean findAndCopyNativeLib(ZipFile zipfile, Context context, String cpuArch, PackageInfo packageInfo, File nativeLibDir) throws Exception {
211+
Log.d("NativeLib", "Try to copy plugin's cup arch: " + cpuArch);
212+
boolean findLib = false;
213+
boolean findSo = false;
214+
byte buffer[] = null;
215+
String libPrefix = "lib/" + cpuArch + "/";
216+
ZipEntry entry;
217+
Enumeration e = zipfile.entries();
218+
219+
while (e.hasMoreElements()) {
220+
entry = (ZipEntry) e.nextElement();
221+
String entryName = entry.getName();
222+
223+
if (entryName.charAt(0) < 'l') {
224+
continue;
225+
}
226+
if (entryName.charAt(0) > 'l') {
227+
break;
228+
}
229+
if (!findLib && !entryName.startsWith("lib/")) {
230+
continue;
231+
}
232+
findLib = true;
233+
if (!entryName.endsWith(".so") || !entryName.startsWith(libPrefix)) {
234+
continue;
235+
}
236+
237+
if (buffer == null) {
238+
findSo = true;
239+
Log.d("NativeLib", "Found plugin's cup arch dir: " + cpuArch);
240+
buffer = new byte[8192];
241+
}
242+
243+
String libName = entryName.substring(entryName.lastIndexOf('/') + 1);
244+
Log.d("NativeLib", "verify so " + libName);
245+
File libFile = new File(nativeLibDir, libName);
246+
String key = packageInfo.packageName + "_" + libName;
247+
if (libFile.exists()) {
248+
int VersionCode = Settings.getSoVersion(context, key);
249+
if (VersionCode == packageInfo.versionCode) {
250+
Log.d("NativeLib", "skip existing so : " + entry.getName());
216251
continue;
217-
if((findSo && entry.getName().contains("lib/" + cpuArch)) || (!findSo && entry.getName().contains("lib/armeabi/"))){
218-
String[] temp = entry.getName().split("/");
219-
String libName = temp[temp.length - 1];
220-
System.out.println("verify so " + libName);
221-
File libFile = new File(nativeLibDir.getAbsolutePath() + File.separator + libName);
222-
String key = packageInfo.packageName + "_" + libName;
223-
if (libFile.exists()) {
224-
int VersionCode = Settings.getSoVersion(context, key);
225-
if (VersionCode == packageInfo.versionCode) {
226-
System.out.println("skip existing so : " + entry.getName());
227-
continue;
228-
}
229-
}
230-
FileOutputStream fos = new FileOutputStream(libFile);
231-
System.out.println("copy so " + entry.getName() + " of " + cpuArch);
232-
copySo(zipfile.getInputStream(entry), fos);
233-
Settings.setSoVersion(context, key, packageInfo.versionCode);
234252
}
235-
236253
}
237-
238-
zipfile.close();
239-
} catch (IOException e) {
240-
e.printStackTrace();
254+
FileOutputStream fos = new FileOutputStream(libFile);
255+
Log.d("NativeLib", "copy so " + entry.getName() + " of " + cpuArch);
256+
copySo(buffer, zipfile.getInputStream(entry), fos);
257+
Settings.setSoVersion(context, key, packageInfo.versionCode);
241258
}
259+
260+
if (!findLib) {
261+
Log.d("NativeLib", "Fast skip all!");
262+
return true;
263+
}
264+
265+
return findSo;
242266
}
243-
244-
private static void copySo(InputStream input, OutputStream output) throws IOException {
267+
268+
private static void copySo(byte[] buffer, InputStream input, OutputStream output) throws IOException {
245269
BufferedInputStream bufferedInput = new BufferedInputStream(input);
246270
BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
247271
int count;
248-
byte data[] = new byte[8192];
249-
while ((count = bufferedInput.read(data, 0, 8192)) != -1) {
250-
bufferedOutput.write(data, 0, count);
272+
273+
while ((count = bufferedInput.read(buffer)) > 0) {
274+
bufferedOutput.write(buffer, 0, count);
251275
}
252276
bufferedOutput.flush();
253277
bufferedOutput.close();

CoreLibrary/upload.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def gitUrl = 'https://github.com/didi/VirtualAPK' // Git仓库的url
1111
group = GROUP_ID
1212
archivesBaseName = 'core'
1313

14-
version = "0.9.4-dev"
14+
version = "0.9.5-dev"
1515

1616

1717
install {

PluginDemo/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ dependencies {
5151
// the following aars are also compiled in host project, so they will be filterd when build plugin apk.
5252
// but, wo can still visit their Class and Resources.
5353
compile 'com.android.support:appcompat-v7:23.4.0'
54-
compile 'com.didi.virtualapk:core:0.9.4-dev'
54+
compile 'com.didi.virtualapk:core:0.9.5-dev'
5555
}
5656

5757
apply plugin: 'com.didi.virtualapk.plugin'

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ apply plugin: 'com.didi.virtualapk.host'
4141
Compile VirtualAPK in application module of `build.gradle`.
4242

4343
``` java
44-
compile 'com.didi.virtualapk:core:0.9.4-dev'
44+
compile 'com.didi.virtualapk:core:0.9.5-dev'
4545
```
4646

4747
Initialize `PluginManager` in `YourApplication::attachBaseContext()`.

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ dependencies {
4949
testCompile 'junit:junit:4.12'
5050

5151
compile 'com.android.support:appcompat-v7:23.4.0'
52-
compile 'com.didi.virtualapk:core:0.9.4-dev'
52+
compile 'com.didi.virtualapk:core:0.9.5-dev'
5353
// compile project (':CoreLibrary')
5454

5555
}

0 commit comments

Comments
 (0)