Android中两个进程如何共享相同的代码?

Android中两个进程如何共享相同的代码?,android,process,ipc,aidl,android-binder,Android,Process,Ipc,Aidl,Android Binder,我的android项目中有一个util类,它看起来像这样 public class MyUtil { public static final String TAG = "tim"; static IBinder mIBinder1 = new Binder(); public static void printHelloWorld() { Log.i(TAG, "Just printing hello world from my util" + mIBi

我的android项目中有一个util类,它看起来像这样

public class MyUtil {
    public static final String TAG = "tim";
    static IBinder mIBinder1 = new Binder();

    public static void printHelloWorld() {
        Log.i(TAG, "Just printing hello world from my util" + mIBinder1.toString());
    }
}
public class MyService extends Service {

    public static final String TAG = "tim";

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
       return new IMyAidlInterface.Stub() {

           @Override
           public void printHelloWorld() throws RemoteException {
               Log.i(TAG, "This is just printing hello world");
               MyUtil.printHelloWorld();
           }
       };
    }
}
我有一个服务在同一个应用程序中的单独进程(:1)下运行,看起来像这样

public class MyUtil {
    public static final String TAG = "tim";
    static IBinder mIBinder1 = new Binder();

    public static void printHelloWorld() {
        Log.i(TAG, "Just printing hello world from my util" + mIBinder1.toString());
    }
}
public class MyService extends Service {

    public static final String TAG = "tim";

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
       return new IMyAidlInterface.Stub() {

           @Override
           public void printHelloWorld() throws RemoteException {
               Log.i(TAG, "This is just printing hello world");
               MyUtil.printHelloWorld();
           }
       };
    }
}
当我从应用程序(流程p1)的util类和服务类(流程p1:one)中调用
printHelloWorld()
时,我可以看到
mBinder1
对象的相同值,以便在各个流程中打印相同的值

一般来说,当我们在进程之间进行通信时,我们通常进行IPC调用。这里是如何在进程之间共享util代码的?当进程在同一应用程序中时,它们之间如何共享代码


我不能理解。这方面的一些帮助将非常有用。

绑定器实例在进程之间不是共享的

虽然Binder实例在
MyUtil
类中是静态的, 应用程序和服务流程都有自己的
MyUtil
code副本

因此,应用程序进程为其
MyUtil
类创建一个静态对象, 服务流程为其
MyUtil
类创建另一个静态对象

让我们看看它的实际行动

1。在单独的进程中运行服务

这是AndroidManifest.xml


MyService.java

公共类MyService扩展服务{
私有静态最终字符串TAG=“mytest\u MyService”;
private final IBinder mBinder=new IMyService.Stub(){
@凌驾
public void printHelloWorld()引发RemoteException{
i(标记“这只是打印hello world”);
MyUtil.printHelloWorld();
}
};
@可空
@凌驾
公共IBinder onBind(意向){
返回mBinder;
}
}
MyUtil.java

公共类MyUtil{
私有静态最终字符串TAG=“mytest\u MyUtil”;
私有静态最终IBinder mMyBinder=new MyBinder();
公共静态void printHelloWorld(){
Log.i(标记“刚刚从我的util打印hello world”+mMyBinder.toString());
}
}
MyBinder
只是一个活页夹,它在每次创建对象时都会记录一条消息

MyBinder.java

公共类MyBinder扩展了Binder{
私有静态最终字符串TAG=“mytest\u MyBinder”;
公共MyBinder(){
d(标记“创建MyBinder对象”);
}
}
为了测试,我编写了这个安卓测试

app/src/androidTest/StaticObjectBehaviorTest.java

import org.junit.runner.RunWith;
导入androidx.test.ext.junit.runners.AndroidJUnit4;
导入org.junit.Rule;
导入org.junit.Test;
导入androidx.test.platform.app.InstrumentationRegistry;
@RunWith(AndroidJUnit4.class)
公共类StaticObjectBehaviorTest{
@统治
public final ServiceTestRule mServiceRule=新ServiceTestRule();
@试验
public void objectCreation()引发TimeoutException,RemoteException{
//正在测试的应用程序的上下文。
Context appContext=InstrumentationRegistry.getInstrumentation().getTargetContext();
//在测试应用程序进程中调用MyUtil类。
MyUtil.printHelloWorld();
Intent Intent=新的Intent(appContext,MyService.class);
IBinder binder=mServiceRule.bindService(intent);
assertNotNull(活页夹);
IMyService myService=IMyService.Stub.as接口(活页夹);
assertNotNull(myService);
//使用服务代理在服务流程中调用MyUtil类。
printHelloWorld();
}
}
检查日志

$adb logcat| grep“mytest”
如您所见,每个流程都创建了两个活页夹对象

2。在同一进程中运行服务

只需更改AndroidManifest.xml


没有代码更改

检查日志

$adb logcat| grep“mytest”

在同一进程中运行时,只创建了一个绑定器实例。

但我注意到power manager也是如此,
PowerManager pm=(PowerManager)getSystemService(Context.power\u SERVICE)
当我从任何进程打印
pm.toString
时,它会返回相同的值。我读取的原因是binder在binder驱动程序中分配内存(在内核级别),并且在进程之间共享相同的内存(共享内存)在java对象级别,
toString
方法被重写以提供相同的hashCode值。最初我们讨论的是,在Android应用程序级别,两个不同的进程如何拥有同一类的两个不同副本。但这个问题问的是,同一个Android框架资源在不同进程之间共享在哪里,以及如何共享。如果您为此
PowerManager
ask创建新问题,社区将能够看到您的问题并为您提供满意的答案。我认为你的问题是一个好问题,我将不得不对它进行研究,为你提供答案。