Android 系统奔溃触发WatchDog分析

2023-05-16

和你一起终身学习,这里是程序员Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、前言
二、场景介绍
三、分析trace文件

一、前言

作为一个Android开发者,不管是App或者是System开发者,经常会遇到一些分析日志的场景,本文就通过一个场景介绍一下Android 系统触发Watdog重启时的分析思路。Watchdog俗称看门狗,Android如果一些系统服务发生异常,会触发Watchdog,导致系统重启。

二、场景介绍

QA报了一个系统重启的Bug,就是电视通过Hdmi连接盒子,在进入Hdmi页面时,系统奔溃了,既然是系统奔溃一般情况都是系统服务挂掉了,系统服务挂掉一遍会触发Watchdog.下面就是触发WatDog时的日志,一般查看Android Log中是否触发WatDog可以搜索Watchdog,或者GOODBYE关键字.

07-26 06:34:10.100  2112  2135 W Watchdog: *** Watchdog KILLING SYSTEM PROCESS: Blocked in handler on main thread (main)
07-26 06:34:10.105  2112  2135 W Watchdog: main annotated stack trace:
07-26 06:34:10.106  2112  2135 W Watchdog:     at com.android.server.tv.TvInputHardwareManager.getHardwareList(TvInputHardwareManager.java:250)
07-26 06:34:10.106  2112  2135 W Watchdog:     - waiting to lock <0x0c25fdf3> (a java.lang.Object)
07-26 06:34:10.107  2112  2135 W Watchdog:     at com.android.server.tv.TvInputManagerService$InputServiceConnection.onServiceConnected(TvInputManagerService.java:2419)
07-26 06:34:10.107  2112  2135 W Watchdog:     - locked <0x0c7f5ab0> (a java.lang.Object)
07-26 06:34:10.108  2112  2135 W Watchdog:     at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1954)
07-26 06:34:10.108  2112  2135 W Watchdog:     at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1986)
07-26 06:34:10.109  2112  2135 W Watchdog:     at android.os.Handler.handleCallback(Handler.java:938)
07-26 06:34:10.109  2112  2135 W Watchdog:     at android.os.Handler.dispatchMessage(Handler.java:99)
07-26 06:34:10.109  2112  2135 W Watchdog:     at android.os.Looper.loop(Looper.java:223)
07-26 06:34:10.110  2112  2135 W Watchdog:     at com.android.server.SystemServer.run(SystemServer.java:669)
07-26 06:34:10.110  2112  2135 W Watchdog:     at com.android.server.SystemServer.main(SystemServer.java:413)
07-26 06:34:10.111  2112  2135 W Watchdog:     at java.lang.reflect.Method.invoke(Native Method)
07-26 06:34:10.111  2112  2135 W Watchdog:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
07-26 06:34:10.111  2112  2135 W Watchdog:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1060)
07-26 06:34:10.112  2112  2135 W Watchdog: *** GOODBYE!
07-26 06:34:10.112  2112  2135 I Process : Sending signal. PID: 2112 SIG: 9

上面TvInputHardwareManager.getHardwareList方法被调用的时候block住了,从下一行日志得知他block的原因是等待一个锁。

07-26 06:34:10.106  2112  2135 W Watchdog:     at com.android.server.tv.TvInputHardwareManager.getHardwareList(TvInputHardwareManager.java:250)
07-26 06:34:10.106  2112  2135 W Watchdog:     - waiting to lock <0x0c25fdf3> (a java.lang.Object)

代码如下

   public List<TvInputHardwareInfo> getHardwareList() {
        synchronized (mLock) {
            return Collections.unmodifiableList(mHardwareList);
        }
    }

那这个锁被谁持有呢?现在只看Android log已经无能为力了,需要分析trace文件,做过app开发的应该都经常遇到anr,遇到anr一般都需要分析trace文件, 这个trace文件在/data/anr/目录下。我们知道触发ANR,dump trace文件的场景如下:

Service Timeout:比如前台服务在20s内未执行完成
BroadcastQueue Timeout:比如前台广播在10s内未执行完成
ContentProvider Timeout:内容提供者,在publish过超时10s
InputDispatching Timeout: 输入事件分发超时5s,包括按键和触摸事件

其实还有一种情况也会生成trace文件,那就是触发Framework的Watchdog的时候。看一下Watchdog.java的run方法,符合条件时,会触发dump trace的操作。
//frameworks/base/services/core/java/com/android/server/Watchdog.java

@Override
    public void run() {
      ···
if (!fdLimitTriggered) {
                    final int waitState = evaluateCheckerCompletionLocked();
                    if (waitState == COMPLETED) {
                        // The monitors have returned; reset
                        waitedHalf = false;
                        continue;
                    } else if (waitState == WAITING) {
                        // still waiting but within their configured intervals; back off and recheck
                        continue;
                    } else if (waitState == WAITED_HALF) {
                        if (!waitedHalf) {
                            Slog.i(TAG, "WAITED_HALF");
                            // We've waited half the deadlock-detection interval.  Pull a stack
                            // trace and wait another half.
                            ArrayList<Integer> pids = new ArrayList<>(mInterestingJavaPids);
                          //dump trace文件
                            ActivityManagerService.dumpStackTraces(pids, null, null,
                                    getInterestingNativePids(), null);
                            waitedHalf = true;
                        }
                        continue;
                    }
  ···
}

触发dump trace时,日志里会有如下的日志:

07-26 06:33:59.485  2112  2135 I ActivityManager: Dumping to /data/anr/anr_2021-07-26-06-33-59-483

三、分析trace文件

"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x71684c28 self=0xe11c5410
  | sysTid=2112 nice=-2 cgrp=default sched=0/0 handle=0xe9762470
  | state=S schedstat=( 0 0 0 ) utm=377 stm=96 core=1 HZ=100
  | stack=0xff11b000-0xff11d000 stackSize=8192KB
  | held mutexes=
  at com.android.server.tv.TvInputHardwareManager.getHardwareList(TvInputHardwareManager.java:250)
  - waiting to lock <0x0c25fdf3> (a java.lang.Object) held by thread 100
  at com.android.server.tv.TvInputManagerService$InputServiceConnection.onServiceConnected(TvInputManagerService.java:2419)
  - locked <0x0c7f5ab0> (a java.lang.Object)
  at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1954)
  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1986)
  at android.os.Handler.handleCallback(Handler.java:938)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:223)
  at com.android.server.SystemServer.run(SystemServer.java:669)
  at com.android.server.SystemServer.main(SystemServer.java:413)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1060)

这个堆栈我们在Android log里已经看到了,block的原因是等待0x0c25fdf3这个锁,那我们就搜一下0x0c25fdf3这个锁现在被谁持有.

"Binder:2112_6" prio=5 tid=100 Blocked
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x135c0808 self=0xb9698810
  | sysTid=2491 nice=0 cgrp=default sched=0/0 handle=0xb478b1c0
  | state=S schedstat=( 0 0 0 ) utm=32 stm=10 core=1 HZ=100
  | stack=0xb4690000-0xb4692000 stackSize=1008KB
  | held mutexes=
  at com.android.server.tv.TvInputHardwareManager$TvInputHardwareImpl.release(TvInputHardwareManager.java:847)
  - waiting to lock <0x0234b2e5> (a java.lang.Object) held by thread 11
  at com.android.server.tv.TvInputHardwareManager$Connection.resetLocked(TvInputHardwareManager.java:652)
  at com.android.server.tv.TvInputHardwareManager$Connection.binderDied(TvInputHardwareManager.java:722)
  - locked <0x0c25fdf3> (a java.lang.Object)
  at android.os.IBinder$DeathRecipient.binderDied(IBinder.java:305)
  at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:654)

从上面的trace发现0x0c25fdf3被Connection.binderDied这个方法持有的,而该方法被block原因是它调用了TvInputHardwareImpl.release方法,这个TvInputHardwareImpl.release方法被另外一个锁0x0234b2e5block住了,那么0x0234b2e5锁被谁持有呢?

"Binder:2112_2" prio=5 tid=11 Native
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x131c03c8 self=0xe11c6210
  | sysTid=2127 nice=0 cgrp=default sched=0/0 handle=0xbd2401c0
  | state=S schedstat=( 0 0 0 ) utm=73 stm=20 core=3 HZ=100
  | stack=0xbd145000-0xbd147000 stackSize=1008KB
  | held mutexes=
  native: #00 pc 000715e4  /apex/com.android.runtime/lib/bionic/libc.so (__ioctl+8)
  native: #01 pc 0003f2a3  /apex/com.android.runtime/lib/bionic/libc.so (ioctl+30)
  native: #02 pc 0006d78f  /system/lib/libhidlbase.so (android::hardware::IPCThreadState::transact(int, unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int)+438)
  native: #03 pc 0006a265  /system/lib/libhidlbase.so (android::hardware::BpHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+36)
  native: #04 pc 0000c3f9  /system/lib/android.hardware.tv.input@1.0.so (android::hardware::tv::input::V1_0::BpHwTvInput::_hidl_closeStream(android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, int, int)+228)
  native: #05 pc 0000c7c5  /system/lib/android.hardware.tv.input@1.0.so (android::hardware::tv::input::V1_0::BpHwTvInput::closeStream(int, int)+36)
  native: #06 pc 00069801  /system/lib/libandroid_servers.so (android::JTvInputHal::removeStream(int, int)+440)
  at com.android.server.tv.TvInputHal.nativeRemoveStream(Native method)
  at com.android.server.tv.TvInputHal.removeStream(TvInputHal.java:111)
  - locked <0x08f771dc> (a java.lang.Object)
  at com.android.server.tv.TvInputHardwareManager$TvInputHardwareImpl.setSurface(TvInputHardwareManager.java:872)
  - locked <0x0234b2e5> (a java.lang.Object)
  at android.media.tv.ITvInputHardware$Stub.onTransact(ITvInputHardware.java:136)
  at android.os.Binder.execTransactInternal(Binder.java:1154)
  at android.os.Binder.execTransact(Binder.java:1123)

这个0x0234b2e5锁被TvInputHardwareImpl.setSurface方法持有了,那么他被block的原因是:android.hardware.tv.input@1.0.so中有个_hidl_closeStream方法被block住了。

  native: #04 pc 0000c3f9  /system/lib/android.hardware.tv.input@1.0.so (android::hardware::tv::input::V1_0::BpHwTvInput::_hidl_closeStream(android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, int, int)+228)

由于再往下追会涉及到公司的私有代码了,这里就不在继续往下分析了,但是上面的思路已经很清楚了,结合trace中的堆栈和源码定位问题应该不成问题。
总结
不管是普通的anr问题或者是这种触发Watchdog的重启,分析方式都类似的,就是先查看Android log,然后在分析trace文件,一步一步的往下挖掘。在上面的介绍中提到的WatDog,其实是Android Framework中一个很重要的机制,后面将出文章专门介绍一下其实现,v。

参考链接:https://juejin.cn/post/6989592850170118158

友情推荐:

Android 开发干货集锦

至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

点个在看,方便您使用时快速查找!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 系统奔溃触发WatchDog分析 的相关文章

  • Android如何在账户设置中添加App的账户

    Android系统为外部服务提供了账号登录的机制 xff0c 用于同步数据等作用 进入设置 gt 账户 gt 添加账户 xff0c 即可看到目前手机上有哪些App提供了同步服务 接下来将会演示如何在App中定义登录服务并添加一个登录选项到这
  • linux服务器使用入门

    以阿里云的CentOS6 8 64位为例 xff1a 1 获取你服务器主机的IP xff0c 密码 xff0c 一般是在你留给空间商的邮箱之中 2 使用putty登录服务器 xff0c 用户名root xff0c 密码就是上一步中的密码 3
  • Java系列 - Spring 加载配置项的四种方式

    本文默认 spring 版本是 spring5 1 spring 加载 yml 文件2 spring 加载 properties 文件3 spring 加载 系统磁盘 文件4 spring 加载 xml 文件5 Java 基于 InputS
  • openbox的异常

    openbox的异常 xff0c 虽然标题是这个 xff0c 但未必是openbox的bug 但肯定的是与openbox关系比较密切 项目中出现一件灵异事件 xff1a 当程序 基于qt 起来之后 xff0c 有时 xff0c 主界面会发生
  • bind配置文件语法

    acl xff1a 定义IP地址表的名字 用于访问控制等 语法 acl acl name address match list controls xff1a 宣告一个用于rndc工具控制通道 语法 controls inet ip addr
  • APUE两次fork防止产生僵尸进程的例程相关——子进程没有被init收留的问题

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 APUE两次fork防止产生僵尸进程的例程相关 子进程没有被init收留的问题 一 问题二 证明 一 问题 首先看书上的例程与结果 按道理
  • XD如何将喜欢的颜色添加到资源中

    1 打开InstantColor插件 2 产生颜色 3 选取颜色 4 添加到资源 5 查看资源
  • VSCode主题设置和常用快捷键

    主题设置 点击菜单栏的 Code 首选项 设置 xff0c 然后在左边找到 工作台 外观 xff0c 在 Color Theme 选项下可以设置主题 xff0c 下面以 Default Dark 43 主题为例 xff0c 讲解如何在这个主
  • 网络爬虫详细设计方案

    目录 网络爬虫设计方案 1 网络爬虫简介 2 Java爬虫的开发和使用流程 2 1 下载 2 2 分析 3 单点登陆与Jsoup解析 3 1 单点登陆简介 3 1 1 登陆 3 1 2 注销 3 2 Jsoup网页解析 4 网络爬虫详细设计
  • Android之资源限制ulimit

    Android之资源限制ulimit https notes z dd net 2020 09 06 Android E4 B9 8B E8 B5 84 E6 BA 90 E9 99 90 E5 88 B6ulimit
  • 技术人成长中的得与失,想当程序员或者已经是程序员的要注意了!

    每个人在成长过程中 xff0c 都免不了在得失中摇晃 xff0c 对我来说 xff0c 将来如何更好地去平衡得失 xff0c 是需要思考的问题 xff0c 而对新入行的年轻人来说 xff0c 能从我这些总结中获得一点点启发 xff0c 那我
  • stm32 代码RAM溢出

    KEIL编译程序后报下边错误 xff1a 原因是因为代码的全局变量太多或全局的数组太大导致程序编译后RAM溢出 xff0c 建议先查看有没有比较大的全局数组 BootLoader BootLoader axf Error L6406E No
  • 【测试沉思录】6. 设计一款简单的接口自动化测试框架

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 周栒 编辑 xff1a 毕小烦 接口自动化测试是质量保障体系中非常重要的一环 xff0c 业内也有很多的
  • 【测试沉思录】7. 测试左移的一点思考

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 王媛媛 编辑 xff1a 毕小烦 万物皆有生命周期 xff0c 软件工程也一样 软件生命周期 xff08
  • 【测试沉思录】8. 测试计划应该怎么做?

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 闫嘉欣 编辑 xff1a 毕小烦 敏捷项目的特点是需求变化快 项目周期短 传统的极致详尽的测试计划已经不
  • 【测试沉思录】9. 数据工厂低代码平台探索与实践

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 吴锺瑞 刘洪初 编辑 xff1a 毕小烦 一 需求背景 造数据可能是日常迭代中最频繁也是最耗时的工作 我
  • 【测试沉思录】10. 我们用到的3种Mock测试方案

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 王媛媛 编辑 xff1a 毕小烦 Mock 这个词对于测试人员来说并不陌生 xff0c 当我们要测试的接
  • 【测试沉思录】11. 如何进行基准测试?

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 刘洪初 编辑 xff1a 毕小烦 基准测试 xff08 benchmarking xff09 其实就是一
  • 【测试沉思录】12. 可用性保障平台的自动化测试探索与实践

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 张雅瑜 编辑 xff1a 毕小烦 一 背景 随着业务的发展 xff0c 应用越来越多 xff0c 并且承
  • 【测试沉思录】13. 玩转 Dubbo 接口测试的 3 种姿势

    欢迎订阅我的新专栏 现代命令行工具指南 xff0c 精讲目前最流行的开源命令行工具 xff0c 大大提升你的工作效率 作者 xff1a 王伟 编辑 xff1a 毕小烦 微服务盛行的今天 xff0c 保障服务质量至关重要 xff0c 作为测试

随机推荐

  • 【测试沉思录】14. 性能测试中的系统资源分析之一:CPU

    作者 xff1a 马海琴 编辑 xff1a 毕小烦 在日常的性能测试中 xff0c 我们除了关注应用本身的性能 xff0c 比如服务的响应时间 TPS 等 xff0c 也需要关注服务器本身的资源使用情况 xff0c 比如 CPU 内存 磁盘
  • Java 多线程编程 实验题

    Java 多线程编程 实验二 1 创建键盘操作练习2 双线程猜数字3 月亮围绕地球 1 创建键盘操作练习 题目描述 xff1a 编写一个Java应用程序 xff0c 在主线程中再创建两个线程 xff0c 一个线程负责给出键盘上字母键上的字母
  • 【测试沉思录】15. 性能测试中的系统资源分析之二:内存

    作者 xff1a 马海琴 编辑 xff1a 毕小烦 二 内存 内存又称主存 xff0c 是 CPU 能直接寻址的存储空间 xff08 由半导体器件制成 xff09 内存的特点是存取速率快 xff0c 断电一般不保存数据 xff08 非持久化
  • 【测试沉思录】16. 性能测试中的系统资源分析之三:磁盘

    作者 xff1a 马海琴 编辑 xff1a 毕小烦 三 磁盘 磁盘是可以持久化存储的设备 xff0c 根据存储介质的不同 xff0c 常见磁盘可以分为两类 xff1a 机械磁盘和固态磁盘 磁盘就像人的大脑皮层 xff0c 负责数据的储存 记
  • 【测试沉思录】17. 性能测试中的系统资源分析之四:网络

    作者 xff1a 马海琴 编辑 xff1a 毕小烦 计算机网络 xff0c 就是通过光缆 电缆 电话线或无线通讯将两台以上的计算机互连起来的集合 xff0c 包括广域网 城域网 局域网和无线网 计算机网络是传输信息的媒介 我们常说的千兆网
  • 【测试沉思录】18.如何测试微信小程序?

    作者 xff1a 雷远缘 编辑 xff1a 毕小烦 一 先知道小程序是什么 啥是小程序 xff1f 小程序是一种不需要下载安装即可使用的应用 xff0c 它实现了应用 触手可及 的梦想 xff0c 用户扫一扫或者搜一下即可打开应用 也体现了
  • 【测试沉思录】19. 如何设置 JMeter 线程组?

    作者 xff1a 宋赟 编辑 xff1a 毕小烦 最近有不少测试同学问我 JMeter 线程组如何设置并发的问题 xff0c 发现很多人对线程组里的参数不是很清楚 xff0c 今天就科普一下 JMeter 线程组的信息 xff0c 也简单介
  • 【测试沉思录】20. 如何做好测试需求分析?

    作者 xff1a 刘亚茹 编辑 xff1a 毕小烦 我们都知道测试用例是软件测试中保障质量的必要手段 xff0c 而测试需求作为用例编写的主要依据却往往被很多人忽视 到底什么是测试需求 xff1f 又如何做好测试需求分析呢 xff1f 本文
  • 【测试沉思录】21. 如何用 JMeter 编写性能测试脚本?

    作者 xff1a 宋赟 编辑 xff1a 毕小烦 Apache JMeter 应该是应用最广泛的性能测试工具 怎么用 JMeter 编写性能测试脚本 xff1f 1 编写 HTTP 性能测试脚本 STEP 1 添加 HTTP 请求 STEP
  • 【测试沉思录】21. 如何用 JMeter 编写性能测试脚本?

    作者 xff1a 宋赟 编辑 xff1a 毕小烦 Apache JMeter 应该是应用最广泛的性能测试工具 怎么用 JMeter 编写性能测试脚本 xff1f 1 编写 HTTP 性能测试脚本 STEP 1 添加 HTTP 请求 STEP
  • 【测试沉思录】22. 前端性能测试怎么做?

    作者 xff1a 张丹青 编辑 xff1a 毕小烦 普通用户如何评价一个网站的体验好不好呢 xff1f 除了满足他的功能需求以外 xff0c 用得爽不爽可能是最大的评估因素 这个爽不爽可以简单理解为快不快 xff0c 好不好看 xff0c
  • 【测试沉思录】23. 如何实现基于场景的接口自动化测试用例?

    作者 xff1a 陈爱娇 编辑 xff1a 毕小烦 自动化本身是为了提高工作效率 xff0c 不论选择何种框架 xff0c 何种开发语言 xff0c 我们最终想实现的效果 xff0c 就是让大家用最少的代码 xff0c 最小的投入 xff0
  • 搭建linux服务器详细教程

    Linux服务器的部署 xff0c 配置 xff0c 搭建步骤 xff1a 1 准备 xff1a 1 1 jdk1 8 xff1a jdk 8u11 linux x64 tar gz tomcat xff1a apache tomcat 8
  • 使用Word2013写论文的时候,波浪号(~)一直在一行的上面,无法上下居中 的解决方案

    这里提供四种方法给大家 xff0c 不用谢 xff01 1 搜狗输入法 xff0c 直接打 blh xff0c 即可获得波浪号 xff08 这个方法大多数地方都可以用 xff0c 比如打摄氏度符号 xff08 xff09 的时候 xff09
  • centos7.4安装图形界面并远程桌面连接

    1 系统版本 CentOS release 6 2 Final 以下安装需要用root权限操作 2 安装x windows yum groupinstall y X Window System 注意有引号 3 安装图形界面软件 GNOME
  • linux服务器更改网络配置

    文章目录 前言一 更改vmware的虚拟网络配置二 修改window的网络配置三 修改虚拟机内部的配置四 映射 选做 修改hostname修改hosts修改windows的配置验证 前言 linux服务器更改网络配置 xff0c 是为让它的
  • FastBoot 刷机教程

    本篇文章主要介绍 Android 开发中的 FastBoot 部分知识点 xff0c 通过阅读本篇文章 xff0c 您将收获以下内容 一 Fastboot 简介 欢迎关注微信公众号 程序员Android 微信公众号 xff1a Progra
  • Google GMS Crash 优化方案

    极力推荐文章 xff1a 欢迎收藏 Android 干货分享 阅读五分钟 xff0c 每日十点 xff0c 和您一起终身学习 xff0c 这里是程序员Android GMS GoogleMobile Service 包是出口国外手机中 Go
  • FastBoot 刷机使用方法

    和你一起终身学习 xff0c 这里是程序员Android 经典好文推荐 xff0c 通过阅读本文 xff0c 您将收获以下知识点 一 Fastboot 简介 二 Fastboot 刷机准备 三 Fastboot 刷机命令 四 其他刷机工具
  • Android 系统奔溃触发WatchDog分析

    和你一起终身学习 xff0c 这里是程序员Android 经典好文推荐 xff0c 通过阅读本文 xff0c 您将收获以下知识点 一 前言 二 场景介绍 三 分析trace文件 一 前言 作为一个Android开发者 xff0c 不管是Ap