Android车载经验总结

1,537 阅读9分钟

打开车载wifi能力,让车载设备能够连接wifi:

  • adb root

  • adb remount

  • adb shell setprop persist.service.wifi.ipcp false

  • adb reboot

车载安装apk总结

  1. 车载安装失败,报错如下:

Failure [INSTALL_PARSE_FAILED_NO_CERTIF ICATES: Failed to collect certificates from /data/app/vmdl817232687.tmp/base.apk: Attempt to get length of null array] 

大部分场景,强制安装都可以安上:

  • adb install -r -t -d D:\FTD_E\Task\Thundersoft\Project\com.ftd.theme.apk

如果 -r -t -d 强制低版本生高版本都无法安装上的话,可以取巧。通过pm命令去查看包安装到哪个目录了,然后把这个目录下的apk包重命名,之后车载就没有了这个应用,就可以使用没签名的包替换了

  • adb shell pm path com.ftd.theme (这个命令能够识别当前车机使用的是哪个目录下的包作为当前运行的内容,比如是system下的还是data下的起作用)。

  • 将/system/app下面的你想安装的包重命名,然后车载无法识别这个应用,你就可以安装了。

关于车机签名:

   关于车机包安装需要统一签名,建议项目初始应用和服务都做签名,这样方便后续AS 直接install否则,上一个车载apk安装问题,总会困扰你,整个开发周期如果你对系统包不是很理解,很容易出现调试和开发的根本不是你的当前程序的怪异问题。

关于车机签名的详细汇总:

  • jks是在android studio里面生成的签名证书。keystoreeclipse里面生成的。

  • jks和keystore的转换:blog.csdn.net/linxinfa/ar…

  • pem和pk8是设备厂商给的命令行签名的文件。

以上使用pem和pk8可以转换为jks和keystore, 反之也行,可以互相转换。一般应用测签名就用jks(见AS上面的代码配置),然后系统平台统一签名,就用pem和pk8。

java -jar signapk.jar platform.x509.pem platform.pk8 [old].apk [new].apk

以下是详细文章,这次基本把车载签名文件和签名的方式一次性梳理明白了。

  1. blog.csdn.net/weixin\_424…

  2. www.javashuo.com/article/p-m…

  3. blog.csdn.net/weixin\_387…

车载更新VIN码等的指令:

adb root 

adb remount 

adb shell setprop persist.adaptapi.debug 1 

 adb root && adb remount 

 adb shell setprop persist.device.vehicle_type 02605G1 

adb shell setprop persist.device.vin VFK20220616661958 

adb shell setprop persist.device.ihuid IFK202206162013123456798 

adb shell setprop persist.device.serialno 8892558230 

 adb shell setprop persist.device.partno 8892558230

 adb reboot

Android隐藏hide接口的调用--配置framework.jar

  1. 首先要配置系统签名(见上面签名配置)

  1. compileOnly files('../libs/framework.jar') (compare方式编译通过即可,车机会放入framework.jar真正引用的车机内部的代码)

  2. gradle.projectsEvaluated {

    tasks.withType(JavaCompile) {

    Set fileSet = options.bootstrapClasspath.getFiles()

List newFileList = new ArrayList<>();

newFileList.add(new File("../libs/framework.jar"))

newFileList.addAll(fileSet)

options.bootstrapClasspath = files(

newFileList.toArray()

)

}

}

也可以结合:blog.csdn.net/xiayiye5/ar…

原生的通知打开和关闭权限设置

车载换肤和切换白天黑夜,简易处理方法

保证页面不重启,通过xml解析的方式避免多次的setTextView和setBackground操作

www.jianshu.com/p/3b581ba5f…

车载清理apk缓存

data/system/package_cache/Mine.apk把缓存清理重启下

data/app/包名/*

system/app/包名下的文件。

Launcher启动:设置动态壁纸,关机,开机先显示静态壁纸,闪烁黑画,然后显示动态壁纸。

调查中:猜测是Framework开发性能优化导致的问题

1、试了更换更换systemUI,合并systemUI和Image壁纸服务进程,没有效果。

2、增加android:directBootAware="true",结果:动态壁纸服务启动太早,资源文件不可读,直接MediaPlayer黑画,无法使用此方案。

3、根因是系统启动的时候LiveWallpaperService无法被Bind上。 unavailable, 所以去加载了静态壁纸,导致闪烁

最终方案:基于方案2,给Livewallpaperservice加上android:directBootAware="true",开机快速启动,保证服务是可以被bind的,然后把动态壁纸服务Livewallpaperservice依赖的资源从/sdcard/中转到/ivres/中,sdcard开机挂载慢,ivres直接快,直接可以供framework使用解决这个问题。但是整体核心还是开机时序优化导致的问题。各种服务依赖错乱了。 (后续还有点问题是开机偶现先显示动态壁纸,黑画闪烁后再显示动态壁纸,这个还是开机时序错乱,导致的页面加载混乱导致的,framework问题)。

4、Android 静态壁纸走的是ImageWallpaper,一个壁纸服务WallpaperService的子类。 然后动态壁纸服务走也是自定义LiveWallpaperService,继承WallpaperService,最终使用的都是SurfaceView去展示动静态壁纸。

5、原生壁纸的APP到Framework的设置流程

  • 从WallpaperManager的setBitmap或者setWallpaperComponent

  • 到WallpaperManager内部的相应方法

  • 到WallpaperManagerService的setWallpaperComponent

  • 到WallpaperManagerService的bindWallpaperComponentLocked

  • bindWallpaperComponentLocked方法内部会BindService,启动系统的WallpaperService的子类或者是启动我们自定义的MyWallpaperService子类壁纸服务。

  • MyWallpaperService类会执行我们壁纸渲染的引擎Engine,类似于surfaceView等,开发渲染Surface,这期间我们自定义的MyWallpaperManager类中定义壁纸文件的地址和逻辑等会被触发和使用。 实现了车载主副屏自定义壁纸。

  • 涉及到的壁纸类:

  • /frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java (WallpaperManager的实现类)

  • /frameworks/base/core/java/android/app/WallpaperManager.java(IWallpaperManager的实现类,作为APP的工具类使用)

  • /frameworks/base/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java(原生静态壁纸类:当主副屏静态壁纸自定义的时候不用ImageWallpaper.java了,然后Launcher需要去掉一个Window,自定义的静态壁纸才能显示出来)。

  • /frameworks/base/core/java/android/service/wallpaper/WallpaperService.java(继承自service,核心的壁纸服务)

  • 涉及到的命令:

  • dumpsys SurfaceFlinger (dump命令,能够打印出屏幕张多个屏幕的Surface的数据,主屏和副屏Surface分别对应的Activity和View的信息)

  • 使用scrcpy-win64-v1.22.7z等软件

  • 命令start scrcpy.exe --display=2 投屏命令,能够把屏幕2启动到这个软件上。 

动态壁纸设置失败导致重影问题:

解决措施:

  • 1、播放过程中prepare准备中的话,需要异步onprepare过程中去播放player.start
  • 2、onError的话,在异步错误中player.start
  • 3、如果视频解码偶现错误,磁层偶现,这个捕获setOnInfoListener()的回调中判断

what == MediaPlayer.MEDIA_INFO_VIDEO_NOT_PLAYING && extra == -38的code然后去重新播放。 只要不是100%解码错误可以解决。如果是100%解码错误需要更换视频。

车载VDI开发环境,adb 安装过程中设备总是异常中断,无法安装apk的问题:

vdi adb 运行到车机断连问题解决办法 

1.先退出androidstudio 

2.执行adb kill-server 

3.执行adb start-server 

4.adb启动成功后 打开androidstudio 

亲试好用,如不好用再试一遍. 该问题原因是androidstudio的adb的问题

Android的vdex和odex的区别

  • blog.csdn.net/qq\_3944160… 
  • vdex主要是为了免除合法校验
  • odex主要是为了开机优化dex文件,有了odex文件的话,直接用这个文件,后续开机就快了。

Android的主副屏相关的需求定制

  • Android的主副屏的壁纸和屏保以及APP主副屏启动等,多数是通过Display和Displayid的概念去区分主副屏。

  • 而对于应用来说从ActivityDisplay->ActivityStack->ActivityTask->ActivityRecord. 每个ActivityDisplay对应一个屏幕,ActivityRecord记录一个Activity的详细信息。从Framework到上层页面的关系流

Android11的Framework变更:

  • 记录一个bug调查,找不到数据库文件了,查了半个点才知道换了路径,Android 11的应用预制应用的默认数据库从/data/data/包名/database, 调整为**/data/user_de/0/包名/database**下面了。

Foreground和Background关于车载进程是否在最前台的处理方法:后续需要使用手机或者模拟器再确认一遍,可能是定制Launcher导致的进程方法不好用。

  • 使用FW的能力:参考飞书-Android 车载Framework知识总结。ActivityManager.getservice().getAllStackinfo.获取所有的栈信息然后取包名和裁剪获取Activity,进程和Activity都能获取到。(以下的其他都不好用)

gitee.com/safei/Andro…:

  • 方法五:github.com/jaredrummle…

  • 方法一:RunningTask,之前车型好用过,但是Android9的新车型发现也是前后台结果一致,不好用,NG。

  • 方法二:方法二:通过RunningProcess,但是Android9的新车型发现也是前后台结果一致,不好用,NG

  • UsageStatsManager没测试。

  • 方法三:ActivityLifecycleCallbacks的方式,这个应用内判断感觉没啥问题,但是车机场景有HUD其他屏幕的Activity或者1像素的导致APP的activity还显示但是Pause了,这种场景还没推入后台,但是时序已经推入后台了,这种场景可能无法满足需求。比如A程序5S程序退出,但是HUD一干扰,界面显示,但是A程序Pause后Timer移除了,但是A程序并没有从Launcher界面退出。

  • Demo测试结论:当用户点击启动和退出的时候,各种方法基本都是有用的,但是如果是点击Launcher上的切换应用,有时候就不起作用了。尝试了以上很多种方式。最受还是14

    [

    ](stackoverflow.com/posts/48112…)

    Activity::hasWindowFocus()这个焦点的方式比较好用,即便命令行切换应用和页面也能够及时的监控,如果你因为多屏幕导致生命周期被搞乱了或者被一像素的窗口干扰,这个方法可能可以辅助判断应用是否在前台需要结合应用ActivityLifecycleCallback整体效果更佳。总之完美的解决了前台后各种方法都不好用的问题。思路参考stackoverflow:stackoverflow.com/questions/1…

Git使用:

通过gitk命令可以通过视图查看代码多分支的使用情况,这个挺方便的,原生Git带的。

Android车载启动优化的工具:

车载Widget架构组成:

Android SEAndroid 系统安全配置:

juejin.cn/post/720847…

Android车载最简单的提前应用启动时机的修改:

增加这两个directBootAware, 下面这个属性是补充资源访问保护。有可能加上让访问SP了

查找多文件中的关键字Log:grep命令使用。

  • baijiahao.baidu.com/s?id=173154…

  • zhuanlan.zhihu.com/p/561445240…

  • grep -r -n -l -i "system.err" ( -r递归; -n显示行号; -l列出文件名看着更清晰不列详细行; -i 忽略大小写;4个指令就能列举出来包含的最简单的文件列表了)

  •  grep --color=auto -v "system.err" (增加-v 反转查询会多出来很多文件,但是关联关系不太明确;  增加颜色不错)

Android车载服务无法启动调查,PMS优化:

  • 一个应用车机目录存在安装了,通过adb shell pm path +包名能够查到。说明包代码被PMS应该解析了。(之前出现过一次,查不到,只是apk包存在,这个是因为签名不是系统签名,所以可能没有解析成功,通过packagemanager或者packagemanagerservice应该能够搜索到Log, 一般是pms解析失败了)

  • 通过adb shell am startservice -n 类名+包名启动后报错了,报Error: Not found; no started

  • 个人尝试修改调整am的参数,添加Action。不起作用

  • 尝试给APP添加一个activity, am start  activity也无法启动

  • 最后查Log,PMS相关的log,引申到博客中pm相关指令,学习了adb shell pm list packages -d,这个命令能够列举出设备中被disable的包,查完果然是改APK被pms禁用了。 这其实是多车型或者高低配车型禁用提升性能的优化项。 然后就和需求对上了,确实低配车型没有这个需求,所以无法启动这个进程的任务服务和页面,学到了PMS的高级用法blog.csdn.net/xiaokangss/…](p6-juejin.byteimg.com/tos-cn-i-k3…?)

Android automotive车载平台介绍

Android 因为 Swap内存交换太高导致的,整车卡顿问题优化

当系统的kswapd 启动过于频案,导致系统 CPU 上升,同时系统内存还有剩余的时候比如500M以上,可以尝试优化启动参数:www.jianshu.com/p/542eeb7e7…

当内存紧张时,优先换出无脏数据的page cache (文件页包含page cache) ,直接丢弃。其次才是匿名页和有脏数据的文件页的回收。遵循URL老化规则。通过Swappiness来确定更倾向于回收哪种更多一点,swappiness越大,越倾向于回收匿名页,反之越倾向于回收文件页。

swapness=0则意味着不再交换匿名页,swapness=100,尽量交换匿名页,Swappiness默认值为60

解决方案: FW层修改参数

Android9/AOSP/device/qcom/common

rootdir/etc/init.qcom.post boot.sh

修改init.qcom.post boot.sh的参数

其中所有的echo 100 > /proc/sys/vm/swappiness调整我echo 20 > /proc/sys/vm/swappiness。 默认值60,20的话,会严重降低交换次数, 因为内存交换的bug不再现,但是需要注意整车的应用内存优化问题,一般导航,语音助手,设置,三方多媒体等

Android原生音源焦点和音源仲裁:

  • 焦点申请:关于原生音源的切换,可以从系统测音源的申请和释放逻辑去分析。

requestAudiofocus0 from uid/pid: 应用主动申请焦点

abandonAudioFocus0 from uid/pid 应用主动放弃焦点。

  • 音源仲裁:关于音源仲裁的比如Vr出现其他声音降音,比如报警音B/e-call出现后的其他媒体降音等都算音源仲裁的范畴

Android界面层级设置:

  • DisplayContent类中的 SurfaceControl.Transaction类能够支撑各种Surface界面渲染的时候的界面层级设置。

关于分屏或者输入法的界面层级等设置,Android原生中通过

Android9/AOSP/platform/frameworks/base

services/core/java/com/android/server/wm/DisplayContent java中得DisplayContent类去控制。

void assignStackOrdering(SurfaceControl.Transaction t)方法中 Transaction类能够设置界面层级,比如给分屏线设置界面层级。

if (s.inSplitScreenWindowingMode() && mSplitScreenDividerAnchor != null) {         t.setLayer(mSplitScreenDividerAnchor, layer++);

}

Android 性能调查:打开IO相关的Log的监控:

后续可以使用iotop的log文件去查看IO

Android9/AOSP/platform/vendor/XXXX/common下tools/init.logcat.sh

Android启动优化:bootchart使用和分析

1、参考这个博客:www.jianshu.com/p/552973365…

2、进一步优化的操作思路,参考个人飞书文档

Android 网络访问,流量监控,流量使用过多的调查:

adb shell tcpdump -vv -w /sdcard/hehe.pacp获取文件

然后使用WiresShark软件分析下。

www.jianshu.com/p/51825ceff…