bug练习1 车载蓝牙设备共享2000个联系人

学到的:
1. anr是什么
2. anr的时候会dump出一个log
3. log的结构,有哪几个部分组成
4. broadcastReceiver的onReceive方法的执行线程
5. 清晰理解bug报告(将bug重现一次)

[all;100%;yijun.xu]–[共同cell_REV01]–BT carkit
Pre: insert GSM card ,inport 2000 contacts and some MP3
Occur Process: connect Santa Fe Sport state/KIA MOTORS–>contact–>share namecard via
–>multiple contacts–>select all–>done–>Bluetooth–>Santa Fe Sport
–>it will receive a alert:BT send fail–>retry
Occur status: test phone lock up,and then screen become black,after a while,pop up ANR

理解问题

  1. 注意几个名词的意思:
    Santa Fe Sport state/KIA MOTORS //两款车载蓝牙设备
    it will receive a alert:BT send fail–>retry //出现失败通知,点击重试
    ANR //程序没有相应

  2. 重新描述问题:
    对某个车载蓝牙设备共享2000个联系人时,显示失败后,点击重试。然后手机没有响应,黑屏,过一会后显示ANR。

分析问题

  1. 查阅资料和经验得知,ANR出现一般是由于:

    • 没有响应用户输入5s以上
    • broadcast没有10s内处理完毕

    bug描述中强调2000个联系人,猜测是由于耗时操作处理不当引起的anr。

    根据个人经验,程序无法响应一般是由于主线程堵塞引起的,或者是线程的运行时间超过了某个上限。

  2. 阅读log:

    打开dumpstate_app_anr-2014-05-20-14-47-00.txt, 搜索“anr”,有以下结果:


    05-20 14:46:08.327 3312 3312 D CrashAnrDetector: Subject: Broadcast of Intent { act=android.bluetooth.devicepicker.action.DEVICE_SELECTED flg=0x10 cmp=com.android.bluetooth/.opp.BluetoothOppReceiver (has extras) }

    可得知anr的类型是“Broadcast timeout”。查阅代码得知DEVICE_SELECTED由BluetoothOppReceiver注册,查阅BluetoothOppReceiver代码后,没有发现涉及耗时操作的语句。
    又由于BluetoothOppReceiver是在xml中声明的,所以它的onReceive会在主线程中运行。所以推断timeout的原因是由于主线程堵塞。

    于是查看一下当时系统的各个进程和线程的调用栈的情况。
    打开dumpstate_app_anr-2014-05-20-14-47-00.txt,搜索“main”,有以下结果:

    得知当ANR发生时,主线程正在运行数据库相关操作:generateFileInfo。因此猜测ANR的出现是由于该函数在主线程上运行太久所导致的。
    但是经过询问,该bug的出现需要多次重复Occur Process,说明generateFileInfo的运行时间不确定。

代码分析

继续进行分析,generateFileInfo中涉及ContentResolver的query操作。查阅资料得知,ContentProvider是线程安全的,但是某一时刻只能处理一种操作。于是推断是由于竞争ContentProvider的使用权导致generateFileInfo的运行时间不确定。
在前一次传输失败后,BluetoothOppTransfer会调用markBatchFailed方法,其中涉及ContentProvider的update方法。
于是推断bug是由于generateFileInfo和markBatchFailed竞争ContentProvider的使用权导致ANR。

但未能在log中找到上述推断的明显证据。

方案

  1. 总结
    • 没有仔细研究bug报告导致误解retry一词。
    • 经验不足,对anr不熟悉,不止从何下手。
    • 阅读和分析log的技能很不足,很多信息一开始的时候没有挖掘出来,例如查看线程的调用栈、anr的log文件等等。

bug练习2 车载设备三方通话合并

题目:BT carkit , missing conference options

[all; 100%; Xian Xiaohong]_[共同cell]_BT carkit
Pre: BT connect with carkit[MB BLUETOOTH]; insert 3 way calling card
Occur Process: on call conversation -> outgoing second call by carkit -> after it , make 3 way calling by carkit
Occur State: haven’t options “conference”

分析问题:

查看log:

分析代码

经验教训

免费的天气api以及一些需要注意的地方

免费的天气api

网络上可以找到许多免费获取天气信息的api,大多是遵循着以下流程:

获取的数据一般是json格式。

这里推荐一个API接口:

分别是获取城市编号接口和获取天气信息接口。

这两个接口的速度和稳定性都不错,推荐使用。

返回结果的编码

在用python通过这个api获取到json格式的天气数据后,发现某些城市的数据解释不了。

用repr()函数打印返回结果,发现部分城市(例如广州)的数据的头部多了3个字节:\xef\xbb\xbf。这是什么呢?

google了一番,原来这个是BOM。返回结果是一个”UTF-8+BOM”。这三个字节头表明数据是以utf-8编码的。

那么怎么兼容这种情况呢?又google了一番。找到了如下解决方案:

无论是否带BOM,结果都为不带BOM的str。

[BetterExplained]重新认识极限

文章大部分参考这里,加上自己的一点理解而已


什么是极限

构想下面一个画面:

https://i2.wp.com/betterexplained.com/wp-content/uploads/limit_intro/soccer-limits.jpg?w=840

如图所示,4.00时刻的画面由于缓冲跳过了。我们无法得知这个时刻球的位置,但是我们可以作出一个估计:

球在3:59时和4:01时球的位置之间的某个位置上

由于现实世界中球的轨迹是连续的,所以这是一个很不错的估计。

但是!如果在3:599时球突然被外星人以极快的速度吸走,在4:001时按照原来的速度和方向放回来,那么我们的估计就不正确了(尽管这不太可能发生,但是必须考虑)。

那么,如果我们把镜头放慢,慢到看得清外星人的存在,那么我们可以重新做一个更准确的估计。例如我们可以通过慢镜头,估计球在4:00的位置为“3:59.999和4:00.001的位置之间”。

假设3:59时球在9.9米处,4:01时球在10.1米处,我们可以换一种说法:

可以感性地得知,在例子中,当这个缩放级别越小时,我们便越有信心估计球的位置(如果在某个级别中发现发现球的位置发生了意外的变化,那么便很有可能要推翻10m的估计,要进一步缩小级别来确定球的位置)。

对数学极限定义的另一种理解

理解了上面的例子后,我们来看一看官方对极限的定义(official definition):

lim(x->c) f(x) = L

means for all real ε > 0 there exists a real δ > 0 such that for all x with 0 < |x − c| < δ, we have |f(x) − L| < ε (对于所有ε>0,存在一个δ > 0,使得对于所有x满足0 < |x − c| < δ,都有|f(x) − L| < ε)

可以按照以下的方式去理解:

也就是说,如果这个估计是正确的(或者说无限有信心的),那么对于一个任意小误差范围ε,总可以找出一个缩放级别δ,令到与c距离小于δ的x(0 < |x − c| < δ),满足f(x)的值和L之间的距离在误差范围ε内。

极限存在的必要条件是“对于任意小的误差范围总可以找到相应的缩放级别”,这个条件保证了不会漏掉“中途被外星人吸走又放回去”的情况。

也就是说:

证明极限存在

举一个例子:

例子

证明x=2时极限存在

我们不可以直接代入2来说明极限存在并且为5,因为(x – 2)作为分母,其值不能为0。当时当 x != 2时,我们可以将其代入,然后消掉分子和分母的(x – 2),得到f(x) = 2x + 1。

这时我们作出一个估计,当x=2时,f(x)的值为5。

我们无法得知f(2)的值,但是我们可以证明f(2)=5的估计是无限准确的。

假设允许的误差范围为+-1.0,我们有:

当x在0.5到2的区间内取值时,所有的f(x)都满足|f(x) – 5| < 1.0。

下一步我们加入error tolerance (ε) 令到这个误差区间变成任意的:

由于x – 2是单调而且连续的,所以总能找到一个x的范围,使得范围内的所有x和2的距离在+-0.5 · ε内,于是我们的估计可以无限地准确了。

函数连续(A function is continuous)

当我们说一个函数在某个区间内连续(continuous)的时候,是指它在这个区间内处处可以准确地估计,也就是:

ps:这里这是一篇通俗的传统的解释极限的文章