Android (Вещи): Как выполнить очистку перед завершением программы? - PullRequest
0 голосов
/ 02 сентября 2018

У меня 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, которое бы работало в моем случае.

1 Ответ

0 голосов
/ 03 сентября 2018

Вы правы, что нажатие кнопки «Стоп» в 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, завершается или вылетает).

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

...