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
错误原因分析
finishActivity()无法终止跨应用Activity:finishActivity(requestCode)只能终止当前应用任务栈中、由自身通过startActivityForResult启动的Activity。第二个应用的Activity属于独立的任务栈,不在当前应用的控制范围内,因此这个调用完全无效。- 主线程被阻塞:
while(true)结合Thread.sleep(10000)直接阻塞了onResume所在的主线程,不仅会引发ANR(应用无响应),还会导致代码逻辑执行异常——主线程被挂起时,后续的finishActivity无法及时执行,且重复启动的操作会不断创建第二个应用的新实例。 - 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
相关产品推荐
相关产品推荐

