Java Android(事物):如何在程序结束前进行清理?

Java Android(事物):如何在程序结束前进行清理?,java,android,process,terminate,android-things,Java,Android,Process,Terminate,Android Things,我有一个树莓皮3运行Android的东西。为简单起见,假设它只旋转步进电机 为了再次简化事情,步进电机通过一圈接一圈地告诉线圈哪些要充电,哪些不充电来旋转。在Raspberry Pi中,您将四个输出引脚连接到步进电机的四个输入引脚。然后,在每次运行之间的几毫秒内,以连续顺序逐个启动管脚 如果我在Android Studio中按stop‘MainActivity’停止程序,程序代码将被删除,但Raspberry Pi中的输出引脚仍保持充电状态。在我的例子中,如果我在Android Studio中停

我有一个树莓皮3运行Android的东西。为简单起见,假设它只旋转步进电机

为了再次简化事情,步进电机通过一圈接一圈地告诉线圈哪些要充电,哪些不充电来旋转。在Raspberry Pi中,您将四个输出引脚连接到步进电机的四个输入引脚。然后,在每次运行之间的几毫秒内,以连续顺序逐个启动管脚

如果我在Android Studio中按stop‘MainActivity’停止程序,程序代码将被删除,但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中找到任何适用于我的情况

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

一个选项是将您的电机驱动器逻辑移动到一个单独的应用程序模块中,并通过。这样,当主应用程序终止时(无论是在开发过程中还是由于崩溃),驱动程序应用程序都可以适当地进行管理。通过这种方式将驱动程序代码与主应用程序分离通常也是一种很好的关注点分离

下面是一个可能的示例:

驱动程序.apk

class MotorDriverService : Service() { 

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

    override fun onDestroy() {
        super.onDestroy()
        stopMotor()
    }
}
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) { }
    }
}
main.apk

class MotorDriverService : Service() { 

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

    override fun onDestroy() {
        super.onDestroy()
        stopMotor()
    }
}
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中的活动/服务),因为只有在这两个应用程序在完全独立的进程中运行时,才会起作用。

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

一个选项是将您的电机驱动器逻辑移动到一个单独的应用程序模块中,并通过。这样,当主应用程序终止时(无论是在开发过程中还是由于崩溃),驱动程序应用程序都可以适当地进行管理。通过这种方式将驱动程序代码与主应用程序分离通常也是一种很好的关注点分离

下面是一个可能的示例:

驱动程序.apk

class MotorDriverService : Service() { 

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

    override fun onDestroy() {
        super.onDestroy()
        stopMotor()
    }
}
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) { }
    }
}
main.apk

class MotorDriverService : Service() { 

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

    override fun onDestroy() {
        super.onDestroy()
        stopMotor()
    }
}
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中的活动/服务),因为只有在这两个应用程序在完全独立的进程中运行时,这才有效。

谢谢!我甚至没有意识到Android的东西可以运行多个AppsHanks!我甚至还没有意识到Android可以运行多个应用程序