Android (Вещи): как выполнить очистку до завершения программы?

У меня есть Raspberry Pi 3 под управлением Android Things. Для простоты предположим, что он вращает только шаговый двигатель.

Чтобы еще раз упростить ситуацию, шаговый двигатель вращается, сообщая катушке за катушкой, какие из них заряжать, а какие нет. В Raspberry Pi вы подключаете четыре выходных контакта к четырем входным контактам шагового двигателя. Затем вы запускаете кегли один за другим в непрерывной последовательности с несколькими миллисекундами между каждым запуском.

Если я остановлю программу в Android Studio, нажав Stop «MainActivity», программный код будет убит, но выходные контакты в Raspberry Pi все равно останутся заряженными. В моем случае, если я остановлю программу в Android Studio, одна из катушек моего шагового двигателя останется заряженной (и перегреется).

ВОПРОС: Как лучше всего выполнить очистку в Android перед завершением работы программы?

Я пробовал onDestroy () и onPause (), но ни один из них не гарантированно будет вызван при закрытии программы. (В моем случае они тоже никогда не работали).

Я также попытался добавить ловушку отключения, но даже это не отключает выходной контакт. Shutdownhook, расположенный в методе onCreate () MainActivity, выглядит следующим образом:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Runtime.getRuntime().addShutdownHook(new Thread(){
        @Override
        public void run(){
            try{
                mRobotics.stopMotor();
            } catch (Exception e){
                // Ignore error
            }
        }
    });
// onCreate continues...

Метод stopMotor () выглядит так:

public void stopMotor(){
    this.motorHandler.removeCallbacksAndMessages(null);
    try {
        mStepper1.setValue(false);
        mStepper2.setValue(false);
        mStepper3.setValue(false);
        mStepper4.setValue(false);

    } catch (Exception e){
        // Nothing here
    }
}

Есть много связанных вопросов, например, об остановке потоков при закрытии программы, но я не нашел в StackOverflow ничего, что работало бы в моем случае.


person Crebit    schedule 02.09.2018    source источник


Ответы (1)


Вы правы, что нажатие кнопки «Стоп» в Android Studio просто завершает процесс вашего приложения без вызова каких-либо методов жизненного цикла. То же самое верно, если ваше приложение дает сбой или Android необходимо завершить работу вашего приложения из-за нехватки памяти, поэтому это может произойти и во время выполнения. Нет никаких зацепок, которые можно было бы добавить, чтобы предвидеть каждый раз, когда это может произойти.

Один из вариантов - переместить логику драйвера двигателя в отдельный модуль приложения и управлять им с помощью привязки сервис. Таким образом, когда основное приложение завершает работу (либо во время разработки, либо из-за сбоя), приложение драйвера может управлять этим соответствующим образом. Разделение кода драйвера и основного приложения таким образом также является хорошим разделением задач.

Вот пример того, как это может выглядеть:

driver.apk

class MotorDriverService : Service() { 

    override fun onCreate() {
        super.onCreate()
        startMotor()
    }

    override fun onDestroy() {
        super.onDestroy()
        stopMotor()
    }
}

main.apk

class MainActivity : Activity() { 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intent = ...
        bindService(intent, connection, Context.BIND_AUTO_CREATE)
    }

    override fun onDestroy() {
        super.onDestroy()
        unbindService(connection)
    }

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) { }

        override fun onServiceDisconnected(name: ComponentName) { }
    }
}

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

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

person devunwired    schedule 03.09.2018
comment
Спасибо! Я даже не догадывался, что Android Things может запускать несколько приложений - person Crebit; 04.09.2018