概述
本文收集平常工作过程中遇到的一些常见问题,遇到的一些坑,把它们记录下来,以便日后再次遇到能快速排查。
无法下载版本问题:
确认主板中是否有download过软件——直接接电源开机,如可以开机,可以断定此主板已经down过版本了;如果无法开机,尝试焊接串口线,抓一下log,看看在哪一步停下来走不下去了。
一般而言,可以开机但是不能下载的,存在两种可能:
①新软件中未兼容主板上的Memory物料;
②分区表更新了。
对于这第一种情况,可以通过查配置表,找到Memory物料型号,然后跟软件开发人员核对,是否有兼容;或者查看flash download工具的log,发给开发人员,通过Memory ID来确认是否兼容该物料。
对于第二种情况,通常可以选择upgrade的升级方式,如实在不行,可以导出校准参数,然后格式化下载新软件,最后重新导入校准参数。如果遇到无法开机,又无法下载的,可能有三种种情况:
①软件中未兼容主板上的Memory物料;
②下载工具版本过旧,不支持当前平台的下载;
③主板有异常,尤其Memory可能有损坏。
第一种情况跟上面类似,不再赘述。第二种情况,可以先直接换一个新版本工具试试能否下载,如可以下载,说明工具需要更新,如仍然无法下载,说明跟工具无关。第三种情况,可以多找几块主板,如果有一块可以下载软件,基本就可以判断无法下载的主板存在硬件上的损坏。不开机问题:
1、 按开机键没有反应,屏幕不亮,用电源连接时发现电流无变化。这种情况,有两种可能:
①主板开机键或电池连接异常;
②单块主板损坏;
第一种情况,可以直接使用电源,然后用镊子连接主板power key测试点与地,如可以开机,说明开机键或电池异常;
第二种情况通常需要硬件同事介入分析。
2、开机到某个阶段停止不动。类似这样的情况,可以直接抓log分析。
比较实用的方法:①抓取不开机的uart log,部分手机不开机,同时抓取正常开机的uart log对比分析;②如果开机到android界面,可使用adb logcat -v time > log.txt获取上层log信息。部分手机开机时间非常长:
此类问题很大可能性是由于外设在读ID导致的,直接抓log查看即可。最方便的方式就是直接抓串口log来分析。此外还可以用adb shell logcat –v time > 123.txt来抓取上层log来分析。开机背光亮,有开机铃声,屏幕没有显示:
一般而言,问题在于屏没有兼容或者屏/主板单体损坏。如果是单体问题,我们可以做交叉实验,分析问题是主板还是屏导致的。如果全部显示都不对,可以跟软件开发同事确认是否软件不对,或者抓串口log,确认屏ID是否读到。Camera应用丢失,Camera切换按钮丢失:
在MTK平台上,Camera的识别是在开机过程中完成的。如果开机时没有识别到任何Camera,开机之后Camera应用就会直接影藏;如果只识别到一个Camera,Camera切换按钮就是影藏。
1、如果有发现手机开机之后,Camera应用丢失,可以通过以下步骤去:
①将手机恢复出厂设置,然后重新开机,此时如果Camera应用显示出来,且多次使用都正常了,说明之前该机器很有可能是先开机过,然后再安装Camera的。
②如果恢复出厂设置还是无法显示Camera应用,首先需要确认此问题是单体(或小概率)问题还是大批量问题。单体问题的话,就需要去排查Camera焊接/连接是否正常。如焊接/连接正常,接着做交叉实验,确认是模组问题还是主板问题。模组问题就安排模组厂分析,主板问题就合硬件沟通解决。如果是大批量问题,一方面需要让模组厂参与进来分析,另一方面需要排查软件/硬件。软件上可以抓串口log给软件同事分析,硬件上排查走线、供电是否有异常。
③如果切换异常,通常是某个Camera的ID没有读到。可以在拨号界面输入“_##9375##_”(仅适用于MTK平台),确认下是否是没有读到ID,如确实ID没有读到,一方面检查Camera焊接/连接是否正常,另一方面抓下串口log给软件同事分析。Camera花屏/闪绿线:
遇到Camera使用过程中花屏/闪绿线的问题,我们可以从两个方向去排查问题。首先还是按照惯例统计花屏的概率,如果是单体问题,需要去确认Camera数据线是否有问题,直接测量数据线信号即可,将波形发生给硬件同事检查。然后做交叉实验,确认是模组问题还是主板问题。模组问题让模组厂来分析,主板问题可以跟硬件沟通处理。
如果大批量都有问题,需要软件和硬件同事介入分析。软件上尝试修改Camera驱动能力,优化一个最好的组合,硬件上尝试包导电布、做接地处理。
技巧 Android 打印堆栈
Java 方法打印堆栈1
2
3
4RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Log.w("eric", "Called: " , here);
//here.printStackTrace();
如在PanelView的onTouchEvent方法中打log后,调用堆栈如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
4501-03 17:53:39.860 8861 8861 W eric : Called:
01-03 17:53:39.860 8861 8861 W eric : java.lang.RuntimeException: here
01-03 17:53:39.860 8861 8861 W eric : at com.android.systemui.statusbar.phone.PanelView.onTouchEvent(PanelView.java:265)
01-03 17:53:39.860 8861 8861 W eric : at com.android.systemui.statusbar.phone.NotificationPanelView.onTouchEvent(NotificationPanelView.java:860)
01-03 17:53:39.860 8861 8861 W eric : at android.view.View.dispatchTouchEvent(View.java:11781)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2962)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2643)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
01-03 17:53:39.860 8861 8861 W eric : at com.android.systemui.statusbar.phone.StatusBarWindowView.dispatchTouchEvent(StatusBarWindowView.java:290)
01-03 17:53:39.860 8861 8861 W eric : at android.view.View.dispatchPointerEvent(View.java:12020)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4809)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4623)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4214)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4180)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4307)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4188)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4364)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4214)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4180)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4188)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6682)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6656)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6617)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6785)
01-03 17:53:39.860 8861 8861 W eric : at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
01-03 17:53:39.860 8861 8861 W eric : at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
01-03 17:53:39.860 8861 8861 W eric : at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:177)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6756)
01-03 17:53:39.860 8861 8861 W eric : at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6808)
01-03 17:53:39.860 8861 8861 W eric : at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
01-03 17:53:39.860 8861 8861 W eric : at android.view.Choreographer.doCallbacks(Choreographer.java:723)
01-03 17:53:39.860 8861 8861 W eric : at android.view.Choreographer.doFrame(Choreographer.java:652)
01-03 17:53:39.860 8861 8861 W eric : at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
01-03 17:53:39.860 8861 8861 W eric : at android.os.Handler.handleCallback(Handler.java:790)
01-03 17:53:39.860 8861 8861 W eric : at android.os.Handler.dispatchMessage(Handler.java:99)
01-03 17:53:39.860 8861 8861 W eric : at android.os.Looper.loop(Looper.java:164)
01-03 17:53:39.860 8861 8861 W eric : at android.app.ActivityThread.main(ActivityThread.java:6501)
01-03 17:53:39.860 8861 8861 W eric : at java.lang.reflect.Method.invoke(Native Method)
01-03 17:53:39.860 8861 8861 W eric : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
01-03 17:53:39.860 8861 8861 W eric : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
01-03 17:53:39.877 8861 8861 I chatty : uid=10034(com.android.systemui) identical 1 line
查看View属性的值
发现安卓里一个牛逼的开发工具ViewDebug.ExportedProperty
Android 中Trace log
在Android中经常看到Trace.beginSection之类的代码如下:1
2
3
4
5
6
7public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation");
Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
new StartKeyguardExitAnimParams(startTime, fadeoutDuration));
mHandler.sendMessage(msg);
Trace.endSection();
}
参考资料
Android下打印调试堆栈方法
https://blog.csdn.net/u013270444/article/details/53012976
发现安卓里一个牛逼的开发工具ViewDebug.ExportedProperty