赞
踩
mPresenter.addApp(info);
实际上调用的是 io.virtualapp.home.HomePresenterImpl
类的 addApp()
方法 , 安装应用 , 传入 AppInfoLite info
参数 , 封装如下值 :
packageName : com.example.filepath , path : /storage/emulated/0/./app-debug.apk , fastOpen : false
通过 VirtualCore.get().getInstalledAppInfo(info.packageName, 0);
代码 , 获取该应用是否安装过 ,
InstallResult res = mRepo.addVirtualApp(info);
进行安装操作 ;class HomePresenterImpl implements HomeContract.HomePresenter { @Override public void addApp(AppInfoLite info) { class AddResult { private PackageAppData appData; private int userId; private boolean justEnableHidden; } AddResult addResult = new AddResult(); VUiKit.defer().when(() -> { // 获取安装的应用信息 , 该应用之前是否安装过 // 这里应该是判断 克隆应用 / SD 卡 APK 文件 InstalledAppInfo installedAppInfo = VirtualCore.get().getInstalledAppInfo(info.packageName, 0); // 是否隐藏 , 如果之前有安装过 , 即这是第二次安装 , 则需要隐藏 , 命中 if (addResult.justEnableHidden) 分支 addResult.justEnableHidden = installedAppInfo != null; if (addResult.justEnableHidden) { // 克隆应用 int[] userIds = installedAppInfo.getInstalledUsers(); int nextUserId = userIds.length; /* Input : userIds = {0, 1, 3} Output: nextUserId = 2 */ for (int i = 0; i < userIds.length; i++) { if (userIds[i] != i) { nextUserId = i; break; } } addResult.userId = nextUserId; if (VUserManager.get().getUserInfo(nextUserId) == null) { // user not exist, create it automatically. String nextUserName = "Space " + (nextUserId + 1); VUserInfo newUserInfo = VUserManager.get().createUser(nextUserName, VUserInfo.FLAG_ADMIN); if (newUserInfo == null) { throw new IllegalStateException(); } } boolean success = VirtualCore.get().installPackageAsUser(nextUserId, info.packageName); if (!success) { throw new IllegalStateException(); } } else { // SD 卡 APK 文件 , 如果是第一次安装 , 则命中该分支 InstallResult res = mRepo.addVirtualApp(info); if (!res.isSuccess) { throw new IllegalStateException(); } } }).then((res) -> { addResult.appData = PackageAppDataStorage.get().acquire(info.packageName); }).done(res -> { boolean multipleVersion = addResult.justEnableHidden && addResult.userId != 0; if (!multipleVersion) { PackageAppData data = addResult.appData; data.isLoading = true; mView.addAppToLauncher(data); handleOptApp(data, info.packageName, true); } else { MultiplePackageAppData data = new MultiplePackageAppData(addResult.appData, addResult.userId); data.isLoading = true; mView.addAppToLauncher(data); handleOptApp(data, info.packageName, false); } }); } }
InstallResult res = mRepo.addVirtualApp(info);
方法调用的是 AppRepository
类的 addVirtualApp
方法 ;
public class AppRepository implements AppDataSource {
@Override
public InstallResult addVirtualApp(AppInfoLite info) {
// int COMPARE_VERSION = 0X01 << 3;
// int SKIP_DEX_OPT = 0x01 << 6;
int flags = InstallStrategy.COMPARE_VERSION | InstallStrategy.SKIP_DEX_OPT;
// fastOpen 值是 false , 该分支没有命中
if (info.fastOpen) {
flags |= InstallStrategy.DEPEND_SYSTEM_IF_EXIST;
}
// 安装 SD 卡中的 APK 文件
return VirtualCore.get().installPackage(info.path, flags);
}
}
原始数据 AppInfoLite info
如下 :
I/HSL: packageName : com.example.filepath , path : /storage/emulated/0/./app-debug.apk , fastOpen : false
此处找到了可以直接调用的 API 方法 , 调用 VirtualCore.get().installPackage( SD卡绝对路径 , 0X01 << 3 | 0x01 << 6);
API 安装某个路径中中的 APK 文件 ;
flags 值参考 : 0X01 << 3 | 0x01 << 6
;
// int COMPARE_VERSION = 0X01 << 3;
// int SKIP_DEX_OPT = 0x01 << 6;
int flags = InstallStrategy.COMPARE_VERSION | InstallStrategy.SKIP_DEX_OPT;
InstallStrategy
常量类定义 :
public interface InstallStrategy {
int TERMINATE_IF_EXIST = 0x01 << 1;
int UPDATE_IF_EXIST = 0x01 << 2;
int COMPARE_VERSION = 0X01 << 3;
int IGNORE_NEW_VERSION = 0x01 << 4;
int DEPEND_SYSTEM_IF_EXIST = 0x01 << 5;
int SKIP_DEX_OPT = 0x01 << 6;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。