Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
门心叼龙
VirtualAPK
提交
1b7cfbf7
V
VirtualAPK
项目概览
门心叼龙
/
VirtualAPK
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
VirtualAPK
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1b7cfbf7
编写于
5月 09, 2018
作者:
S
superq_sky
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimized process of copying native libs.
上级
ad024b1b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
91 addition
and
98 deletion
+91
-98
CoreLibrary/src/main/java/com/didi/virtualapk/internal/LoadedPlugin.java
.../main/java/com/didi/virtualapk/internal/LoadedPlugin.java
+7
-38
CoreLibrary/src/main/java/com/didi/virtualapk/utils/PluginUtil.java
...y/src/main/java/com/didi/virtualapk/utils/PluginUtil.java
+80
-56
CoreLibrary/upload.gradle
CoreLibrary/upload.gradle
+1
-1
PluginDemo/app/build.gradle
PluginDemo/app/build.gradle
+1
-1
README.md
README.md
+1
-1
app/build.gradle
app/build.gradle
+1
-1
未找到文件。
CoreLibrary/src/main/java/com/didi/virtualapk/internal/LoadedPlugin.java
浏览文件 @
1b7cfbf7
...
@@ -47,7 +47,6 @@ import android.content.res.XmlResourceParser;
...
@@ -47,7 +47,6 @@ import android.content.res.XmlResourceParser;
import
android.graphics.Rect
;
import
android.graphics.Rect
;
import
android.graphics.drawable.Drawable
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Process
;
import
android.os.Process
;
import
android.os.UserHandle
;
import
android.os.UserHandle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.NonNull
;
...
@@ -147,22 +146,7 @@ public final class LoadedPlugin {
...
@@ -147,22 +146,7 @@ public final class LoadedPlugin {
private
Application
mApplication
;
private
Application
mApplication
;
// void dumpClass(Class cls) {
LoadedPlugin
(
PluginManager
pluginManager
,
Context
context
,
File
apk
)
throws
Exception
{
// Log.w(TAG, "########################################");
// Log.w(TAG, "cls: " + cls.getName());
// Log.w(TAG, "cls.super: " + cls.getSuperclass());
// Log.w(TAG, "field size: " + cls.getDeclaredFields().length);
// Log.w(TAG, "method size: " + cls.getDeclaredMethods().length);
//
// for (Field f : cls.getDeclaredFields()) {
// Log.w(TAG, "field: " + f.getType().getName() + " " + f.getName());
// }
// for (Method m : cls.getDeclaredMethods()) {
// Log.w(TAG, "method: " + m.getReturnType() + " " + m.getName() + " " + Arrays.toString(m.getParameterTypes()));
// }
// }
LoadedPlugin
(
PluginManager
pluginManager
,
Context
context
,
File
apk
)
throws
PackageParser
.
PackageParserException
{
this
.
mPluginManager
=
pluginManager
;
this
.
mPluginManager
=
pluginManager
;
this
.
mHostContext
=
context
;
this
.
mHostContext
=
context
;
this
.
mLocation
=
apk
.
getAbsolutePath
();
this
.
mLocation
=
apk
.
getAbsolutePath
();
...
@@ -172,14 +156,6 @@ public final class LoadedPlugin {
...
@@ -172,14 +156,6 @@ public final class LoadedPlugin {
this
.
mPackageInfo
.
applicationInfo
=
this
.
mPackage
.
applicationInfo
;
this
.
mPackageInfo
.
applicationInfo
=
this
.
mPackage
.
applicationInfo
;
this
.
mPackageInfo
.
applicationInfo
.
sourceDir
=
apk
.
getAbsolutePath
();
this
.
mPackageInfo
.
applicationInfo
.
sourceDir
=
apk
.
getAbsolutePath
();
// dumpClass(PackageParser.class);
// dumpClass(this.mPackage.getClass());
// try {
// dumpClass(Class.forName("android.content.pm.PackageParser$SigningDetails"));
// } catch (ClassNotFoundException e) {
// Log.w(TAG, e);
// }
if
(
Build
.
VERSION
.
SDK_INT
==
27
&&
Build
.
VERSION
.
PREVIEW_SDK_INT
!=
0
)
{
// Android P Preview
if
(
Build
.
VERSION
.
SDK_INT
==
27
&&
Build
.
VERSION
.
PREVIEW_SDK_INT
!=
0
)
{
// Android P Preview
this
.
mPackageInfo
.
signatures
=
this
.
mPackage
.
mSigningDetails
.
signatures
;
this
.
mPackageInfo
.
signatures
=
this
.
mPackage
.
mSigningDetails
.
signatures
;
}
else
{
}
else
{
...
@@ -239,25 +215,18 @@ public final class LoadedPlugin {
...
@@ -239,25 +215,18 @@ public final class LoadedPlugin {
Map
<
ComponentName
,
ActivityInfo
>
receivers
=
new
HashMap
<
ComponentName
,
ActivityInfo
>();
Map
<
ComponentName
,
ActivityInfo
>
receivers
=
new
HashMap
<
ComponentName
,
ActivityInfo
>();
for
(
PackageParser
.
Activity
receiver
:
this
.
mPackage
.
receivers
)
{
for
(
PackageParser
.
Activity
receiver
:
this
.
mPackage
.
receivers
)
{
receivers
.
put
(
receiver
.
getComponentName
(),
receiver
.
info
);
receivers
.
put
(
receiver
.
getComponentName
(),
receiver
.
info
);
try
{
BroadcastReceiver
br
=
BroadcastReceiver
.
class
.
cast
(
getClassLoader
().
loadClass
(
receiver
.
getComponentName
().
getClassName
()).
newInstance
());
BroadcastReceiver
br
=
BroadcastReceiver
.
class
.
cast
(
getClassLoader
().
loadClass
(
receiver
.
getComponentName
().
getClassName
()).
newInstance
());
for
(
PackageParser
.
ActivityIntentInfo
aii
:
receiver
.
intents
)
{
for
(
PackageParser
.
ActivityIntentInfo
aii
:
receiver
.
intents
)
{
this
.
mHostContext
.
registerReceiver
(
br
,
aii
);
this
.
mHostContext
.
registerReceiver
(
br
,
aii
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
}
this
.
mReceiverInfos
=
Collections
.
unmodifiableMap
(
receivers
);
this
.
mReceiverInfos
=
Collections
.
unmodifiableMap
(
receivers
);
this
.
mPackageInfo
.
receivers
=
receivers
.
values
().
toArray
(
new
ActivityInfo
[
receivers
.
size
()]);
this
.
mPackageInfo
.
receivers
=
receivers
.
values
().
toArray
(
new
ActivityInfo
[
receivers
.
size
()]);
}
}
private
void
tryToCopyNativeLib
(
File
apk
)
{
private
void
tryToCopyNativeLib
(
File
apk
)
throws
Exception
{
Bundle
metaData
=
this
.
mPackageInfo
.
applicationInfo
.
metaData
;
PluginUtil
.
copyNativeLib
(
apk
,
mHostContext
,
mPackageInfo
,
mNativeLibDir
);
if
(
metaData
!=
null
&&
metaData
.
getBoolean
(
"VA_IS_HAVE_LIB"
))
{
PluginUtil
.
copyNativeLib
(
apk
,
mHostContext
,
mPackageInfo
,
mNativeLibDir
);
}
}
}
public
String
getLocation
()
{
public
String
getLocation
()
{
...
...
CoreLibrary/src/main/java/com/didi/virtualapk/utils/PluginUtil.java
浏览文件 @
1b7cfbf7
...
@@ -23,15 +23,13 @@ import android.content.Intent;
...
@@ -23,15 +23,13 @@ import android.content.Intent;
import
android.content.pm.ActivityInfo
;
import
android.content.pm.ActivityInfo
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageManager
;
import
android.content.pm.ServiceInfo
;
import
android.content.pm.ServiceInfo
;
import
android.content.res.Configuration
;
import
android.content.res.Resources
;
import
android.content.res.Resources
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.IBinder
;
import
android.os.IBinder
;
import
android.support.annotation.Keep
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
android.view.ContextThemeWrapper
;
import
android.view.ContextThemeWrapper
;
import
com.didi.virtualapk.PluginManager
;
import
com.didi.virtualapk.PluginManager
;
...
@@ -46,10 +44,6 @@ import java.io.IOException;
...
@@ -46,10 +44,6 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.util.Enumeration
;
import
java.util.Enumeration
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
java.util.zip.ZipFile
;
...
@@ -186,68 +180,98 @@ public class PluginUtil {
...
@@ -186,68 +180,98 @@ public class PluginUtil {
return
null
;
return
null
;
}
}
}
}
public
static
void
copyNativeLib
(
File
apk
,
Context
context
,
PackageInfo
packageInfo
,
File
nativeLibDir
)
{
public
static
void
copyNativeLib
(
File
apk
,
Context
context
,
PackageInfo
packageInfo
,
File
nativeLibDir
)
throws
Exception
{
long
startTime
=
System
.
currentTimeMillis
();
ZipFile
zipfile
=
new
ZipFile
(
apk
.
getAbsolutePath
());
try
{
try
{
String
cpuArch
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
cpuArch
=
Build
.
SUPPORTED_ABIS
[
0
];
for
(
String
cpuArch
:
Build
.
SUPPORTED_ABIS
)
{
if
(
findAndCopyNativeLib
(
zipfile
,
context
,
cpuArch
,
packageInfo
,
nativeLibDir
))
{
return
;
}
}
}
else
{
}
else
{
cpuArch
=
Build
.
CPU_ABI
;
if
(
findAndCopyNativeLib
(
zipfile
,
context
,
Build
.
CPU_ABI
,
packageInfo
,
nativeLibDir
))
{
}
return
;
boolean
findSo
=
false
;
ZipFile
zipfile
=
new
ZipFile
(
apk
.
getAbsolutePath
());
ZipEntry
entry
;
Enumeration
e
=
zipfile
.
entries
();
while
(
e
.
hasMoreElements
())
{
entry
=
(
ZipEntry
)
e
.
nextElement
();
if
(
entry
.
isDirectory
())
continue
;
if
(
entry
.
getName
().
endsWith
(
".so"
)
&&
entry
.
getName
().
contains
(
"lib/"
+
cpuArch
)){
findSo
=
true
;
break
;
}
}
}
}
e
=
zipfile
.
entries
();
while
(
e
.
hasMoreElements
())
{
findAndCopyNativeLib
(
zipfile
,
context
,
"armeabi"
,
packageInfo
,
nativeLibDir
);
entry
=
(
ZipEntry
)
e
.
nextElement
();
if
(
entry
.
isDirectory
()
||
!
entry
.
getName
().
endsWith
(
".so"
))
}
finally
{
zipfile
.
close
();
Log
.
d
(
"NativeLib"
,
"Done! +"
+
(
System
.
currentTimeMillis
()
-
startTime
)
+
"ms"
);
}
}
private
static
boolean
findAndCopyNativeLib
(
ZipFile
zipfile
,
Context
context
,
String
cpuArch
,
PackageInfo
packageInfo
,
File
nativeLibDir
)
throws
Exception
{
Log
.
d
(
"NativeLib"
,
"Try to copy plugin's cup arch: "
+
cpuArch
);
boolean
findLib
=
false
;
boolean
findSo
=
false
;
byte
buffer
[]
=
null
;
String
libPrefix
=
"lib/"
+
cpuArch
+
"/"
;
ZipEntry
entry
;
Enumeration
e
=
zipfile
.
entries
();
while
(
e
.
hasMoreElements
())
{
entry
=
(
ZipEntry
)
e
.
nextElement
();
String
entryName
=
entry
.
getName
();
if
(
entryName
.
charAt
(
0
)
<
'l'
)
{
continue
;
}
if
(
entryName
.
charAt
(
0
)
>
'l'
)
{
break
;
}
if
(!
findLib
&&
!
entryName
.
startsWith
(
"lib/"
))
{
continue
;
}
findLib
=
true
;
if
(!
entryName
.
endsWith
(
".so"
)
||
!
entryName
.
startsWith
(
libPrefix
))
{
continue
;
}
if
(
buffer
==
null
)
{
findSo
=
true
;
Log
.
d
(
"NativeLib"
,
"Found plugin's cup arch dir: "
+
cpuArch
);
buffer
=
new
byte
[
8192
];
}
String
libName
=
entryName
.
substring
(
entryName
.
lastIndexOf
(
'/'
)
+
1
);
Log
.
d
(
"NativeLib"
,
"verify so "
+
libName
);
File
libFile
=
new
File
(
nativeLibDir
,
libName
);
String
key
=
packageInfo
.
packageName
+
"_"
+
libName
;
if
(
libFile
.
exists
())
{
int
VersionCode
=
Settings
.
getSoVersion
(
context
,
key
);
if
(
VersionCode
==
packageInfo
.
versionCode
)
{
Log
.
d
(
"NativeLib"
,
"skip existing so : "
+
entry
.
getName
());
continue
;
continue
;
if
((
findSo
&&
entry
.
getName
().
contains
(
"lib/"
+
cpuArch
))
||
(!
findSo
&&
entry
.
getName
().
contains
(
"lib/armeabi/"
))){
String
[]
temp
=
entry
.
getName
().
split
(
"/"
);
String
libName
=
temp
[
temp
.
length
-
1
];
System
.
out
.
println
(
"verify so "
+
libName
);
File
libFile
=
new
File
(
nativeLibDir
.
getAbsolutePath
()
+
File
.
separator
+
libName
);
String
key
=
packageInfo
.
packageName
+
"_"
+
libName
;
if
(
libFile
.
exists
())
{
int
VersionCode
=
Settings
.
getSoVersion
(
context
,
key
);
if
(
VersionCode
==
packageInfo
.
versionCode
)
{
System
.
out
.
println
(
"skip existing so : "
+
entry
.
getName
());
continue
;
}
}
FileOutputStream
fos
=
new
FileOutputStream
(
libFile
);
System
.
out
.
println
(
"copy so "
+
entry
.
getName
()
+
" of "
+
cpuArch
);
copySo
(
zipfile
.
getInputStream
(
entry
),
fos
);
Settings
.
setSoVersion
(
context
,
key
,
packageInfo
.
versionCode
);
}
}
}
}
FileOutputStream
fos
=
new
FileOutputStream
(
libFile
);
zipfile
.
close
(
);
Log
.
d
(
"NativeLib"
,
"copy so "
+
entry
.
getName
()
+
" of "
+
cpuArch
);
}
catch
(
IOException
e
)
{
copySo
(
buffer
,
zipfile
.
getInputStream
(
entry
),
fos
);
e
.
printStackTrace
(
);
Settings
.
setSoVersion
(
context
,
key
,
packageInfo
.
versionCode
);
}
}
if
(!
findLib
)
{
Log
.
d
(
"NativeLib"
,
"Fast skip all!"
);
return
true
;
}
return
findSo
;
}
}
private
static
void
copySo
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
private
static
void
copySo
(
byte
[]
buffer
,
InputStream
input
,
OutputStream
output
)
throws
IOException
{
BufferedInputStream
bufferedInput
=
new
BufferedInputStream
(
input
);
BufferedInputStream
bufferedInput
=
new
BufferedInputStream
(
input
);
BufferedOutputStream
bufferedOutput
=
new
BufferedOutputStream
(
output
);
BufferedOutputStream
bufferedOutput
=
new
BufferedOutputStream
(
output
);
int
count
;
int
count
;
byte
data
[]
=
new
byte
[
8192
];
while
((
count
=
bufferedInput
.
read
(
data
,
0
,
8192
))
!=
-
1
)
{
while
((
count
=
bufferedInput
.
read
(
buffer
))
>
0
)
{
bufferedOutput
.
write
(
data
,
0
,
count
);
bufferedOutput
.
write
(
buffer
,
0
,
count
);
}
}
bufferedOutput
.
flush
();
bufferedOutput
.
flush
();
bufferedOutput
.
close
();
bufferedOutput
.
close
();
...
...
CoreLibrary/upload.gradle
浏览文件 @
1b7cfbf7
...
@@ -11,7 +11,7 @@ def gitUrl = 'https://github.com/didi/VirtualAPK' // Git仓库的url
...
@@ -11,7 +11,7 @@ def gitUrl = 'https://github.com/didi/VirtualAPK' // Git仓库的url
group
=
GROUP_ID
group
=
GROUP_ID
archivesBaseName
=
'core'
archivesBaseName
=
'core'
version
=
"0.9.
4
-dev"
version
=
"0.9.
5
-dev"
install
{
install
{
...
...
PluginDemo/app/build.gradle
浏览文件 @
1b7cfbf7
...
@@ -51,7 +51,7 @@ dependencies {
...
@@ -51,7 +51,7 @@ dependencies {
// the following aars are also compiled in host project, so they will be filterd when build plugin apk.
// the following aars are also compiled in host project, so they will be filterd when build plugin apk.
// but, wo can still visit their Class and Resources.
// but, wo can still visit their Class and Resources.
compile
'com.android.support:appcompat-v7:23.4.0'
compile
'com.android.support:appcompat-v7:23.4.0'
compile
'com.didi.virtualapk:core:0.9.
4
-dev'
compile
'com.didi.virtualapk:core:0.9.
5
-dev'
}
}
apply
plugin:
'com.didi.virtualapk.plugin'
apply
plugin:
'com.didi.virtualapk.plugin'
...
...
README.md
浏览文件 @
1b7cfbf7
...
@@ -41,7 +41,7 @@ apply plugin: 'com.didi.virtualapk.host'
...
@@ -41,7 +41,7 @@ apply plugin: 'com.didi.virtualapk.host'
Compile VirtualAPK in application module of
`build.gradle`
.
Compile VirtualAPK in application module of
`build.gradle`
.
```
java
```
java
compile
'
com
.
didi
.
virtualapk
:
core:
0.9
.
4
-
dev
'
compile
'
com
.
didi
.
virtualapk
:
core:
0.9
.
5
-
dev
'
```
```
Initialize
`PluginManager`
in
`YourApplication::attachBaseContext()`
.
Initialize
`PluginManager`
in
`YourApplication::attachBaseContext()`
.
...
...
app/build.gradle
浏览文件 @
1b7cfbf7
...
@@ -49,7 +49,7 @@ dependencies {
...
@@ -49,7 +49,7 @@ dependencies {
testCompile
'junit:junit:4.12'
testCompile
'junit:junit:4.12'
compile
'com.android.support:appcompat-v7:23.4.0'
compile
'com.android.support:appcompat-v7:23.4.0'
compile
'com.didi.virtualapk:core:0.9.
4
-dev'
compile
'com.didi.virtualapk:core:0.9.
5
-dev'
// compile project (':CoreLibrary')
// compile project (':CoreLibrary')
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录