Чистая привязка / открепление к Сервису в Приложении - PullRequest
13 голосов
/ 20 февраля 2012

У меня есть приложение Android, которое привязывается к постоянной службе (однажды запущенная с startService()).

Услуга является неотъемлемой частью приложения и, таким образом, используется практически во всех видах деятельности. Поэтому я хочу привязать к сервису только один раз (вместо привязки / отмены привязки в каждом действии) и сохранить привязку в течение срока действия моего приложения.

Я расширился с Приложение и связался с сервисом в Приложение # onCreate () . Однако теперь у меня есть проблема, которую я не знаю, когда мое приложение существует, так как Application # onTerminate () никогда не вызывается, см. JavaDoc:

Этот метод предназначен для использования в эмулируемых средах процессов. Никогда не будет быть вызванным на производственном устройстве Android, где процессы удалены просто убивая их; нет кода пользователя (включая этот обратный вызов) выполняется при этом.

Так как же мне отменить привязку от службы, связанной в приложении?

Ответы [ 3 ]

13 голосов
/ 08 марта 2012

Я решил эту проблему, посчитав ссылки на привязку службы в Application.Каждый Activity должен вызывать acquireBinding() в своих onCreate() методах и вызывать releaseBinding() в onDestroy().Если счетчик ссылок достигает нуля, привязка сбрасывается.

Вот пример:

class MyApp extends Application {
    private final AtomicInteger refCount = new AtomicInteger();
    private Binding binding;

    @Override
    public void onCreate() {
        // create service binding here
    }

    public Binding acquireBinding() {
        refCount.incrementAndGet();
        return binding;
    }

    public void releaseBinding() {
        if (refCount.get() == 0 || refCount.decrementAndGet() == 0) {
            // release binding
        }
    }
}

// Base Activity for all other Activities
abstract class MyBaseActivity extend Activity {
    protected MyApp app;
    protected Binding binding;

    @Override
    public void onCreate(Bundle savedBundleState) {
        super.onCreate(savedBundleState);
        this.app = (MyApp) getApplication();
        this.binding = this.app.acquireBinding();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.app.releaseBinding();
    }
}
4 голосов
/ 01 апреля 2012

Из ответа Свена:

Я решил эту проблему, посчитав ссылки на привязку службы в Приложении.Каждое действие должно вызывать acquBinding () в своих методах onCreate () и вызывать releaseBinding () в onDestroy ().Если счетчик ссылок достигает нуля, привязка освобождается.

Я согласен, НО вам не следует делать это в onDestroy - это часто не будет вызываться.

Вместо этого я предлагаюследующее (на основе вашего примера кода) ...

// Base Activity for all other Activities
abstract class MyBaseActivity extend Activity {
    protected MyApp app;
    protected Binding binding;

    @Override
    public void onCreate(Bundle savedBundleState) {
        super.onCreate(savedBundleState);
        this.app = (MyApp) getApplication();
        this.binding = this.app.acquireBinding();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Pre-HC, activity is killable after this.
        if ((11 > Build.VERSION.SDK_INT) && (isFinishing()))
            onFinishing();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if ((10 < Build.VERSION.SDK_INT) && (isFinishing()))
            onFinishing();
    }

    protected void onFinishing() {
        // Do all activity clean-up here.
        this.app.releaseBinding();          
    }
}

НО, мое использование isFinishing () - всего лишь мысль - я не уверен, что это надежно.Возможно, onPause / onStop вызывается с isFinishing () false, но затем действие уничтожается - и ваш releaseBinding () никогда не вызывается.

Если вы избавляетесь от проверки isFinishing, я думаю, вам нужно переместить acquBinding() вызовите onCreate для onStart / onResume (в зависимости от версии SDK), чтобы убедиться, что ваш счетчик ссылок не испортился.

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

2 голосов
/ 22 ноября 2012

Требуется ли вообще развязывание в этом случае?Приложение все равно будет убито.Я попытался реализовать пример приложения, делая это без отмены привязки, и, похоже, он работает правильно.

...