美文网首页
2.2 android中的多进程机制

2.2 android中的多进程机制

作者: 武安长空 | 来源:发表于2016-06-15 10:09 被阅读58次

    1. 在android中创建多进程

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name="._2activity.SecondActivity"
        android:process=":remote" />
    <activity
        android:name="._2activity.ThirdActivity"
        android:process="qingfengmy.developmentofart.remote"></activity>
    

    然后在mainActivity中启动SecondActivity,在SecondActivity中启动ThirdActivity。
    cmd中敲命令查看当前进程如下:

    127|root@vbox86p:/ # ps | grep qingfengmy
    u0_a61    1721  97    1004236 54184 ffffffff b76faf75 S qingfengmy.developmentofart
    u0_a61    1754  97    1004236 53908 ffffffff b76faf75 S qingfengmy.developmentofart:remote
    u0_a61    1786  97    1007356 54200 ffffffff b76faf75 S qingfengmy.developmentofart.remote
    

    可以看到有三个进程。默认进程qingfengmy.developmentofart。两个新进程qingfengmy.developmentofart:remote和qingfengmy.developmentofart.remote。
    其中,以":"开头的进程表示当前应用的私有进程,其他应用组件不可以和它跑在同一进程中,而进程名不以":"开头的进程属于全局进程,其他应用通过shareUID方式可以和它跑在同一进程中。
    扩展:android系统会为每一个应用分配一个唯一的UID,具有相同UID的应用才能共享数据,而且两个应用的签名相同才可以。这种情况下,他们可以互相访问对方私有数据,如data目录,组件信息等。
    再看栈内情况(使用adb shell dumpsys activity):

    Running activities (most recent first):
          TaskRecord{2dda218f #179 A=qingfengmy.developmentofart U=0 sz=3}
            Run #2: ActivityRecord{2bfdd409 u0 qingfengmy.developmentofart/._2activi
    ty.ThirdActivity t179}
            Run #1: ActivityRecord{150eaa0c u0 qingfengmy.developmentofart/._2activi
    ty.SecondActivity t179}
            Run #0: ActivityRecord{2dcd1047 u0 qingfengmy.developmentofart/.MainActi
    vity t179}
    

    可见虽然不在一个进程,但还是在一个任务栈中。

    2. 开启多进程后的问题

    项目中新建一个数据类

    public class UserManager {
        public static int sUserId = 1;
    }
    

    MainActivity中设置sUserId=2

    UserManager.sUserId = 2;
    

    SecondActivity中打印sUserId的值

    Log.e("aaa","sUserId="+UserManager.sUserId);
    

    打印结果是1.为什么呢?
    android为每一个应用都分配了一个独立的虚拟机,或者说为每一个进程都分配了一个虚拟机。不同的虚拟机在内存分配上有不同的地址空间。这就导致了不同的虚拟机中访问同一个类的对象会产生多份副本。如上面的例子,两个进程的虚拟机中都有一个UserManager类,修改当前UserManager类只会对当前进程产生影响,不影响其他进程中的userManager。从而导致上面的问题。

    3. 开启多进程的其他问题

      1. 静态成员和单例模式失效
        这个问题上面已经举例说明了。
      1. 线程同步机制完全失效
        既然都不是同一块内存,锁对象和锁全局都无法保证线程安全。
      1. SharedPreferences的可靠性下降
        多进程同时并发读写肯定会造成问题。
      1. Application会多次创建
        当一个组件跑在一个新的进程中时,由于系统要创建新的进程同时分配独立的虚拟机,所以这个过程其实是启动一个应用的过程,既然重新启动应用,肯定会创建新的Application。

    实例如下:Applicaion的onCreate中打印当前进程的名称。

    @Override
    public void onCreate() {
        super.onCreate();
        String processName = getCurProcessName(this);
        Log.e("aaa",processName);
    }
    String getCurProcessName(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager mActivityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
                .getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
    
                return appProcess.processName;
            }
        }
        return null;
    }
    

    结果:可见onCreate执行了三次。

    06-14 22:03:25.787 27760-27760/qingfengmy.developmentofart E/aaa: qingfengmy.developmentofart
    06-14 22:03:26.038 27782-27782/? E/aaa: qingfengmy.developmentofart:remote
    06-14 22:03:26.418 27814-27814/? E/aaa: qingfengmy.developmentofart.remote
    

    相关文章

      网友评论

          本文标题:2.2 android中的多进程机制

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