Непредсказуемое поведение, вызванное PackageManager.DONT_KILL_APP

В документации API PackageManager.DONT_KILL_APP говорится:

Будьте осторожны при установке этого параметра, так как изменение состояния компонента может сделать поведение содержащего его приложения непредсказуемым.

К сожалению, они не вдаются в подробности того, что они подразумевают под непредсказуемым поведением.

В моем приложении я переключаю включенное состояние активности. Сначала служба включает действие и запускает его:

getPackageManager().setComponentEnabledSetting(
    new ComponentName(MyService.this.getApplicationContext(),
    MyActivity.class),
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
    PackageManager.DONT_KILL_APP);

final Intent launchIntent = new Intent(context, MyActivity.class);
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
        | Intent.FLAG_ACTIVITY_CLEAR_TOP
        | Intent.FLAG_ACTIVITY_SINGLE_TOP);

context.startActivity(launchIntent);

Если активность (single-top) запускается снова или уничтожается, она снова отключается:

@Override
protected void onDestroy() {
    log.d("ON DESTROY");
    super.onDestroy();
    getPackageManager().setComponentEnabledSetting(getComponentName(),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);
}

@Override
protected void onNewIntent(Intent intent) {
    if (someCondition) {
        getPackageManager().setComponentEnabledSetting(getComponentName(),
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

        Intent i = new Intent();
        i.setAction(Intent.ACTION_MAIN);
        i.addCategory(Intent.CATEGORY_HOME);
        startActivity(i);

        finish();
        return;
    }

    super.onNewIntent(intent);
}

Обычно все работает нормально, но иногда объекты нулевые в onResume(), которые созданы в onCreate() и больше нигде не трогались. Мне не удалось восстановить эту проблему в отладчике, но я получаю много отчетов об ошибках с исключениями NullPointerException в onResume(), которые невозможны, если onCreate() действительно вызывался ранее.

Тривиальный пример для этого:

private String s;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    s = new String("");
    ...
}

@Override
protected void onResume() {
    super.onResume();
    ...
    s.equals(""); // rarely causes NullPointerException
    ...
}

Мой вопрос: может ли это быть непредсказуемым поведением PackageManager.DONT_KILL_APP? Или у кого-нибудь есть другая идея, как это может произойти?


person Arthur Dent    schedule 19.02.2013    source источник
comment
Помните, что вызов onDestroy не гарантируется, см.: stackoverflow.com/a/19608985/562139. Вместо этого я бы переместил любую логику поддержания состояния в onStop.   -  person scorpiodawg    schedule 22.12.2016


Ответы (1)


Да, в значительной степени, хотя вы не хотите, чтобы приложение было убито, иногда Системе требуется память и она уничтожает некоторые объекты. Само приложение все еще существует и будет вызывать только onResume(), но не имеет всех объектов, которые оно создало ранее.

person Yalla T.    schedule 19.02.2013
comment
Это объяснило бы мои проблемы. Знаете ли вы, есть ли какая-либо официальная документация по этому поводу, или у вас есть какие-либо ссылки на справочную информацию, объясняющую такое поведение? Если это правильно, это поможет создавать объекты в onResume вместо onCreate. Я попробую это, но, к сожалению, мне придется дождаться следующего выпуска, чтобы увидеть, работает ли он, потому что даже при массовом тестировании проблема никогда не появлялась на моих устройствах. - person Arthur Dent; 19.02.2013