Android(内容):如何在程序结束前进行清理?

时间:2018-09-02 16:12:53

标签: java android process terminate android-things

我有一个运行Android Things的Raspberry Pi 3。为简单起见,假设它仅旋转步进电机。

为简化起见,步进电机通过逐个线圈告诉哪个要充电和哪个不充电来旋转。在Raspberry Pi中,您将四个输出引脚连接到步进电机的四个输入引脚。然后,以连续的顺序逐个触发引脚,每次运行之间间隔几毫秒。

如果我通过按Stop'MainActivity'停止了Android Studio中的程序,程序代码将被杀死,但Raspberry Pi中的输出引脚仍保持充电状态。就我而言,如果我在Android Studio中停止该程序,则我的步进电机线圈之一仍保持充电状态(并且过热)。

问题:在程序关闭之前,在Android中进行清理的最佳方法是什么?

我已经尝试过onDestroy()和onPause(),但不能保证在程序关闭时都不会调用它们。 (在我看来,他们也从未工作过)。

我也试图添加一个关闭钩子,但即使这样也不会关闭输出引脚。位于MainActivity的onCreate()方法中的shutdownhook如下所示:

@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 :(得分:4)

您是正确的,只需在Android Studio中单击“停止”按钮即可终止应用程序进程,而无需调用任何生命周期方法。如果您的应用程序崩溃或Android由于内存压力而需要终止应用程序,情况也是如此,因此在运行时也会发生这种情况。您可以添加钩子来预测每次可能发生的情况。

一种选择是将电动机驱动器逻辑移到单独的应用程序模块中,然后通过bound service对其进行控制。这样,当主应用程序终止时(在开发过程中或由于崩溃而终止),驱动程序应用程序可以对其进行适当的管理。通常,以这种方式将驱动程序代码与主应用程序分开也可以很好地解决问题。

这是一个可能看起来像的例子:

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会创建服务,而在没有更多客户端绑定时,Android将销毁该服务(在这种情况下,也会在main.apk中终止或崩溃)。

驱动程序和主程序必须是两个单独的应用程序(不是同一APK中的一项活动/服务),因为只有当这两个程序在完全独立的进程中运行时,这才起作用。