You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中如何停止已启动的第三方应用Activity并重启?

问题:无法停止并重启第三方应用

我有两个应用,第一个应用启动第二个应用后,需要每隔10秒停止该应用并重新启动。目前第一个应用能成功启动第二个应用,但无法停止它——日志显示每10秒都在执行启动操作,但第二个应用一直处于运行状态,没有被停止或重启。

原代码

package com.example.launch

import android.content.ActivityNotFoundException
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onResume() {
        super.onResume()
        val launchIntent = packageManager.getLaunchIntentForPackage("com.example.secondapp")
        while (true) {
            if (launchIntent != null) {
                try {
                    startActivityForResult(launchIntent, 1)
                    Log.d("", "Launching com.example.secondapp")
                } catch (e: ActivityNotFoundException) {
                    Log.d("", "Failed to launch com.example.secondapp")
                }
            } else {
                Log.d("", "Intent is null value.")
            }
            Thread.sleep(10000)
            finishActivity(1)
        }
    }
}

日志输出

2022-10-28 00:17:58.127 21240-21240/com.example.launch D/: Launching com.example.secondapp
2022-10-28 00:18:08.140 21240-21240/com.example.launch D/: Launching com.example.secondapp
2022-10-28 00:18:18.150 21240-21240/com.example.launch D/: Launching com.example.secondapp

错误原因分析

  1. finishActivity()无法终止跨应用Activity:finishActivity(requestCode)只能终止当前应用任务栈中、由自身通过startActivityForResult启动的Activity。第二个应用的Activity属于独立的任务栈,不在当前应用的控制范围内,因此这个调用完全无效。
  2. 主线程被阻塞:while(true)结合Thread.sleep(10000)直接阻塞了onResume所在的主线程,不仅会引发ANR(应用无响应),还会导致代码逻辑执行异常——主线程被挂起时,后续的finishActivity无法及时执行,且重复启动的操作会不断创建第二个应用的新实例。
  3. Intent复用问题:重复使用同一个launchIntent可能导致启动行为不符合预期,每次启动应确保Intent的flag设置正确(比如添加FLAG_ACTIVITY_NEW_TASK)。

修复方案

1. 添加必要权限

在AndroidManifest.xml中添加权限:

<!-- 用于结束后台进程 -->
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<!-- Android 11及以上需要查询应用信息的权限 -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- 或者针对特定包声明查询权限(更合规) -->
<queries>
    <package android:name="com.example.secondapp" />
</queries>

2. 替换阻塞式循环为定时任务

使用Handler实现非阻塞的定时逻辑,同时通过ActivityManager结束目标应用的任务。

修复后的代码

package com.example.launch

import android.app.ActivityManager
import android.content.ActivityNotFoundException
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log

class MainActivity : AppCompatActivity() {
    private val handler = Handler(Looper.getMainLooper())
    private val targetPackage = "com.example.secondapp"
    private lateinit var runnable: Runnable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 定义定时任务逻辑
        runnable = Runnable {
            stopTargetApp()
            startTargetApp()
            // 10秒后重复执行
            handler.postDelayed(runnable, 10000)
        }
    }

    override fun onResume() {
        super.onResume()
        // 启动定时任务
        handler.post(runnable)
    }

    override fun onPause() {
        super.onPause()
        // 暂停定时任务,避免后台继续执行
        handler.removeCallbacks(runnable)
    }

    private fun startTargetApp() {
        val launchIntent = packageManager.getLaunchIntentForPackage(targetPackage)?.apply {
            // 添加FLAG确保启动新任务
            addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        if (launchIntent != null) {
            try {
                startActivity(launchIntent)
                Log.d("LaunchApp", "Launching $targetPackage")
            } catch (e: ActivityNotFoundException) {
                Log.d("LaunchApp", "Failed to launch $targetPackage: ${e.message}")
            }
        } else {
            Log.d("LaunchApp", "Intent for $targetPackage is null")
        }
    }

    private fun stopTargetApp() {
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        // 结束目标应用的所有任务
        activityManager.killBackgroundProcesses(targetPackage)
    }
}

注意事项

  • 权限限制:killBackgroundProcesses只能结束应用的后台进程,若目标应用处于前台,可能需要结合其他逻辑判断;forceStopPackage需要系统级权限,普通应用无法调用。
  • 后台运行限制:Android 6.0+的Doze模式和后台限制可能影响定时任务执行,若需后台持续运行,可申请REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限。
  • 合规性:QUERY_ALL_PACKAGES权限在Google Play审核时需说明用途,优先使用<queries>声明特定包的查询权限更合规。

内容的提问来源于stack exchange,提问作者James Read

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:42:16