美文网首页android
IPC 基础一 概念和多进程模式

IPC 基础一 概念和多进程模式

作者: 静享时光 | 来源:发表于2020-04-25 13:04 被阅读0次

IPC简介

IPC是Inter-process communication的缩写,含义是进程间通信或者叫跨进程通信,是指两个进程间进行数据交换的过程。

进程和线程。

1、线程:
线程是CPU调度的最小单眼,线程是一种有限的系统资源。
2、进程:
进程指的是一个执行单元,在PC或移动设备上指一个程序或者一个应用。
3、进程和线程的关系:
一个进程可以包含多个线程。但是一个进程中最多只能包含一个主线程,也就是UI线程。在主线程中不能进行耗时的操作,否则会导致应用无响应,也就是ANR(Application Not Responding),所以需要把一些耗时的操作放在子线程中执行。

Android中的多进程模式

开启多进程模式

正常情况下,在Android中多进程是指一个应用中存在多个进程的情况,所以下面讨论的大都是一个应用下的多个进程之间的通信。

Android中开启多进程的方式

1、在AndroidMenifest.xml文件中注册四大组件(Activity,Service,BroadCastReceiver,ContentProvider)时指定Android:process属性
2、通过JNI在native层去fork一个新的进程。这种方式是非常规的多进程方法,不是常用的创建多进程的方式。

创建多进程:

<activity android:name=".ipc_demo2.IpcEntryActivity" />
<activity
    android:name=".ipc_demo2.OneActivity"
    android:process=":remote" />
<activity
    android:name=".ipc_demo2.TwoActivity"
    android:process="com.ipc_demo2.remote" />

上面的例子分别为OneActivity和TwoActivity指定了process属性,并且它们的属性值不同,也就是说为当前应用开启了两个新的进程。注意,如果没有指定process就是工作在默认进程中,默认进程的进程名是包名。
上面在指定OneActivity和TwoActivity的process属性时使用的方法是不一样的。android:process=":remote"这种用“:”的方式是指要在当前的进程名前面附加上当前的包名,这是一种简写的方式; android:process="com.ipc_demo2.remote"这种是完整的命名方式,不会附加包名信息。另外需要注意的是“:”这种方式开启的进程属于当前应用的私有进程,其他应用组件不可以和它跑在同一个进程中,而不用“:”开启的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一个进程中。

我们看下日志,会更清晰:


图片1.png
获取进程id和进程名

    /**
     * 获取进程信息
     */
    private void getProcessInfo() {
        // 获取活动管理器
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        // 获取正在运行的进程信息
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
        // 遍历所有 进程
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
            // 进程名字 一般和包名一样
            String processName = runningAppProcessInfo.processName;
            // 进程的id
            int pid = runningAppProcessInfo.pid;
            Log.e("进程间通信", "IpcEntryActivity processName: " + processName + " pid: " + pid);
        }
    }
通过ShareUID实现两个APP之间的通信

通过ShareUID实现两个APP之间通信最基本的要求就是两个APP的ShareUID相同。
如何设置ShareUID?


图片二.png

以共享res文件为例来进行说明

   /**
     * 获取其他app的res资源并且显示--以图片为例
     */
    private void showOtherAppImage() {
        try {
            //通过包名获取其他应用的context对象
            Context packageContext = createPackageContext("com.example.jinghuang.demo2020", Context.CONTEXT_IGNORE_SECURITY);
            if (packageContext != null) {
                //获取其他应用的Resource对象
                Resources resources = packageContext.getResources();
                //getIdentifier方法的第一个参数是资源名(注意不要带文件后缀),
                // 第二个参数是资源类型,如果在drawable文件夹中就传入drawable,如果是mipmap文件夹中就传入mipmap
                //第三个参数是包名
                int resourceId = resources.getIdentifier("ic_launcher", "mipmap", "com.example.jinghuang.demo2020");
                Drawable drawable = resources.getDrawable(resourceId);
                imageIV.setBackgroundDrawable(drawable);
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

当然,通过shareUID还可以共享其他的数据资源,例如数据库数据等,再这里就不过多介绍了

多进程模式的运行机制以及问题

我们都知道Android为每一个应用分配了一个独立的虚拟机,或者说为每个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同一个类的对象会产生多个副本。
下面我们来看下多进程之间会有什么问题呢?
1、静态成员和单例模式完全失效
2、线程同步机制失效
因为不是在一块内存了,所以不管是锁对象合适锁全局类都无法保证线程同步,因为不同进程所得不是同一个对象。
3、SharedPreferences的可靠性下降
4、Application会多次被闯将。
当一个组件到一个新的进程中的时候,由于系统要在创建新的进程汇总同事分配独立的虚拟机,所以这个过程其实就是启动一个应用的过程。因此,相当于系统又把这个应用重新启动了一遍,既然重新启动了,那么自然会创建新的Application。其实可以这么理解,运行在同一个进程中的组件属于同一个虚拟机和同一个Application,运行在不同进程中的组件是属于两个不同的虚拟机和Application。

相关文章

网友评论

    本文标题:IPC 基础一 概念和多进程模式

    本文链接:https://www.haomeiwen.com/subject/dxnhwhtx.html