一、配置环境
Android Studio中使用的 gradle 版本一般不是*新版,所以在使用其自带的 Terminal 时容易报版本过低的错误,为了方便使用,我从 gradle
官网下载了*新版的 gradle ,然后配置好 gradle 的环境变量以方便使用。
二、gradle task 相关内容
gradle 本身不提供查看 library 依赖关系的命令,幸好 Android Studio 提供了可供查看的 task ,位于各个 module 的 help 任务堆中,如下图:
双击 dependencies 执行该任务,可以看到在 gradle console 中均没有得到依赖关系,结果如下图所示:
从上图可以看出无论我们执行哪个 module 下的 dependencies 其结果都是相当于在 Root project 执行了该任务;那么在 app project 或者 test01library project 中执行该 dependencies 任务呢?此时就需要我们通过命令行的方式执行 dependencies 了。
1.查看 app project 的依赖关系
在该路径下打开命令行工具,输入
gradle dependencies
稍等一会,便可看到 library 的依赖关系,如下图所示:
但是命令行中会生成大量内容,并且无法看到全部信息,为了方便查看,我们将输出信息写入文本文件中
gradle dependencies >log.txt
在当前目录下将生成一个 log.txt 文件里面包括所有 app project 所依赖 library 的所有依赖关系(test01library 同理) 。
2.查看指定类型的依赖关系
由于 dependencies 的配置类型太多这里仅以编译时 library 为例说明:
// 查看 compile 时的依赖关系
gradle dependencies –configuration compile
关于其他配置类型可以通过这条命令获得:
gradle dependencies –info
可以看到有很多参数
3.在 Root project 下查看依赖关系
在项目根目录下我们可以通过下面命令达到和上面相同的效果,如:
// gradle :project name:dependencies [–configuration compile]
gradle :app:dependencies –configuration compile
三、总结
查看各 library 的依赖关系是为了避免出现java.util.zip.ZipException: duplicate entry exception android/support/vX/…/xxx.class 异常;由于 app project 必定会直接或间接引用其他所有 project, 所以,只查看这一个 project 的依赖关系即可得到全部信息。
一.问题抛出
- android运行的时候难免会有一些空指针(NullPointerException)或者下标越界(IndexOutOfBoundsException),用户使用的过程操作某一个按钮的时候,就发生了崩溃.这时候可能还没有到他感兴趣的部分,程序就Crash掉了,因此导致了用户流失
- 在集成一些第三方库的时候,我们不能修改里面的实现(例如 Gson,FastJson,OkHttp,OkSocket,Glide)等,那么如果他们里面抛出异常如何解决,Glide加载图片之后填充图片时,如果Activity销毁就会造成崩溃,那么我们如何解决?
二.解决效果
预防崩溃演示效果图.gif
三.解决思路
- MainLooper一定要保证在崩溃的时候持续Loop
- 子线程发生崩溃,保证主线程Looper继续Loop
- 当绘制,测量,布局出现问题导致编舞者Crash时,应该及时处理(关闭当前异常的界面)
- 生命周期方法发生了异常,在ActivityThread里面hook其中的Instrumentation.进行代理.
- 对ActivityThread中的mH 变量添加Callback,对于不能再Instrumentation中处理的异常进行再次Catch.*大限度保证不崩溃.
四.成品Library
Github项目地址: https://github.com/xuuhaoo/DefenseCrash (欢迎Star)
集成方法:
- Please add the code into your project gradle file
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
We provide you two options for choosing:
- Options 1: You should manually install the defense as following code
-
public class MyApp extends Application implements IExceptionHandler {
-
-
protected void attachBaseContext(Context base) {
-
super.attachBaseContext(base);
-
-
DefenseCrash.initialize();
-
-
DefenseCrash.install(this);
-
-
-
-
public void onCaughtException(Thread thread, Throwable throwable, boolean isSafeMode) {
-
-
throwable.printStackTrace();
-
-
-
-
-
public void onEnterSafeMode() {
-
-
-
-
-
public void onMayBeBlackScreen(Throwable throwable) {
-
-
-
-
-
- Options 2: To facilitate some users, we provide a DefenseCrashApplication super class for you to integrate,as following code
-
public class MyApp extends DefenseCrashApplication {
-
-
public void onCaughtException(Thread thread, Throwable throwable, boolean isSafeMode) {
-
-
throwable.printStackTrace();
-
-
-
-
-
public void onEnterSafeMode() {
-
-
-
-
-
public void onMayBeBlackScreen(Throwable throwable) {
-
-
-
-
-