android ipc通讯基础疑问点一

来源:互联网 发布:博雅软件集团多少人 编辑:程序博客网 时间:2024/05/24 05:53

一。多进程问题:
1.四大组件只能通过android:process=”:remote”属性这一种方式实现多进程;
进程名以“:”开头的进程属于当前应用的私有进程,其他应用的组件不可以和它泡在同一个进程中,而进程名不以“:”开头的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一个进程中。
2.每个应用分配了一个独立的虚拟机,或者说为每个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同一个类的对象会产生多份副本。所以在一个app中同一个类的静态变量在不同进程的activity中赋值互不影响。。所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败,这也是多进程所带来的主要影响。
一般来说,使用多进程会造成如下几方面的问题:
1).静态成员和单例模式完全失效;
2).线程同步机制完全失效;
3).SharedPreferences的可靠性下降;
4).Application会多次创建。
为了解决这个问题,系统提供了很多跨进程通信方法,虽然说不能直接的共享内存,但是通过跨进程通信我们还是可以实现数据交互。方式有:
Intent传递数据,共享文件和SharedPreferences,基于Binder的Messenger和AIDL以及Socket。
更好的理解各种IPC方式,需要熟悉基础的Serializable和Parceable接口以及Binder的概念。

二。IPC基础概念疑惑
1).Serializable的transient关键字
转载–http://www.cnblogs.com/liuling/archive/2013/05/05/transient.html

1、transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。
2、被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
3、一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。

如下面的例子

package com.kkoolerter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class Main implements Serializable {

private static final long serialVersionUID = -5836283489677344417L;private transient int classValue = 10;private transient Date date = new Date();private transient static int staticValue = 10;public static void main(String[] args) throws Exception {    Main m = new Main();    m.classValue = 11;    Main.staticValue = 11;    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(            new File("0xjh000")));    out.writeObject(m);    out.close();    ObjectInputStream in = new ObjectInputStream(new FileInputStream(            new File("0xjh000")));    Main m1 = (Main) in.readObject();    in.close();    System.out.println(m1.classValue);    System.out.println((m1.date == null ? "date is null"            : "date is not null"));}

}

程序将输出:
0
date is null

这就说明了一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

思考一下下面的例子:
package com.kkoolerter;

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class ExternalizableTest implements Externalizable {

private transient String content = "哈哈~我将会被序列化,不管我是是否被transient关键字修饰";@Overridepublic void writeExternal(ObjectOutput out) throws IOException {    out.writeObject(content);}@Overridepublic void readExternal(ObjectInput in) throws IOException,        ClassNotFoundException {    content = (String) in.readObject();}public static void main(String[] args) throws Exception {    ExternalizableTest et = new ExternalizableTest();    ObjectOutput out = new ObjectOutputStream(new FileOutputStream(            new File("ext0000")));    out.writeObject(et);    ObjectInput in = new ObjectInputStream(new FileInputStream(new File(            "ext0000")));    ExternalizableTest et1 = (ExternalizableTest) in.readObject();    System.out.println(et1.content);    out.close();    in.close();}

}

程序运行后将输出如下结果:
哈哈~我将会被序列化,不管我是是否被transient关键字修饰

这是为什么呢,不是说类的变量被transient关键字修饰以后将不能序列化了吗?
我们知道在Java中,对象的序列化可以通过实现两种接口来实现,若操作的是一个Serializable对象,则所有的序列化将会自动进行,若操作的是 一个Externalizable对象,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。因此第二个例子输出的是变量content初始化的内容,而不是null。

0 0
原创粉丝点击