Android Java静态变量通信和反射的前提是须要在同一进程内

发布时间 2023-08-17 18:09:16作者: 小汀

静态变量通信:
java类中的static变量是属于类的,即使new了两个对象访问的也是同一个内存地址的static变量,也就是说可以通过static变量通信,但前提必须是这两个对象必须是同一个进程中的。

父进程通过fork来复制出一个子进程的副本,根据原理,子进程拥有父进程的一份完整数据拷贝。同时由于fork时按页复制数据太耗时,于是子进程在刚被fork出来的时候,读取的其实是父进程中的内存数据(所以,这时候也可以说静态变量是共享的)但是, 当父子进程中的一方对静态变量(其实不只是静态变量,任何内存中的东西都是这样)进行写入操作时,就会触发写时复制机制,这个变量将在子进程中产生一个新的空间来存放,于是变量不再共享,每个进程的内存空间都是属于它自己的。

 

反射:
java反射机制原理:我们写的源代码是.java文件,通过javac编译后成为.class文件,即字节码文件,程序执行时,JVM会类加载字节码文件到内存,严格意义上说是加载到方法区,并转换成java.lang.Class对象,通过反射,我们可以构建实例,得到成员变量的值,得到方法并调用。
比如 同样是//packages/modules/Wifi/目录下的类,android.net.wifi.WifiManager 可以被反射到,但 com.android.server.wifi.WifiServiceImpl 就无法被反射到。

因为WifiManager是可以通过WifiManager wifiManager = ((WifiManager) mContext.getSystemService(WIFI_SERVICE))在app端进程创建; 但WifiServiceImpl是系统服务,是在android系统启动时被system_server进程创建的对象,和pms、wms、ams等都属于同一个进程号。

 

举例:

在Android中想要跨进程通信也有一些方法比如共享内存、binder通信等等,像上面WifiManager的例子如果想在各个app进程之间进行通信,在WifiManager中增加静态变量或者对WifiManager实现单例模式或直接反射WifiServiceImpl里的静态变量是不行的,推荐使用aidl方式:

WifiManager.java              
IWifiManager.aidl              
BaseWifiService extends IWifiManager.Stub 
WifiServiceImpl extends BaseWifiService

如上结构,通过在WifiManager中实现接口访问WifiServiceImpl的普通变量,即可在多个进程各自生成的WifiManager对象调用接口访问系统进程中WifiServiceImpl对象的一般变量。