Gradle Android 错误:MethodHandle.invoke 和 MethodHandle.invokeExact

Posted

技术标签:

【中文标题】Gradle Android 错误:MethodHandle.invoke 和 MethodHandle.invokeExact【英文标题】:Gradle Android Error: MethodHandle.invoke and MethodHandle.invokeExact 【发布时间】:2019-11-17 17:49:37 【问题描述】:

我正在尝试在我的 android 应用程序中使用 SOAP 服务。我正在尝试关注this guide。当我尝试运行我的应用程序时出现错误:

Error: MethodHandle.invoke and MethodHandle.invokeExact are only supported starting with Android O (--min-api 26)

我在 Android N 上(SDK 25 - 我无法像错误消息所示那样达到 26),这是一个由 Android Studio 刚刚创建的全新项目。

这是我没有更改的项目 build.gradle 文件:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript 
    repositories 
        google()
        jcenter()
    
    dependencies 
        classpath 'com.android.tools.build:gradle:3.4.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    


allprojects 
    repositories 
        google()
        jcenter()
    


task clean(type: Delete) 
    delete rootProject.buildDir


这是我的 app build.gradle 文件:

apply plugin: 'com.android.application'

configurations 
    jaxb


buildscript 
    repositories 
        mavenCentral()
    
    dependencies 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE")
    


apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

repositories 
    mavenCentral()


// tag::wsdl[]
task genJaxb 
    ext.sourcesDir = "$buildDir/generatedjava/jaxb"
    ext.classesDir = "$buildDir/classes/jaxb"
    ext.schema = "https://lite.realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01"

    outputs.dir classesDir

    doLast() 
        project.ant 
            taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
                    classpath: configurations.jaxb.asPath
            mkdir(dir: sourcesDir)
            mkdir(dir: classesDir)

            xjc(destdir: sourcesDir, schema: schema,
                    package: "hello.wsdl") 
                arg(value: "-wsdl")
                produces(dir: sourcesDir, includes: "**/*.java")
            

            javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true,
                    debugLevel: "lines,vars,source",
                    classpath: configurations.jaxb.asPath) 
                src(path: sourcesDir)
                include(name: "**/*.java")
                include(name: "*.java")
            

            copy(todir: classesDir) 
                fileset(dir: sourcesDir, erroronmissingdir: false) 
                    exclude(name: "**/*.java")
                
            
        
    

// end::wsdl[]

android 
    compileSdkVersion 29
    buildToolsVersion "29.0.0"
    defaultConfig 
        applicationId "com.example.magicmirror"
        minSdkVersion 25
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    
    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        
    

    compileOptions 
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    

    packagingOptions 
        exclude 'META-INF/spring.tooling'
        exclude 'META-INF/spring.handlers'
        exclude 'META-INF/spring-configuration-metadata.json'
        exclude 'META-INF/additional-spring-configuration-metadata.json'
        exclude 'META-INF/spring.factories'
        exclude 'META-INF/spring.schemas'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
    


dependencies 
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation "org.springframework.boot:spring-boot-starter"
    implementation "org.springframework.ws:spring-ws-core"
    implementation(files(genJaxb.classesDir).builtBy(genJaxb))

    jaxb "com.sun.xml.bind:jaxb-xjc:2.1.7"


从日志中,导致此问题的确切 JAR 是 org.springframework/spring-core/5.1.8.RELEASE.jar。在其他答案中提到了添加 compileOptions 块作为修复,但它并没有解决这个问题。我该如何解决这个问题?

【问题讨论】:

要明确,我必须使用 SDK 25 (Android N),而不是错误消息中所说的 26。 您可以使用这些参考。关联。它可能对你有帮助。 Jar File UpdateJAVA VErsion Configuration 我看过那些。这就是我添加 compileOptions 的原因。就像我说的我不能使用 SDK 26。所以不幸的是他们没有帮助。 所以我看到您使用的是 Spring Boot 而不是 Spring for Android,这有点复杂。恕我直言,Spring Boot 仅适用于 Java 应用程序而不是 Android 应用程序,因为引导方式主要是为纯 Java 应用程序设计的。但是,您可以使用 Spring for Android 并包含 Spring WebServices 库 (spring-ws-core) 并因此执行 SOAP 请求。但任何包含“启动”一词的东西都几乎无法在 Android 上运行。 这个库可能对你有用android-arsenal.com/details/1/430 【参考方案1】:

你尝试过 ksoap 吗?

https://github.com/simpligility/ksoap2-android

看起来它应该做肥皂,还活着并且适用于 android。

ksoap2-android 项目提供了一个轻量高效的 SOAP Android 平台的客户端库。

【讨论】:

谢谢,我会试试这个。不生成 WSDL,但可能比手动构建 SOAP 信封更好。 嗨@Maksim 知道如何在 build.gradle 中配置 ksoap2 ?【参考方案2】:

我认为您只需要使用不同的库即可进行 SOAP 调用。这是我所使用的,它支持最早 14 版本的 SDK。

private void GetSomeStuff(String myterm) throws UnsupportedEncodingException 


try 

     String strStuff2 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
     "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
     "<soap:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"+
     "<wsse:UsernameToken><wsse:Username>my username</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">my password</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header>"+
     "<soap:Body> <GetSomeStuff xmlns=\"https://mycompany.com.MyService\">"+
     "<term>" + myterm + "/term></GetSomeStuff></soap:Body></soap:Envelope>";


    StringBuilder stringBuilder = new StringBuilder();


    HttpPost httppost = new HttpPost("https://mycompany.com/MyService.svc");        
    StringEntity se;

    se = new StringEntity(strStuff2,HTTP.UTF_8);


    httppost.setHeader("SOAPAction", "https://mycompany.com.MyService/GetSomeStuff”);


    se.setContentType("text/xml");  
    httppost.setEntity(se);  


    HttpClient httpclient = new DefaultHttpClient();      

    HttpResponse theresponse = (HttpResponse) httpclient.execute(httppost);

    StatusLine statusLine = theresponse.getStatusLine();
    int statusCode = statusLine.getStatusCode();
    if (statusCode == 200) 
        HttpEntity entity = theresponse.getEntity();
        InputStream content = entity.getContent();
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(content));
        String line;
        while ((line = reader.readLine()) != null) 
            stringBuilder.append(line);
        

        String theXML = stringBuilder.toString();

        int start = theXML.indexOf("<GetSomeStuffResult>") + 21;
        int end = theXML.indexOf("</GetSomeStuffResult>") - 1;

        // We didn't get the response we expected
        if ((start < 0) || (end < 0) || (start==end)) 
            Log.i(“MyApp”,”Empty Response from GetSomeStuffResult");
            return;
        

        String myData = theXML.substring(start, end);

        if (myData() > 0) 
            try 
                JSONObject jObject = new JSONObject(myData);

                String deptDesc = jObject.getString("DepartmentDescription");
                String areaCode = jObject.getString("area_code");
                String phoneNumber = jObject.getString("phone_nbr");
                String title = jObject.getString("title");

                String fullPhoneNumber = "";

                if (phoneNumber.length() == 7) 
                    fullPhoneNumber = "(" + areaCode + ") " + phoneNumber.substring(0, 3) + "-" + phoneNumber.substring(3, 7);
                 else 
                     fullPhoneNumber = "(" + areaCode + ") " + phoneNumber;
                

                SharedPreferences appPrefs =
                        getSharedPreferences("appPreferences",MODE_PRIVATE);

                SharedPreferences.Editor prefsEditor = appPrefs.edit();
                prefsEditor.putString("Title",title);
                prefsEditor.putString("DeptDescr",deptDesc);
                prefsEditor.putString("PhoneNumber",fullPhoneNumber);

                prefsEditor.commit();   

            
            catch (JSONException e) 
                e.printStackTrace();
            
        


     else 
         Log.e(“MyApp”, "Failed to GetSomeStuff”);
    


 catch (ClientProtocolException e) 
    e.printStackTrace();
 catch (IOException e) 
    e.printStackTrace();
 catch (Exception e) 
    e.printStackTrace();

【讨论】:

这就是 SOAP 对世界所做的。【参考方案3】:

org.springframework/spring-core/5.1.8.RELEASE.jar 不能与 minSdkVersion 25 一起使用,它甚至不是 Android 库,而是 Java 库。严格要求minSdkVersion 26

MethodHandle.invoke and MethodHandle.invokeExact
are only supported starting with Android O (--min-api 26)

ksoap2-android 可能确实更兼容(最常见)或

wsdl2ksoap2-android 带有设备上的“从 WSDL 自动生成源代码”。

...还有一些其他的链接;有些需要在桌面 Java 上生成 POJO。

【讨论】:

@jbrown 问题是“我该如何解决这个问题?” - 我根本没有重复。

以上是关于Gradle Android 错误:MethodHandle.invoke 和 MethodHandle.invokeExact的主要内容,如果未能解决你的问题,请参考以下文章

离子构建android错误gradle错误

奇怪的gradle错误android studio

Android Studio 2.3 gradle 错误

Gradle错误Android资源链接失败

android中的gradle依赖错误

Android Studio 2.3 错误:“Gradle 同步失败:原因:services.gradle.org”