Android高级-架构师-PMS源码解析以及apk安装原理(反向推理)

PMS指的是PackageManagerService 

1:什么是PMS   即PackageManagerService

PackageManagerService 负责应用程序的安装,卸载,应用信息查询

     

一个应用对应一个包

PackageManagerService 类关系图

 

下图的左侧是Client端,其余的右侧是Servier端

 

从上层调用的时候,Android studio中写一个测试方法

    try {
            context.getPackageManager().getPackageInfo("", 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

 这里的context.getPackageManager返回的是PackageManager,然后我们在搜索一下PackageManager,他是一个抽象类,里面有很多抽象方法。

public abstract class PackageManager {

 public abstract PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags)
            throws NameNotFoundException;


    @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
    public abstract PackageInfo getPackageInfoAsUser(String packageName,
            @PackageInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException;

  
    public abstract String[] currentToCanonicalPackageNames(String[] names);


    public abstract String[] canonicalToCurrentPackageNames(String[] names);


    public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName);
//省略.....
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

我们怎么才能知道他的实现类是什么?

接着我们再搜索ApplicationPackageManager

public class ApplicationPackageManager extends PackageManager {
//重写PackageManager中的所有抽象方法

    @Override
    public PackageInfo getPackageInfo(String packageName, int flags)
            throws NameNotFoundException {
        return getPackageInfoAsUser(packageName, flags, mContext.getUserId());
    }

    @Override
    public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
            throws NameNotFoundException {
        try {
            PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage, flags,
                    mContext.getUserId());
            if (pi != null) {
                return pi;
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        throw new NameNotFoundException(versionedPackage.toString());
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

//这里我们重点看一下 他是如何拿到ApplicationPackageManager ,因为只有拿到它,才能获取到Server端中定义的那些内容 

我们主要看一下这个方法,我们知道PackageManager的实现类是ApplicationPackageManager,所以我们去这里找一下这个方法,

后我们找到了 mPM这个变量。

    private final IPackageManager mPM;
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

IPackageManager 无法查看源码,我们去android的源码查看一下

位置:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

是一个aidl文件,我们练习AIDL的时候知道,客户端和服务端都需要实现AIDL文件,点击运行的时候都会默认生成一个Stub的实现类和Proxy代理类,

interface IPackageManager {
    void checkPackageStartable(String packageName, int userId);
    boolean isPackageAvailable(String packageName, int userId);
    PackageInfo getPackageInfo(String packageName, int flags, int userId);
    PackageInfo getPackageInfoVersioned(in VersionedPackage versionedPackage,
            int flags, int userId);
//省略,。。。。。

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 类似于这样,

public interface MyIPackageManager extends android.os.IInterface {
    
    public static abstract class Stub extends android.os.Binder implements com.asyn.task.mypmsdemo.MyIPackageManager {
        private static final java.lang.String DESCRIPTOR = "com.asyn.task.mypmsdemo.MyIPackageManager";
       
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }
     
        public static com.asyn.task.mypmsdemo.MyIPackageManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.asyn.task.mypmsdemo.MyIPackageManager))) {
                return ((com.asyn.task.mypmsdemo.MyIPackageManager) iin);
            }
            return new com.asyn.task.mypmsdemo.MyIPackageManager.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
           //省略
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.asyn.task.mypmsdemo.MyIPackageManager {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException {
                
                  //省略
                    mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);
                    //省略
                return _result;
            }
        }

        static final int TRANSACTION_getPackageInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }

    public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException;
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 //

   // 服务连接
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iLogin = ILoginInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 开始调用mPM中的方法,而mPm又是一个aidl文件,从以前的文章中我们知道,Server向Binder声明注册成为ServerManager的时候,会现在本地创建一个Binder对象,并起名字,然后再将binder对象的引用和名字打包发送给ServerManager,插入链表结构。所以当Client端通过ServiceConnection连接服务器的时候,通过回调asInterface方法,将当前的Ibinder对象

 

aidl分两部分:

server端需要提供一个Interface 向外说明自己能够提供哪些方法,实现哪些功能

build后,发现编译器已经帮我们实现了IPackageManager.Stub,里面包括像client提供的

asInterface
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
例子   
  public static com.netease.binder.ILoginInterface asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.netease.binder.ILoginInterface))) {
                return ((com.netease.binder.ILoginInterface) iin);
            }
            return new com.netease.binder.ILoginInterface.Stub.Proxy(obj);
        }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

方法,通过queryLocalInterface查询是否是本地的指向Java  Binder对象的原始本机指针。如果有就返回本地指针,如果没有就返回代理对象。

然后我们再次回到上面的图:

 

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用到mPM这一层,就已经到了Servier端,我们看一下是如何调用到这里的。

我们从源码层拷贝一下

IPackageManager
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

interface MyIPackageManager {

    PackageInfo getPackageInfo(String packageName, int flags, int userId);

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

然后我们运行一下,在MainActivity中写个变量,然后进入源码查看这个方法:

public interface MyIPackageManager extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.asyn.task.mypmsdemo.MyIPackageManager {
        private static final java.lang.String DESCRIPTOR = "com.asyn.task.mypmsdemo.MyIPackageManager";

        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an com.asyn.task.mypmsdemo.MyIPackageManager interface,
         * generating a proxy if needed.
         */
        public static com.asyn.task.mypmsdemo.MyIPackageManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.asyn.task.mypmsdemo.MyIPackageManager))) {
                return ((com.asyn.task.mypmsdemo.MyIPackageManager) iin);
            }
            return new com.asyn.task.mypmsdemo.MyIPackageManager.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_getPackageInfo: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    int _arg1;
                    _arg1 = data.readInt();
                    int _arg2;
                    _arg2 = data.readInt();
                    android.content.pm.PackageInfo _result = this.getPackageInfo(_arg0, _arg1, _arg2);
                    reply.writeNoException();
                    if ((_result != null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    } else {
                        reply.writeInt(0);
                    }
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.asyn.task.mypmsdemo.MyIPackageManager {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                android.content.pm.PackageInfo _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(packageName);
                    _data.writeInt(flags);
                    _data.writeInt(userId);
                    mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);
                    _reply.readException();
                    if ((0 != _reply.readInt())) {
                        _result = android.content.pm.PackageInfo.CREATOR.createFromParcel(_reply);
                    } else {
                        _result = null;
                    }
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_getPackageInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }

    public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException;
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

我们分析一下这个类,MyIPackageManager 里面我们找到了getPackageInfo方法,我们知道MyIPackageManager是一个接口方法,那么它的实现方法是谁,是Proxy,我们看到Proxy实现了getPackageInfo这个方法,而这个方法最后调用了

private android.os.IBinder mRemote;
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
而Stub是IBinder的实现类
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
这个是客户端通过Binder发送远程请求,我们接着看它法发送到了哪里
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

我们从上面找到了Stub,这个里面实现了

onTransact

方法,我们再次看上图

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

通过代理方法发送远程请求发送出去以后,我们开始找接收方, 找到源码

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

我们发现PackageManagerService的类属性:

public class PackageManagerService extends IPackageManager.Stub implements PackageSender {

这里面有getPackageInfo方法

 @Override
    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
                flags, Binder.getCallingUid(), userId);
    }

    @Override
    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
            int flags, int userId) {
        return getPackageInfoInternal(versionedPackage.getPackageName(),
                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
    }

    /**
     * Important: The provided filterCallingUid is used exclusively to filter out packages
     * that can be seen based on user state. It's typically the original caller uid prior
     * to clearing. Because it can only be provided by trusted code, it's value can be
     * trusted and will be used as-is; unlike userId which will be validated by this method.
     */
    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
            int flags, int filterCallingUid, int userId) {
        if (!sUserManager.exists(userId)) return null;
        flags = updateFlagsForPackage(flags, userId, packageName);
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                false /* requireFullPermission */, false /* checkShell */, "get package info");

        // reader
        synchronized (mPackages) {
            // Normalize package name to handle renamed packages and static libs
            packageName = resolveInternalPackageNameLPr(packageName, versionCode);

            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
            if (matchFactoryOnly) {
                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
                if (ps != null) {
                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                        return null;
                    }
                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                        return null;
                    }
                    return generatePackageInfo(ps, flags, userId);
                }
            }

            PackageParser.Package p = mPackages.get(packageName);
            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
                return null;
            }
            if (DEBUG_PACKAGE_INFO)
                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
            if (p != null) {
                final PackageSetting ps = (PackageSetting) p.mExtras;
                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                    return null;
                }
                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
                    return null;
                }
                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
            }
            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps == null) return null;
                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                    return null;
                }
                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                    return null;
                }
                return generatePackageInfo(ps, flags, userId);
            }
        }
        return null;
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

到这为止,就已经将数据和请求发送到了服务端。

我们复习一下:

5:Binder的四个重要的对象

1:IBinder:是一个接口,代表跨进程通讯的能力或者功能,只要实现这个接口就可以跨进程传输了

2:IInterface:代表Server进程对象代表能够提供什么样的功能,什么样的方法,对应的就是AIDL定义的接口。

3:Binder:java层的Binder类,代表的就是Binder的本地对象,这里需要;了解这个BinderProxy,我们需要一个本地的代理来操    作Binder,通过BinderProxy来操作Binder。

4:Stub:就是Aidl的时候,编译工具会自动生成一个stub的静态内部类,他是继承了Binder,实现了IInterface的接口,表明具备了服务端对Clinet承诺接口的能力。他是一个抽象类,具体的实现需要我们自己去做

我们从上层调用了getPackageManager()方法,调用了PackageManager的子类的ApplicationPackageManager的getPackageInfo()方法,getPackageInfo通过代理对象来操控Binder,即将数据发送给服务端,而getPackageInfo就调用了Proxy代理类中的

mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);方法,
mRemote又是  private android.os.IBinder mRemote;  实现了跨进程传输的能力。
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

之后我们找到PackageManagerService,发现它是继承IPackageManager.Stub,即我们自定义的MyIPackageManager,这样通信就被建立起来了。



2:Apk安装原理

界面安装分为有界面安装和无界面安装

有界面安装

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

有界面安装,调用的是PackageInstallerActivity

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

我们从源码分析一下

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  private void startInstall() {
        // Start subactivity to actually install the application
        Intent newIntent = new Intent();
        newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
                mPkgInfo.applicationInfo);
        newIntent.setData(mPackageURI);
        newIntent.setClass(this, InstallInstalling.class);
        String installerPackageName = getIntent().getStringExtra(
                Intent.EXTRA_INSTALLER_PACKAGE_NAME);
        if (mOriginatingURI != null) {
            newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
        }
        if (mReferrerURI != null) {
            newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
        }
        if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
            newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
        }
        if (installerPackageName != null) {
            newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
                    installerPackageName);
        }
        if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
            newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
        }
        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
        startActivity(newIntent);
        finish();
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

2:无界面安装,就是通过adb  push

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

调用的是C的代码,

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==



int adb_commandline(int argc, const char** argv) {
    int no_daemon = 0;
//省略..

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

static int install_app(int argc, const char** argv);
static int install_multiple_app(int argc, const char** argv);
static int uninstall_app(int argc, const char** argv);
static int install_app_legacy(int argc, const char** argv);
static int uninstall_app_legacy(int argc, const char** argv);
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

这里有安装和卸载的方法

因为我们知道上层调用到了PackageManagerService,我们来看一下

    @Override
    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
            int installFlags, String installerPackageName, int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);

        final int callingUid = Binder.getCallingUid();
        enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");

        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
            try {
                if (observer != null) {
                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
                }
            } catch (RemoteException re) {
            }
            return;
        }

        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
            installFlags |= PackageManager.INSTALL_FROM_ADB;

        } else {
            // Caller holds INSTALL_PACKAGES permission, so we're less strict
            // about installerPackageName.

            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
        }

        UserHandle user;
        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
            user = UserHandle.ALL;
        } else {
            user = new UserHandle(userId);
        }

        // Only system components can circumvent runtime permissions when installing.
        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
                && mContext.checkCallingOrSelfPermission(Manifest.permission
                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
            throw new SecurityException("You need the "
                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
        }

        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
            throw new IllegalArgumentException(
                    "New installs into ASEC containers no longer supported");
        }

        final File originFile = new File(originPath);
        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final VerificationInfo verificationInfo = new VerificationInfo(
                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
                null /*packageAbiOverride*/, null /*grantedPermissions*/,
                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));

        mHandler.sendMessage(msg);
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== uploading.gif转存失败 重新上传 取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消 wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

总结:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==uploading.4e448015.gif转存失败重新上传取消wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

Apk的安装原理

安装其实就是把apk文件copy到了对应的目录:

1:data/app/包名-------安装时apk文件复制到此目录,---可以将文件取出并安装,和我们本身的apk一样。

data/data/packagename/(test.apk)

2 :data/data/包名----开辟存放应用程序的文件数据的文件夹,包括i哦应用的so库,缓存文件等等

data/data/packagename/(db,cache)

3:将apk中的dex文件安装到data/dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小为原始apk文件大小的1/4

data/dalvik-cache/(profiles.x86)

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值