Android面试系列多进程模式的运行机制分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xgangzai/article/details/82421997

几个基本概念

  • Android为每一个应用分配一个独立的虚拟机,或者说每一个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致不同的虚拟机访问同一个类的对象会产生多分副本。
  • Android对每个进程分配了虚拟机,早期的版本虚拟机堆内存只有16M
  • 运行在同一个进程中的组件是属于同一个虚拟机和同一个Application的,也就是说有几个进程,我们在第一次启动的时候就要初始化几个Application,调用几次onCreate方法

为什么要考虑多进程模式实现一些内容?

  • App有些功能模块特殊必须运行在单独的进程中。
  • 为了加大一个应用可以使用的内存,需要多进程来获取多份内存空间。
  • 当前应用需要向其它应用获取数据,两个应用必须使用跨进程方式获取数据。

开启多进程的方式

  • 开启多进程的方法
    1. 对四大组件(Activity,Service,Receiver,ContentProvider)在AndroidMenifest中指定android:process属性
    2. 通过JNI在native层fork一个新的进程
      本篇文章我们只讲解第一种开发多进程的方式
  • 代码
<activity
   android:name="com.koala.demo.MainActivity"
   android:configChanges="orientation!screenSize"
   android:label="@string/app_name"
   android:launchMode="standard">
   <intent-fliter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-fliter>
</activity>

<activity
    android:name="com.koala.demo.SecondActivity"
    android:configChanges="screenLayout"
    android:label="@string/app_name"
    android:process=":remote"/>

<activity
    android:name="com.koala.demo.ThirdActivity"
    android:configChanges="screenLayout"
    android:label="@string/app_name"
    android:process="com.koala.demo.remote"/>
  • 查看进程信息

    shell命令查看:adb shell ps 或者 adb shell ps | com.koala.demo ,其中com.koala.demo是包名

  • 详细分析讲解

    上面的代码,通过查看进程信息,我们开启了三个进程:

    进入的时候MainActivity,com.kaola.demo创建

    SecondActivity启动的时候com.kaola.demo:remote创建

    ThirdActivity启动的时候com.kaola.demo.remote创建

  • :remote和.remote有什么区别呢?

    :的含义当前进程名为签名附带上当前的包名,这是一种简写的方法。进程名以:开头的进程属于当前应用的私有进程,其他应用组件不可以和它跑在同一个进程中,而进程名不以:开头的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一个进程中。

    Android系统为每一个应用分配了一个唯一的UID,具有相同UID的应用才能共享数据。这里要说明的是两个应用通过ShareUID跑在同一个进程是有要求的,需要两个应用具有相同的ShareUID并且签名相同才可以,这种情况下,不管它们是否跑在同一个进程,它们可以互相访问私有数据,比如data目录,组件信息等
    。如果跑在同一个进程中,除了共享data目录,组件信息,还可以共享内存数据,或者说它们看起来就像一个应用的两部分。

使用多进程会造成的问题

  • 静态成员和单例模式完全失效

  • 线程同步机制完全失效

    既然不同的进程已经不是一块内存了,那么不管锁对象还是锁全局类都无法保证线程同步,因为不同进程锁不是同一对象

  • SharePreferences的可靠性下降

    SharePreferences不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失,因为SharePrefeience底层是读/写xml文件来实现的,并发显然是可能有问题的

  • Application会多次创建(可以理解为开启一个进程就要创建一次Application)

参考:《Android开发艺术探索》

猜你喜欢

转载自blog.csdn.net/xgangzai/article/details/82421997
今日推荐