Android studio 如何查看 library 间的依赖关系

一、配置环境
Android Studio中使用的 gradle 版本一般不是*新版,所以在使用其自带的 Terminal 时容易报版本过低的错误,为了方便使用,我从 gradle
官网下载了*新版的 gradle ,然后配置好 gradle 的环境变量以方便使用。

二、gradle task 相关内容
gradle 本身不提供查看 library 依赖关系的命令,幸好 Android Studio 提供了可供查看的 task ,位于各个 module 的 help 任务堆中,如下图:

%title插图%num

%title插图%num

双击 dependencies 执行该任务,可以看到在 gradle console 中均没有得到依赖关系,结果如下图所示:

%title插图%num

从上图可以看出无论我们执行哪个 module 下的 dependencies 其结果都是相当于在 Root project 执行了该任务;那么在 app project 或者 test01library project 中执行该 dependencies 任务呢?此时就需要我们通过命令行的方式执行 dependencies 了。

1.查看 app project 的依赖关系
在该路径下打开命令行工具,输入

gradle dependencies

稍等一会,便可看到 library 的依赖关系,如下图所示:

%title插图%num

但是命令行中会生成大量内容,并且无法看到全部信息,为了方便查看,我们将输出信息写入文本文件中

gradle dependencies >log.txt

在当前目录下将生成一个 log.txt 文件里面包括所有 app project 所依赖 library 的所有依赖关系(test01library 同理) 。

2.查看指定类型的依赖关系
由于 dependencies 的配置类型太多这里仅以编译时 library 为例说明:

// 查看 compile 时的依赖关系
gradle dependencies –configuration compile

关于其他配置类型可以通过这条命令获得:

gradle dependencies –info

可以看到有很多参数

%title插图%num

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 studio 导入外部库文件,以及将项目中module变成library引用依赖

android studio 导入外部库文件,以及将项目中module变成library引用依赖

一:导入如百度地图等的外部类。

步骤:1.首先 将androidstudio项目显示切换到 project 状态显示项目

2.然后添加.jar文件,将所有的.jar文件放入libs文件夹内(libs文件夹就在项目文件夹下),然后在引入的.jar文件上右键然后点击 Add As Library… OK jar文件引入。

3.添加.so文件,在项目下的src目录下的main目录下新建jniLibs文件夹,然后将so文件连带着他外面的文件夹整个复制到jniLibs文件夹下(注意:so文件不能直接存在于jniLibs文件夹下,需要存在于如armeabi等文件中放入jniLibs文件夹下),倒入文件后在该文件的build.gradle中添加。(为了保证不出错,可以将.jar文件放入JinLibs将so文件放入libs文件中,使得libs跟jniLibs文件夹下都存在so跟jar。)

sourceSets{
    main(){
        jniLibs.srcDirs = ['libs']
    }
}
代码。具体放入位置如下:

apply plugin: 'com.android.library'
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets{
        main(){
            jniLibs.srcDirs = ['libs']
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile files('libs/BaiduLBS_Android.jar')
}
现在就可以使用外部类的方法了。

二:将同项目的module作为依赖包引用
1.选择你想作为library的module。选择他的build.gradle文件将*上方的代码apply plugin: 'com.android.application'改为apply plugin: 'com.android.library'。然后将下面的代码删去位置为:android下的defaultConfig下的applicationId "frame.myc.com.mycframe"。删除后代码为
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets{
        main(){
            jniLibs.srcDirs = ['libs']
        }
    }
}
2.为主文件添加依赖 mac下使用以下操作:点击file->project structure左边的module下选择你的主工程,然后右边点击dependencies,点击下方或者右方的+点开后在三个选项中选择module dependency,在弹出界面选择你刚刚修改作为library的midule文件 ok了。
其实*简单的方法就是刚开始建立module的时候就作为library来新建。仔细去新建一个module来体会一下,在选择模式的时候选择library就可以啦


出现错误:当你的程序需要引用两个及以上的module library或者其他的jar包是出现错误类型如下

Error:Execution failed for task ‘:app:transformResourcesWithMergeJavaResForDebug’.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK org/apache/log4j/xml/log4j.dtd
File1: /Users/minyuchun/androidwork/projectstudio/StarFaceFrame/app/build/intermediates/exploded-aar/StarFaceFrame/facelibrary/unspecified/jars/classes.jar
File2: /Users/minyuchun/androidwork/projectstudio/StarFaceFrame/app/build/intermediates/exploded-aar/StarFaceFrame/rylibrary/unspecified/jars/classes.jar

出现上述错误的原因是因为 你在引用的labrary中多个存在相同的包导致在打包是冲突 解决方式如下,在android下的 写
packagingOptions{
  exclude 'org/apache/log4j/xml/log4j.dtd'
}
''单引号中的内容为上述错误中APK后面的内容,按照上述的样式填写在 主的app.gradle 中,重新编译后运行,运行后还可能出现相同的错误 这时候请注意错误后面APK中的内容 此时应该与前一次出现的内容不相同。如果是这样的话继续按照上述的方式增加,循环*后就没有这个错误了。

%title插图%num 

 

Android错误崩溃拦截

一.问题抛出

  • android运行的时候难免会有一些空指针(NullPointerException)或者下标越界(IndexOutOfBoundsException),用户使用的过程操作某一个按钮的时候,就发生了崩溃.这时候可能还没有到他感兴趣的部分,程序就Crash掉了,因此导致了用户流失
  • 在集成一些第三方库的时候,我们不能修改里面的实现(例如 Gson,FastJson,OkHttp,OkSocket,Glide)等,那么如果他们里面抛出异常如何解决,Glide加载图片之后填充图片时,如果Activity销毁就会造成崩溃,那么我们如何解决?

二.解决效果

%title插图%num

预防崩溃演示效果图.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'

%title插图%num

  • maven { url 'https://dl.bintray.com/xuuhaoo/maven/'}
  • %title插图%num
  • Make sure you already done with above instructions in project gradle
    files, than you need put this into Module build.gradle file
  • //崩溃预防,可以避免空指针等崩溃错误
      compile 'com.tonystark.android:defense_crash:2.0.0'
  • %title插图%num

We provide you two options for choosing:

  • Options 1: You should manually install the defense as following code
  1. public class MyApp extends Application implements IExceptionHandler {
  2. @Override
  3. protected void attachBaseContext(Context base) {
  4. super.attachBaseContext(base);
  5. // step1: Initialize the lib.
  6. DefenseCrash.initialize();
  7. // setp2: Install the fire wall defense.
  8. DefenseCrash.install(this);
  9. }
  10. @Override
  11. public void onCaughtException(Thread thread, Throwable throwable, boolean isSafeMode) {
  12. // step3: Print the error when crashed during runtime.
  13. throwable.printStackTrace();
  14. // step4: Upload this throwable to your crash collection sdk.
  15. }
  16. @Override
  17. public void onEnterSafeMode() {
  18. // We enter the safe mode to keep the main looper loop after crashed.You’d better do nothing here,we just notify you.
  19. }
  20. @Override
  21. public void onMayBeBlackScreen(Throwable throwable) {
  22. // onLayout(),onMeasure() or onDraw() has breaks down,
  23. // it causes the drawing to be abnormal and the choreographer to break down.
  24. // We will notify you on this method,you’d better finish this activity or restart the application.
  25. }
  26. }
  • Options 2: To facilitate some users, we provide a DefenseCrashApplication super class for you to integrate,as following code
  1. public class MyApp extends DefenseCrashApplication {
  2. @Override
  3. public void onCaughtException(Thread thread, Throwable throwable, boolean isSafeMode) {
  4. // step1: Print the error when crashed during runtime.
  5. throwable.printStackTrace();
  6. // step2: Upload this throwable to your crash collection sdk.
  7. }
  8. @Override
  9. public void onEnterSafeMode() {
  10. // We enter the safe mode to keep the main looper loop after crashed.You’d better do nothing here,we just notify you.
  11. }
  12. @Override
  13. public void onMayBeBlackScreen(Throwable throwable) {
  14. // onLayout(),onMeasure() or onDraw() has breaks down,
  15. // it causes the drawing to be abnormal and the choreographer to break down.
  16. // We will notify you on this method,you’d better finish this activity or restart the application.
  17. }
  18. }