Binder 实例不在进程之间共享。
虽然Binder实例在MyUtil类中是静态的,
应用程序和服务进程都有自己的MyUtil 代码副本。
因此,应用进程为其MyUtil 类创建了1 个静态对象,
并且服务进程为其MyUtil 类创建另一个静态对象。
让我们看看它的实际效果。
1.在单独的进程中运行服务
这是 AndroidManifest.xml。
<manifest
package="com.lakindu.staticobjectbehavior">
<application>
<service
android:name=".MyService"
android:process=":myservice" />
</application>
</manifest>
MyService.java
public class MyService extends Service {
private static final String TAG = "mytest_MyService";
private final IBinder mBinder = new IMyService.Stub() {
@Override
public void printHelloWorld() throws RemoteException {
Log.i(TAG, "This is just printing hello world");
MyUtil.printHelloWorld();
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
MyUtil.java
public class MyUtil {
private static final String TAG = "mytest_MyUtil";
private static final IBinder mMyBinder = new MyBinder();
public static void printHelloWorld() {
Log.i(TAG, "Just printing hello world from my util" + mMyBinder.toString());
}
}
MyBinder 只是一个 Binder,每次创建对象时都会记录一条消息。
MyBinder.java
public class MyBinder extends Binder {
private static final String TAG = "mytest_MyBinder";
public MyBinder() {
Log.d(TAG, "Creating MyBinder object");
}
}
为了测试,我编写了这个 Android 仪器测试。
app/src/androidTest/StaticObjectBehaviorTest.java
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import androidx.test.platform.app.InstrumentationRegistry;
@RunWith(AndroidJUnit4.class)
public class StaticObjectBehaviorTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
@Test
public void objectCreation() throws TimeoutException, RemoteException {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
// Calling MyUtil class in test app process.
MyUtil.printHelloWorld();
Intent intent = new Intent(appContext, MyService.class);
IBinder binder = mServiceRule.bindService(intent);
assertNotNull(binder);
IMyService myService = IMyService.Stub.asInterface(binder);
assertNotNull(myService);
// Using service proxy to call MyUtil class in service process.
myService.printHelloWorld();
}
}
检查日志。
$ adb logcat | grep "mytest_"
[PID]
13054 D mytest_MyBinder: Creating MyBinder object
13054 I mytest_MyUtil: Just printing hello world from my utilcom.lakindu.staticobjectbehavior.MyBinder@5c24fc2
13089 I mytest_MyService: This is just printing hello world
13089 D mytest_MyBinder: Creating MyBinder object
13089 I mytest_MyUtil: Just printing hello world from my utilcom.lakindu.staticobjectbehavior.MyBinder@2723e12
如您所见,每个进程都创建了 2 个 Binder 对象。
2。在同一进程中运行服务
只需更改 AndroidManifest.xml。
<manifest
package="com.lakindu.staticobjectbehavior">
<application>
<service
android:name=".MyService" />
</application>
</manifest>
没有代码更改。
检查日志。
$ adb logcat | grep "mytest_"
[PID]
13202 D mytest_MyBinder: Creating MyBinder object
13202 I mytest_MyUtil: Just printing hello world from my utilcom.lakindu.staticobjectbehavior.MyBinder@5c24fc2
13202 I mytest_MyService: This is just printing hello world
13202 I mytest_MyUtil: Just printing hello world from my utilcom.lakindu.staticobjectbehavior.MyBinder@5c24fc2
在同一进程中运行时,只会创建一个 Binder 实例。