Как один и тот же код распределяется между двумя процессами в Android? - PullRequest
1 голос
/ 22 февраля 2020

У меня есть класс util в моем android проекте, и он выглядит примерно так:

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());
    }
}

У меня есть служба, которая работает под отдельным процессом (: one) в том же приложении, которое выглядит как-то так,

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();
           }
       };
    }
}

Когда я вызываю printHelloWorld() в классе util из приложения (процесс p1) и в классе обслуживания (процесс p1: one), я могу видеть одно и то же значение mBinder1 объект для печати одинакового значения во всех процессах.

В общем, мы использовали вызов IP C, когда общаемся между процессами. Вот как код утилит распределяется между процессами? Как код распределяется между процессами, когда они находятся в одном приложении?

Я не могу понять. Некоторая помощь в этом отношении была бы действительно полезна.

1 Ответ

2 голосов
/ 09 мая 2020

Экземпляр Binder * не используется всеми процессами.

Хотя экземпляр Binder имеет класс c в классе MyUtil, процессы приложения и службы будут иметь свои собственные копии MyUtil code.

Итак, процесс приложения создает 1 объект stati c для своего класса MyUtil, а сервисный процесс создает еще один объект stati c для своего класса 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");
    }
}

To test, я написал этот 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...