本文公众号「AndroidTraveler」首发。java
今天跟你们讲讲解决问题通用的一个方法论。android
在实际开发过程当中,咱们不可避免的会遇到一些 bug。git
那么对于 bug 或者咱们没有遇到过的问题,怎么处理呢?github
本篇层层递进,一步一步跟你讲解。app
各位若是有其余方法或者补充的欢迎留言交流。oop
若是全篇看完,你发现本身平时就是这么处理的,那么恭喜,你有本身的一套处理问题的方法论。源码分析
本次讲解以本人 Android 开发(演示代码之类的)为例进行讲解,可是都是通用的。学习
这个实际上是解决问题或者 bug 最直接的方式了。测试
尤为是奔溃栈信息能够直接定位到项目里面具体文件具体报错位置时。网站
好比下面的空指针异常:
2019-05-24 13:41:10.031 15019-15019/com.nesger.androidproject E/AndroidRuntime: FATAL EXCEPTION: main Process: com.nesger.androidproject, PID: 15019 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nesger.androidproject/com.nesger.androidproject.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference at com.nesger.androidproject.MainActivity.onCreate(MainActivity.java:13) at android.app.Activity.performCreate(Activity.java:7183) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
能够很明显的看到是空指针异常致使的,并且根据奔溃栈信息能够定位到具体的文件,从下面这一行
at com.nesger.androidproject.MainActivity.onCreate(MainActivity.java:13)
能够看出奔溃发生在 MainActivity.java 这个文件的 onCreate() 方法。具体在该文件 13 行。
具体的缘由根据奔溃栈也能够看出是使用 null object 去调用 equals 方法。
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
代码里面也确实是这样:
除了空指针,诸如 IndexOutOfBoundsException 也是常见的,均可以经过奔溃栈信息快速解决。
假设你的问题不能经过栈信息直接获得解决,那么接下来就是善用搜索引擎。
通常搜索引擎一级入口就是 Google、百度等。
实际上问题的解决方法是在二级入口,好比 Stack Overflow、简书、掘金等网站上。
因此若是你熟悉或者一级入口没有找到,能够直接在二级入口进行搜索。
搜索的时候注意一些小技巧,举个例子:
在 Android 里面一些实现能够在 xml 配置,也能够经过代码动态设置。
若是你的目标是要获取代码动态设置的,通常在你搜索的关键信息以后加上 programmatically。
官方渠道其实指的是官网或者官方论坛。
举些我学习 Flutter 过程当中解决问题的例子。
在原生项目嵌入 Flutter 的时候,参考的是 Flutter 在 GitHub 上面的 WIKI。
在运行出现 crash 时,解决是经过 Flutter 在 GitHub 上面的 Issues。
因此我这里就是到 flutter 官方的 GitHub 项目上面去寻找问题的解决方法。
当上面三个方法都不能解决你的问题时,这个时候你就要结合具体业务进行具体分析,而后深刻源码找到本质问题,进行对应处理。
好比我以前写过的一篇文章:
遇到的问题就是业务须要识别反转二维码。
前面提到的三个方法论都不能解决,属于很小众的需求。
这种状况下我就分析了一下需求。需求是二维码的识别,而二维码识别核心就是图像获取和解码。那么经过分析源码的解码过程,是否是就能够解决这个问题呢?最后证实是能够的。
又好比说咱们的业务使用了 GraphQL,而官方 GraphQL 并无提供对 Flutter 的直接支持。
这个时候我在 GitHub 上面发现了一个仓库:https://github.com/zino-app/graphql-flutter
这个仓库提供了 Flutter 对 GraphQL 调用的支持,可是实际测试过程当中发现有个问题,那就是错误没有回调。
这个时候我经过深刻源码,打印日志,发现错误确实有被 catch,可是没有回调回来,说明可能回调里面的代码有问题。
所以我经过实际例子测试并提了一个 PR,最终代码合并解决了这个问题,固然也帮助其余遇到这个问题提 issue 的小伙伴。
因此遇到问题你能够提 issue 被动等待做者解决,也能够主动出击,分析源码,经过实际例子证实代码存在 bug,须要修复。
PR:https://github.com/zino-app/graphql-flutter/pull/162
这个之因此放在最后是由于,这个方法是一把双刃剑,用的好你会成长,用很差你会给本身加上枷锁。
咱们先说说好的一方面:
假设你按照前面 4 个方法论依然无法解决这个问题,那么你能够请教他人来解决这个问题。若是他人知道这个问题的解决方法,那么你不止知足于这个问题的解决,过后你还须要进行总结。
总结为何他人能够解决这个问题:
是经验问题?
仍是有一些其余渠道你以前没有考虑?
是否更新完善上面的解决问题方法论?
经过这样的不断总结,你后面须要请教他人的次数会愈来愈少。或者真的你解决不了须要请教他人的时候,可能他人也不清楚。由于他的方法论你都熟悉了,而你也是如此去完善的。
接下来讲说很差的一方面:
假设你遇到问题,你就请教他人,解决问题以后就不理了。后续有问题依然如此循环往复,那么结果你获得的就是依赖性。假设后面有相似问题存在,而别人没空回答你,你就不知道要怎么办了,由于你没有一套本身解决问题的方法论。并且由于你以前已经善于依赖别人解决问题了,所以你如今会很迷茫,不知道如何下手。再者,你们都很忙,你请教他人,他人不必定会回答你,至于何时回答你,以及答案是否正确,都是不可预知的。
假设咱们要帮助别人,我仍是提倡授人以渔而不是授人以鱼。
最后我再说一下关于请教他人这个问题:
别人没有义务帮你解决问题,因此若是别人没回答你的问题,这是正常的。
若是别人回答你的问题,解决你的问题你能够表示感谢,没有解决也不用吐槽。
最好的方式仍是本身解决问题。
总结:
1. 根据奔溃栈信息
2. 善用搜索引擎
3. 经过官方渠道
4. 深刻源码分析
5. 请教他人