【问题标题】:Android: How to completely kill a Service running separately as a background process?Android:如何完全杀死作为后台进程单独运行的服务?
【发布时间】:2020-06-02 17:31:25
【问题描述】:

我有一个应用程序,它有一个用作常规 GUI 的 Activity 和一个 Service。我的活动有两个按钮。一键停止进程,一键终止进程。我分别使用这些方法来启动和停止我的进程:

Intent i = null;
Button start;
Button stop;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    i = new Intent(this, Service.class);
    start = (Button) findViewbyId(R.id.start_button);
    stop = (Button) findViewById(R.id.stop_button);

    start.setOnClickListener(new OnClickListener(){

        public void onClick(){
            startService(i);
        }
    }
    stop.setOnClickListener(new OnClickListener(){

        public void onClick(){
            stopService(i);
        }
    }
}

本服务不受活动或应用程序的约束。我在清单中配置了服务:

<service
    android:name="com.example.mypackage.Service"
    android:process=":remote"> 
    <intent-filter>
        <action
            android:name="com.example.mypackage.Service" />
    </intent-filter>
</service>

当我启动服务时,它独立于其他任何东西运行。意思是,当我启动服务并onDestroy() 应用程序时,服务仍在运行。我可以看到它仍在运行,因为通过adb,我运行了ps 命令,它说是。

问题是当我打电话给stopService(intent)。当我从活动端调用stopService(intent) 时,它会运行服务的onDestroy() 中设置的代码行,但是当我运行psadb 时,它说它仍在运行。

我希望能够完全销毁服务。我不确定服务是如何工作的,所以请不要犹豫,谈谈补救措施。我不确定这是否与我在服务中所做的事情有关。谢谢!

编辑: 当我启动服务时,我使用onStartCommand() 并在那里运行一些代码。我也从onStartCommand() 返回START_STICKY。我还尝试返回START_NOT_STICKY,并且在我调用startService(intent) 后服务仍在运行。

【问题讨论】:

  • 你是如何启动你的服务的,我猜在 onStartCommand 方法中,你为你的服务返回了 START_STICKY,那为什么你停止服务后,它会重新启动,尝试返回 START_NOT_STICKY,希望这有帮助.
  • @user2652394 是的,我返回START_STICKY
  • 嗯...你在 onDestroy 方法中调用 super.onDestroy() 吗?
  • Android 设计是为了保留一个可能重复使用的进程。你不应该试图通过杀死操作系统来击败它,除非是在非常不寻常的情况下。主要在 Android 上,您应该期望一些不需要的东西是 inactive不一定是死的
  • @MobileMon - 这是基本的 android 意识,与 Activity 生命周期非常平行,尽管在您的情况下不是 Activity。该进程可以在系统方便的情况下保留或丢弃 - 通常会保留它,除非它所持有的内存用于其他用途。 Android 以某种新颖的方式使用进程和用户等 unix 概念,开发人员需要了解这一点。

标签: android service background-process


【解决方案1】:

如果要强行杀死服务进程,可以使用以下代码:

Process.killProcess(Process.myPid());

【讨论】:

    【解决方案2】:

    调用 stopService 后服务停止。停止后,它们处于非活动状态,但已缓存。

    通过 android 文档,它们变成了 empty process

    不包含任何活动应用程序组件的进程。保持这种进程处于活动状态的唯一原因是出于缓存目的,以便在下次组件需要在其中运行时缩短启动时间。系统通常会杀死这些进程,以平衡进程缓存和底层内核缓存之间的整体系统资源。

    服务将保留在缓存中,直到您的应用再次调用它,否则系统缓存将没有空间供它保留。 RS 命令不知道活动和缓存 dprocess 之间的区别,并且总是显示所有可用的进程。如果您删除:remote,此行为将保持(注意不会创建单独的进程)

    【讨论】:

      【解决方案3】:

      我认为您可以在清单中设置android:exported="false",以便其他应用无法访问该服务,从而启动该服务。我可能需要查看您的代码的完整实现才能完全确定它的原因。我做了同样的事情,而且效果很好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多