安装界面权限提示
apk(Android Package)是用于android平台上的一种压缩包
Android系统中,有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件,这个文件位于如下目录:/data/system/packages.xml。
系统在安装这个apk的过程中,会解析apk的AndroidManifest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
AndroidManifest.xml会经过序列化解析为虚拟机能识别的格式。
截取其中一部分展示如下
<package name="com.example.aidldemo" codePath="/data/app/com.example.aidldemo-vuqxmGF2AOsXKPpYJjYHEw=="
nativeLibraryPath="/data/app/com.example.aidldemo-vuqxmGF2AOsXKPpYJjYHEw==/lib" publicFlags="944291654"
privateFlags="0" ft="16c1d7c1598" it="16c1d7c2078" ut="16c1d7c2078" version="1" userId="10081">
<sigs count="1">
<cert index="12" />
</sigs>
<perms>
<item name="android.permission.RESTART_PACKAGES" granted="true" flags="0" />
<item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" />
<item name="android.permission.CHANGE_NETWORK_STATE" granted="true" flags="0" />
<item name="android.permission.RECEIVE_BOOT_COMPLETED" granted="true" flags="0" />
<item name="android.permission.GET_TASKS" granted="true" flags="0" />
</perms>
<proper-signing-keyset identifier="22" />
</package>
安装和卸载应用
安装应用
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive");
startActivity(intent);
卸载应用
String packageName = "com.example.aidldemo";
Uri packageURI = Uri.parse("package:" + packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
应用安装流程
默认google原生系统情况下
- 拷贝apk文件到data/app目录下
x86模拟器,O版本:
PackageManager对象
ApplicationPackageManager 中关于PackageManager的具体实现,其实是调用IPackageManager来是实现的。
-
PackageManager是个抽象类,实现类是ApplicationPackageManager,在ContextImpl中实例化。
-
ApplicationPackageManager的功能调用实际上是通过构造函数中的mPM(IPackageManager对象)来实现的。mPM是SystemServer进程中 PackageManagerService 的远端代理。
-
mPM通过ActivityThread.getPackageManager()得到,serviceBinder查询“package”的服务,返回一个远端服务的IBinder对象,通过IPackageManager.Stub.asInterface(b)得到远端服务的代理对象IPackageManager.Stub.Proxy对象
-
IPackageManager.Stub继承自Binder,实现了IPackageManager接口。
Context.java
public abstract PackageManager getPackageManager();
ContextImpl.java
Context是个抽象类,包装类是ContextWrapper,真正实现类是ContextImpl
private PackageManager mPackageManager;
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
ActivityThread.java
IPackageManager.Stub.asInterface(b)返回PackageManagerService的代理类
static volatile IPackageManager sPackageManager;
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
ApplicationPackageManager.java
public class ApplicationPackageManager extends PackageManager {
private final ContextImpl mContext;
private final IPackageManager mPM;
protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
mContext = context;
mPM = pm;
}
}
PackageManagerService.java
public class PackageManagerService extends IPackageManager.Stub implements PackageSender {
}
ABI全程是:Application binary interface,即:应用程序二进制接口,它定义了一套规则,允许编译好的二进制目标代码在所兼容该ABI的操作系统和硬件平台中无需改动就能运行。
参考:
APK安装流程详解0——前言