Обнаружение, если вы находитесь в основном процессе или процессе удаленного обслуживания в приложении на Android - PullRequest
3 голосов
/ 05 августа 2011

У меня есть приложение, в котором удаленная служба работает в отдельном процессе:

<service android:name=".MyService" android:process=":remote"/>

Я также использую класс приложения:

<application android:label="@string/app_name" android:name=".MyApplication" ...

Могу ли я сделать что-то вродеэто?

public class MyApplication extends Application {

    public MyApplication() {
        if (isRemoteService()) {
            setupLog("remoteservice.log");
        } else {
            setupLog("application.log");
        }
    }

Я думаю, я мог бы получить имя процесса и использовать его, чтобы определить, нахожусь ли я в удаленной службе или в главном приложении, но я не нашел, как получитьИмя процесса.Я могу получить PID из android.os.Process.myPID (), но это мне мало помогает.

Ответы [ 3 ]

4 голосов
/ 28 марта 2016

Например, если вы хотите проверить, находитесь ли вы в главном процессе, вы можете написать код в своем приложении следующим образом:

public class MyApplication extends Application {
@Override
public void onCreate() {
    //...code here will be execute in every process...
    if (isMainProcess()) {
        //...code here will be execute only in main process
    }
    super.onCreate();
}

// your package name is the same with your main process name
private boolean isMainProcess() {
    return getPackageName().equals(getProcessName());
}

// you can use this method to get current process name, you will get
// name like "com.package.name"(main process name) or "com.package.name:remote"
private String getProcessName() {
    int mypid = android.os.Process.myPid();
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
    for(RunningAppProcessInfo info : infos) {
        if (info.pid == mypid) {
            return info.processName;
        }
    }
    // may never return null
    return null;
}

}

1 голос
/ 28 мая 2013

У меня была похожая проблема, и это то, что я сделал.

MyService и MyActivity имеют общую часть, MyEngine, но в этих двух случаях поведение должно быть немного другим.

Одна вещь, которая отличается от других, - это настройка, но эта настройка выполняется в классах MyService и MyActivity.

Еще одна вещь, которая отличается для активности, и служба выполняется через прослушиватель: MyEngine определяет интерфейс MyEngine.Listener, тогда как MyService и MyActivity предоставляют движку различные реализации этого интерфейса.

Итак, если вы хотите передать логическое значение, возможны два метода:

// Method 1: different initialization
class MyEngine {
    MyEngine(boolean isService) { ... }
}
class MyActivity extends Activity {
    private MyEngine = new MyEngine(false);
    ...
}
class MyService extends Service {
    private MyEngine = new MyEngine(true);
    ...
}

// Method 2: callbacks
class MyEngine {
    interface Listener {
        boolean isService();
    }
    private Listener mListener;
    MyEngine(Listener listener) { mListener = listener; }
}
class MyActivity extends Activity {
    private mListener = new MyEngine.Listener() {
        boolean isService() { return false; }
    }
    private MyEngine = new MyEngine(mListener);
    ...
}
class MyService extends Service {
    private mListener = new MyEngine.Listener() {
        boolean isService() { return true; }
    }
    private MyEngine = new MyEngine(mListener);
    ...
}

Примечание.

  1. Логическое значение, используемое в приведенном выше примере, бесполезно в реальном мире: если вы хотите использовать, скажем, разные имена файлов журнала, лучше передать имя файла, а не логическое. Если вы хотите выполнить два разных действия, лучше иметь одну функцию слушателя с двумя реализациями.

  2. Конечно, можно передать Context и проверить, является ли он дочерним элементом Activity или Service, или получить имя текущего процесса, но эти вещи являются реализацией для Android. детали, и лучше не зависеть от них, если это не является абсолютно необходимым.

1 голос
/ 06 апреля 2013

Могу предложить косвенное решение:

В каждом из соответствующих методов запуска установите системное свойство:

System.setProperty("PROCESS_TYPE","SERVICE");
System.setProperty("PROCESS_TYPE","RECEIVER");
System.setProperty("PROCESS_TYPE","ACTIVITY");

Свойства являются статическими, изолированными от процесса, и могут быть доступны из любого места. Дополнительным преимуществом является то, что они могут напрямую использоваться для каркасов, таких как Logback.

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