当前位置: 首页 > news >正文

双进程交互实现App自动重启

背景

你可能会好奇,有些手游(比如王者荣耀)是怎么实现资源更新后自动重启的?

这个体验确实不错,因为不需要用户手动点击桌面图标重启App,在一些数据恢复备份的场景中,很实用。比如,从云端拉取SQLite数据库db文件或一些prefs配置文件后,会直接覆盖到本地,但进程不重新启动的话,是不会生效的。

思路

基本思路其实很简单,利用Android应用对多进程的天然支持,来实现双进程互拉。

有的朋友一看见“双进程”、“互拉”这些词汇就会立马联想到保活,注意本文不是讲保活的哦。

为了方便讲解,我们定义主进程之外的另一个进程为 进程B。大致流程分这么几步:

  • 在主进程执行完一系列业务逻辑后,欲重启,先拉起进程B
  • 进程B启动后,主进程kill掉自己
  • 接着,进程B拉起主进程,然后再kill掉自己,此时主进程完成自动重启

实现

先在Manifest中声明进程B,为了良好的交互体验,需要实现一个Activity,进程名称自定义,比如此处叫“killer”,是不是很贴切?

        <activityandroid:name=".KillerActivity"android:exported="false"android:launchMode="singleTask"android:process=":killer" />

关键实现来了:

class KillerActivity : FragmentActivity() {companion object {private const val EXTRA_MAIN_PID = "extra_main_pid"// 当主进程需要重启时,就直接调用此方法启动KillerActivityfun launch(activity: FragmentActivity) {activity.startActivity(Intent(activity, KillerActivity::class.java).apply {putExtra(EXTRA_MAIN_PID, Process.myPid())})activity.finish() // 主进程的Activity先关闭GlobalScope.launch {// 稍作延迟后,主进程kill掉自己delay(500L)killProcess()}}fun killProcess(pid: Int = Process.myPid()) {Process.killProcess(pid)exitProcess(0)}fun isMainProcessAlive(context: Context): Boolean = runCatching {(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).runningAppProcesses.find { it.processName == context.packageName } != null}.getOrDefault(false)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)lifecycleScope.launch {// 此处可以插入一些Loading的UI显示,比如ProgressDialog之类的// ...// 二次检查,防止主进程没杀掉doubleCheckMainProcess()// 稍作等待后,再次启动主进程的ActivitystartActivity(Intent(this, MainActivity::class.java).apply {addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)})// 进程B的KillerActivity先关闭,再kill掉自己finish()killProcess()}}private suspend fun doubleCheckMainProcess() {delay(1500L)if (isMainProcessAlive(this)) {val mainPid = intent.getIntExtra(EXTRA_MAIN_PID, 0)if (mainPid != 0) {killProcess(mainPid)delay(1500L)}}}
}

整个代码非常简单,只要搞清楚 killProcess 方法哪些时候是kill的哪个进程,就理解了。在任意一个需要重启当前进程(可以不只是主进程)的地方,调用:

KillerActivity.launch(this)

即可。

相关文章:

  • 电脑突然死机怎么办?
  • axios发送get请求但参数中有数组导致请求路径多出了“[]“的处理办法
  • 纯分享万岳外卖跑腿系统客户端源码uniapp目录结构示意图
  • sql造数据
  • zedboard+AD9361 运行 open WiFi
  • 【案例·增】获取当前时间、日期(含,SQL中DATE数据类型)
  • 【Python从入门到进阶】51、电影天堂网站多页面下载实战
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • Linux:Jenkins:参数化版本回滚(6)
  • react native hooks 如何避免重复请求
  • springdata框架对es集成
  • HMI的学习
  • 【SpringCloud微服务实战10】DevOps自动化部署微服务项目(Jenkins+Docker+K8s)
  • Dubbo的服务注册与发现原理、Java如何实现Dubbo的服务注册与发现
  • 【ZZULIOJ】1012: 求绝对值(Java)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Android Studio:GIT提交项目到远程仓库
  • Android Volley源码解析
  • angular2 简述
  • Computed property XXX was assigned to but it has no setter
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  •  D - 粉碎叛乱F - 其他起义
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • node入门
  • php面试题 汇集2
  • Python 反序列化安全问题(二)
  • Python 基础起步 (十) 什么叫函数?
  • Spring Cloud Feign的两种使用姿势
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 力扣(LeetCode)357
  • 目录与文件属性:编写ls
  • 前端临床手札——文件上传
  • 全栈开发——Linux
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • (1)常见O(n^2)排序算法解析
  • (13)Hive调优——动态分区导致的小文件问题
  • (3)llvm ir转换过程
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (附源码)springboot教学评价 毕业设计 641310
  • (力扣题库)跳跃游戏II(c++)
  • .net Signalr 使用笔记
  • .NET开发人员必知的八个网站
  • .NET中winform传递参数至Url并获得返回值或文件
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • /bin/bash^M: bad interpreter: No such file or directory
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • [100天算法】-二叉树剪枝(day 48)
  • [CSS]CSS 字体属性
  • [CTF]php is_numeric绕过
  • [EFI]英特尔 冥王峡谷 NUC8i7HVK 电脑 Hackintosh 黑苹果efi引导文件
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能
  • [Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例