Android进阶——transformDexArchiveXxx、NoSuchMethodError、CMake、Gradle、Conflict with dependency 等错误处理合集

引言

相信很多人在开发工程中都会遇到一些典型的问题,但是并不值得单独写一篇文章进行记录,那样太浪费篇幅了,于是此篇文章应运而生。请移步至那些年踩过的经典Android 的坑

一、transformDexArchiveWithExternalLibsDexMergerForDebug unable to merge dex 问题

造成这样的问题原因有很多,具体问题具体分析,常见处理措施主要有:

  1. 第一种删掉.gradle文件,重新clean再build
  2. 第二种在settings里面打开instant run
  3. 第三种把gradle plugin版本降低至2.3.3 重新编译下

我曾经遇到过是在这样的情景下,
Android studio 从2.3.3升级到3.0,然后gradle也升级了,导致了如下错误:

Error:Execution failed for task ‘:app:transformDexArchiveWithExternalLibsDexMergerForDebug’.

com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex

二、WebView 加载网页的时候报ERR_UNKNOWN_URL_SCHEME

我遇到的是位于baidumap://xxx 的网页无法加载,可在自带的浏览器上却能正确打开并加载而且明明输入的是http://xxx 为何提示中没有了http, 后面发现这是因为这些是自定义的scheme(类似的还有alipays://,weixin:// 等)而WebView只能识别http://或https://开头的url,因此才会报此错,对于这种自定义scheme的url需要进行具体处理:
在这里插入图片描述

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 返回值是true的时候控制去WebView打开(使得点击网页 链接的时候不调用第三方浏览器打开),为false调用系统浏览器或第三方浏览器
                if (url.startsWith("http:") || url.startsWith("https:")) {
                    //屏蔽掉错误的重定向url:"baidumap://six_map/?
                    WebView.HitTestResult hit = view.getHitTestResult();
                    if (hit == null) {// 重定向
                        view.loadUrl(url);
                    } else {
                        return false;
                    }
                }
                //这是处理成跳转到Activity形式的如果不需要就注释掉
                else if(url.startsWith("baidumap://")){
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(intent);
                    return true;
                }
                return true;
            }
        });

三、处理WebView 加载动态网页的时候,先显示部分html或css代码才显示真正要加载的网页内容的问题

发生这种情况的原因在于WebView加载顺序通常是先加载 html ,然后从里面解析出 css 、 js 文件和页面上写死的图片资源进行加载,如果 webkit 的缓存里面有,就不加载。加载完这些资源之后,就进行 css 的渲染和 js 的执行。 CSS 的渲染一般不需要很长时间,几十毫秒就 ok 。关键是 JS 的执行,如果用了 jQuery ,则执行起来需要 可能需要几秒,如果网速渣的话加载内容多的话可能更久,针对这个问题我进行以下一些优化:

  • 首先设置WebView 默认背景,并设置其layerType=“software”
  • 设置WebView的一系列属性
  public void initWebView(WebView webView){
        mWebView=webView;
        mWebView.canGoBackOrForward(1);
        mWebView.getSettings().setJavaScriptEnabled(true);//设置能够解析JavaScript
        mWebView.getSettings().setSupportZoom(true); // 支持缩放
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.getSettings().setDomStorageEnabled(true);
        mWebView.getSettings().setBlockNetworkImage(true);//暂缓加载图片
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//设置缓存模式
        mWebView.getSettings().setDomStorageEnabled(true);
        mWebView.getSettings().setSupportMultipleWindows(false);// 防止否则打开新页签无法加载
    }
  • 在使用WebView的Activity的onCreate方法开启GPU渲染
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
 showLoadingAnim();//显示自定义的Loading
  • 设置使用WebView打开链接
    private void initWebViewClient() {

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                mWebView.clearHistory();
                mWebView.getSettings().setBlockNetworkImage(false);//开始加载网页的图片
                //注入滑动控制通知JS,可以灵活注入
                mWebView.loadUrl(INJECT_JAVASCRIPT);
                mLayout.setWebViewLoaded(true);
                hideLoadingAnim();//隐藏自定义的Loading,有时候需要延时隐藏进度条,因为这个方法被回调的时候并不意味着所有资源加载完毕,
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 返回值是true的时候控制去WebView打开(使得点击网页 链接的时候不调用第三方浏览器打开),为false调用系统浏览器或第三方浏览器
                if (url.startsWith("http:") || url.startsWith("https:")) {
                    //屏蔽掉错误的重定向url:"baidumap://six_map/?
                    WebView.HitTestResult hit = view.getHitTestResult();
                    if (hit == null) {// 重定向
                        view.loadUrl(url);
                    } else {
                        return false;
                    }
                }
                return true;
            }
        });
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.addJavascriptInterface(new JavaScriptInterface(), "nativeInterface");
        HashMap<String,String> headers=new HashMap<>();
        headers.put("Keep-Alive","1000");
        headers.put("Connection","keepalive");
        mWebView.loadUrl(toUrl,headers);//优化链接,添加自定义的Header

    }

四、Execution failed for task ‘:app:preDebugAndroidTestBuild’

Conflict with dependency ‘com.android.support:support-annotations’ in project ‘:app’. Resolved versions for app (26.1.0) and test app (27.1.1) differ. See https://d.android.com/r/tools/test-apk-dependency-conflicts.html for details.

在对应Module 的Gradle脚本下配置

configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-annotations:27.1.1'
    }
}

五、Android 9.0限制了明文流量的网络请求,非加密的流量请求都会被系统禁止掉

虽然将来https 终归会替代http,但是考虑到实际情况并非易事,所以要想明文网络请求也可以在Android 9.0上运行,则可以通过以下两步完成:

  • 在res文件下新建一个xml文件夹并创建一个名为network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

然后在AndroidManifest文件中的application节点配置

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

六、java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedV…

在这里插入图片描述
解决方案:只要把项目的compileSdkVersiontargetSdkVersioncom.android.support:appcompat的版本设置到27以上就OK了。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.crazymo.xglidegif"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
                abiFilters 'armeabi-v7a'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

    configurations.all {
        resolutionStrategy {
            force 'com.android.support:support-annotations:27.1.1'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    //使用Glide 基本Api
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    //需要扩展Glide 时需要引入的类apt编译器
    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
}

七、Execution failed for task ':app:javaPreCompileDebug

在这里插入图片描述
解决方案:在App Module目录下的build.gradle脚本下的android节点中的defaultConfig里配置

android{
...
	defaultConfig{
	...
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath = true
            }
        }
    ...
    }
}

八、Error:Execution failed for task ‘:app:preDebugAndroidTestBuild’.Conflict with dependency ‘com.android.support:support-annotations’ in project ‘:app’. Resolved versions for app (26.1.0) and test app (27.1.1) differ.

只需要在Module下的build.gradle脚本下的android节点里添加以下配置即可

    configurations.all {
            resolutionStrategy {
                force 'com.android.support:support-annotations:27.1.1'
            }
        }

九、AndroidStudio SSL peer shut down incorrectly 问题

AndroidStudio 编译时出现如下问题 SSL peer shut down incorrectly 或者某些jar包下载失败,一般是因为墙的原因导致的。此时就需要配置远程代码库的镜像来解决这个问题,配置的方法就是在根Project下的build.gradle中添加镜像仓库,比如说添加阿里的镜像库

buildscript {

    repositories {
        google()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }
}

allprojects {
    repositories {
        google()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
    }
}

jcenter() 最好配置在最好,因为Gradle 在构建项目时,会按照配置的先后顺序查找对应的。

十、Failed to notify project evaluation listener

我在用配置了高版本的Gradle插件(5.x.x)的Android Studio来打开低版本Gradle插件编译好的项目时,编译工程时遇到了下面的报错:
在这里插入图片描述
首先上面这个问题就是Gradle和Gradle插件的版本不搭配,第一步是修改它们的版本,再次使用
gradlew build --stacktrace进行编译,然后又报以下这个错误:

Caused by: java.lang.NoSuchMethodError: org.gradle.api.tasks.TaskInputs.file(Ljava/lang/Object;)Lorg/gradle/api/tasks/TaskInputs;
        at org.greenrobot.greendao.gradle.Greendao3GradlePlugin.createGreendaoTask(Greendao3GradlePlugin.kt:59)
        at org.greenrobot.greendao.gradle.Greendao3GradlePlugin.access$createGreendaoTask(Greendao3GradlePlugin.kt:14)
        at org.greenrobot.greendao.gradle.Greendao3GradlePlugin$apply$1.execute(Greendao3GradlePlugin.kt:47)
        at org.greenrobot.greendao.gradle.Greendao3GradlePlugin$apply$1.execute(Greendao3GradlePlugin.kt:14)

发现greendao-gradle-plugin和greendao版本号不一致,将它们的版本统一成3.2.2,重新编译即可。

十一、set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true

当把Gradle 插件版本升级到3.1.1以及Gradle 版本升级到4.4以上之后,使用butterknife 7.0.1时再次编译会报以下的错误

 Error:FAILURE: Build failed with an exception.
 
* What went wrong:
    Execution failed for task ':app:javaPreCompileDebug'.
            > Annotation processors must be explicitly declared now.  The following dependencies on the compile classpath are found to contain annotation processor.  Please add them to the annotationProcessor configuration.
    - lombok-1.16.18.jar (org.projectlombok:lombok:1.16.18)
    Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior.  Note that this option is deprecated and will be removed in the future.
    See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
 
            * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
 
* Get more help at https://help.gradle.org
 
    BUILD FAILED in 4s 

这是因为注解处理器的缘故,如果还想沿用之前的版本的话就需要在app下的build.gradle配置:

android {
	...
    defaultConfig {
        javaCompileOptions {
        //编译类路径中的依赖项不需要包含注解处理器时将以下代码includeCompileClasspath=false添加到 啊app下的build.gradle 文件来停用错误检查,这样添加到编译类路径中的注解处理器就不会被添加到处理器类路径中,反之则置为true
            annotationProcessorOptions {
                includeCompileClasspath = true
            }
        }
    }
}

十二、“Error:Error occurred while communicating with CMake server. Check log xxx\Native\app.externalNativeBuild\cmake\debug\armeabi-v7a\cmake_server_log.txt for additional information.”

查看cmake_server_log.txt后显示

"CMAKE SERVER: CMAKE SERVER: [== "CMake Server" ==[ CMAKE SERVER: {"supportedProtocolVersions":[{"isExperimental":true,"major":1,"minor":1}],"type":"hello"} CMAKE SERVER: ]== "CMake Server" ==]"

此问题一般出现在升级Android Studio的 Gradle插件、NDK、CMake版本之后出现的,大部分都是因为版本之间不兼容导致的,我出现问题的开发环境是Android3.5+com.android.tools.build:gradle:3.0.1+gradle-4.0.1-all.zip+Cmake 3.4.1+NDK 17rc,后面我把版本改为:

在这里插入图片描述

十三、The specified Gradle distribution ‘https://services.gradle.org/distributions/gradle-4.4-all.zip’ does not appear to contain a Gradle distribution. 或者 Server returned HTTP response code: 403 for URL:

当你在Android Studio 下载某个版本的Gradle 失败时,可以采取两种措施:

  1. 进入到GRADLE_USR_HOME目录下查看指定版本的子目录下是否有残缺的文件,如果有就把这个版本的所有目录删除重新再试,新版本中必须是以https的方式是请求,否则会报403。
    在这里插入图片描述
    完整的gradle库依赖应该包含4个部分:
    在这里插入图片描述
    具体可以参见上传插件到远程代码仓库系列文章
  2. 自己复制这个链接下载gradle-4.4-all.zip压缩包,放到你的GRADLE_USR_HOME目录下离线使用。

未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CrazyMo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值