Retrofit 2 在 Android API 等级 17 上不起作用。

huangapple go评论79阅读模式
英文:

Retrofit 2 not working on android api level 17

问题

以下是要翻译的代码部分:

第一部分是依赖项:

{
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.google.android.material:material:1.0.0'
    //// 图片轮播 ///////////
    implementation 'com.github.smarteist:autoimageslider:1.3.2'
    // implementation 'com.github.smarteist:autoimageslider:1.3.2-appcompat'
    /// Glide 图片加载库 //
    //implementation 'com.github.bumptech.glide:glide:4.10.0'
    //annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
    ////////
    // implementation 'com.squareup.picasso:picasso:2.71828'
    //// Retrofit ///////
    implementation "com.squareup.retrofit2:retrofit:2.7.0"
    implementation "com.squareup.retrofit2:converter-gson:2.7.0"
//    implementation files('libs/retrofit-2.7.0.jar')
//    implementation files('libs/converter-gson-2.7.1.jar')

///////////////////////////////////////////////////////////
    implementation 'com.android.support:multidex:1.0.3'

    //OkHttp
    //  implementation 'com.squareup.okhttp3:okhttp:3.13.0'
    //   implementation 'com.squareup.okhttp3:okhttp:3.11.0'
    implementation "com.squareup.okhttp3:logging-interceptor:3.12.3"
    implementation 'com.squareup.okhttp3:okhttp:3.12.3'
}

这是关于 Retrofit 的调用。在Android版本高于Lollipop上运行正常,但在API级别17上不起作用。

textView = findViewById(R.id.textView);

Retrofit retrofit;
/* ConnectionSpec.MODERN_TLS 是默认值 */

// List tlsSpecs = Arrays.asList(ConnectionSpec.MODERN_TLS);

/* 为低于Lollipop的API提供向后兼容性: */
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    List tlsSpecs = Arrays.asList(ConnectionSpec.MODERN_TLS);

    tlsSpecs = Arrays.asList(ConnectionSpec.COMPATIBLE_TLS);
    OkHttpClient client = new OkHttpClient.Builder()
            .connectionSpecs(tlsSpecs)
            .build();
    retrofit = new Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com/")
            .addConverterFactory(GsonConverterFactory.create())
            // .client(client)
            .build();
} else {
    retrofit = new Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

//        retrofit = new Retrofit.Builder()
//                .baseUrl("https://jsonplaceholder.typicode.com/")
//                .addConverterFactory(GsonConverterFactory.create())
//
//                .build();

JsonplaceholderApi jsonplaceholderApi = retrofit.create(JsonplaceholderApi.class);
Call<List<RetrofitPost>> call = jsonplaceholderApi.getPosts();

call.enqueue(new Callback<List<RetrofitPost>>() {
    @Override
    public void onResponse(Call<List<RetrofitPost>> call, Response<List<RetrofitPost>> response) {
        if (!response.isSuccessful()) {
            textView.setText("Code:" + response.code());
            return;
        }
        List<RetrofitPost> posts = response.body();
        for (RetrofitPost post : posts) {
            String content = "";
            content += "ID:" + post.getId() + "\n";
            content += "User ID:" + post.getUserId() + "\n";
            content += "Title" + post.getTitle() + "\n";
            content += "Text" + post.getText() + "\n\n";
            textView.append(content);
        }
    }

    @Override
    public void onFailure(Call<List<RetrofitPost>> call, Throwable t) {

    }
});
}

它报错如下:

java.lang.NoClassDefFoundError: java.util.Objects
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:491)
at com.example.shopingtemplate.activities.RetrofitTest.onCreate(RetrofitTest.java:68)
英文:

The first is dependencies here

  {
implementation fileTree(include: [&#39;*.jar&#39;], dir: &#39;libs&#39;)
implementation &#39;androidx.appcompat:appcompat:1.1.0&#39;
implementation &#39;androidx.constraintlayout:constraintlayout:1.1.3&#39;
implementation &#39;androidx.legacy:legacy-support-v4:1.0.0&#39;
testImplementation &#39;junit:junit:4.12&#39;``
androidTestImplementation &#39;androidx.test:runner:1.2.0&#39;
androidTestImplementation &#39;androidx.test.espresso:espresso-core:3.2.0&#39;
implementation &#39;com.google.android.material:material:1.0.0&#39;
//// image slider ///////////
implementation &#39;com.github.smarteist:autoimageslider:1.3.2&#39;
// implementation &#39;com.github.smarteist:autoimageslider:1.3.2-appcompat&#39;
/// glide //
//implementation &#39;com.github.bumptech.glide:glide:4.10.0&#39;
//annotationProcessor &#39;com.github.bumptech.glide:compiler:4.10.0&#39;
////////
// implementation &#39;com.squareup.picasso:picasso:2.71828&#39;
//// retrofit ///////
implementation &quot;com.squareup.retrofit2:retrofit:2.7.0&quot;
implementation &quot;com.squareup.retrofit2:converter-gson:2.7.0&quot;
//    implementation files(&#39;libs/retrofit-2.7.0.jar&#39;)
//    implementation files(&#39;libs/converter-gson-2.7.1.jar&#39;)
///////////////////////////////////////////////////////////
implementation &#39;com.android.support:multidex:1.0.3&#39;
//OkHttp
//  implementation &#39;com.squareup.okhttp3:okhttp:3.13.0&#39;
//   implementation &#39;com.squareup.okhttp3:okhttp:3.11.0&#39;
implementation &quot;com.squareup.okhttp3:logging-interceptor:3.12.3&quot;
implementation &#39;com.squareup.okhttp3:okhttp:3.12.3&#39;

This is the call for retrofit. It is working fine above lollipop but is not working in API level 17.

 textView= findViewById(R.id.textView);
Retrofit retrofit;
/* ConnectionSpec.MODERN_TLS is the default value */
// List tlsSpecs = Arrays.asList(ConnectionSpec.MODERN_TLS);
/* providing backwards-compatibility for API lower than Lollipop: */
if(Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.LOLLIPOP) {
List tlsSpecs = Arrays.asList(ConnectionSpec.MODERN_TLS);
tlsSpecs = Arrays.asList(ConnectionSpec.COMPATIBLE_TLS);
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(tlsSpecs)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(&quot;https://jsonplaceholder.typicode.com/&quot;)
.addConverterFactory(GsonConverterFactory.create())
// .client(client)
.build();
}else {
retrofit = new Retrofit.Builder()
.baseUrl(&quot;https://jsonplaceholder.typicode.com/&quot;)
.addConverterFactory(GsonConverterFactory.create())
.build();
}

// retrofit = new Retrofit.Builder()
// .baseUrl("https://jsonplaceholder.typicode.com/")
// .addConverterFactory(GsonConverterFactory.create())
//
// .build();

    JsonplaceholderApi jsonplaceholderApi = retrofit.create(JsonplaceholderApi.class);
Call&lt;List&lt;RetrofitPost&gt;&gt; call =  jsonplaceholderApi.getPosts();
call.enqueue(new Callback&lt;List&lt;RetrofitPost&gt;&gt;() {
@Override
public void onResponse(Call&lt;List&lt;RetrofitPost&gt;&gt; call, Response&lt;List&lt;RetrofitPost&gt;&gt; response) {
if(!response.isSuccessful()){
textView.setText(&quot;Code:&quot;+response.code());
return;
}
List&lt;RetrofitPost&gt; posts = response.body();
for (RetrofitPost post:posts){
String content=&quot;&quot;;
content+= &quot;ID:&quot;+post.getId()+&quot;\n&quot;;
content+= &quot;User ID:&quot;+post.getUserId()+&quot;\n&quot;;
content+= &quot;Title&quot;+post.getTitle()+&quot;\n&quot;;
content+= &quot;Text&quot;+post.getText()+&quot;\n\n&quot;;
textView.append(content);
}
}
@Override
public void onFailure(Call&lt;List&lt;RetrofitPost&gt;&gt; call, Throwable t) {
}
});
}

It gives this error:

  java.lang.NoClassDefFoundError: java.util.Objects
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:491)
at com.example.shopingtemplate.activities.RetrofitTest.onCreate(RetrofitTest.java:68)

答案1

得分: 2

我遇到了相同的问题。您可以使用以下解决方法。添加一个名为 "java" 的包/文件夹。在该包/文件夹下创建一个名为 "util" 的包/文件夹。在 "util" 文件夹中创建一个名为 Objects 的类。

用以下代码填充 Objects.java 类。

package java.util;

/**
 * 对象的实用方法。
 * @since 1.7
 */
public final class Objects {
    private Objects() {}

    /**
     * 如果 {@code a == b},则返回 0,否则返回 {@code c.compare(a, b)}。
     * 换句话说,这使得 {@code c} 具有空安全性。
     */
    public static <T> int compare(T a, T b, Comparator<? super T> c) {
        if (a == b) {
            return 0;
        }
        return c.compare(a, b);
    }

    // 其他方法的翻译...
}

这对我起作用了


<details>
<summary>英文:</summary>

I have faced the same issue. You could use this workaround. Add a package/folder named &quot;java&quot;. Under that a package/folder named &quot;util&quot;. In this &quot;util&quot; folder create a class named Objects.

Fill the Objects.java class with the following code.

    package java.util;
    /**
    * Utility methods for objects.
    * @since 1.7
    */
    public final class Objects {
        private Objects() {}
        /**
        * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
        * That is, this makes {@code c} null-safe.
        */
        public static &lt;T&gt; int compare(T a, T b, Comparator&lt;? super T&gt; c) {
            if (a == b) {
                return 0;
            }
            return c.compare(a, b);
        }
        /**
        * Returns true if both arguments are null,
        * the result of {@link Arrays#equals} if both arguments are primitive arrays,
        * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
        * and the result of {@link #equals} otherwise.
        */
    
        public static boolean deepEquals(Object a, Object b) {
            if (a == null || b == null) {
                return a == b;
            } else if (a instanceof Object[] &amp;&amp; b instanceof Object[]) {
                return Arrays.deepEquals((Object[]) a, (Object[]) b);
            } else if (a instanceof boolean[] &amp;&amp; b instanceof boolean[]) {
                return Arrays.equals((boolean[]) a, (boolean[]) b);
            } else if (a instanceof byte[] &amp;&amp; b instanceof byte[]) {
                return Arrays.equals((byte[]) a, (byte[]) b);
            } else if (a instanceof char[] &amp;&amp; b instanceof char[]) {
                return Arrays.equals((char[]) a, (char[]) b);
            } else if (a instanceof double[] &amp;&amp; b instanceof double[]) {
                return Arrays.equals((double[]) a, (double[]) b);
            } else if (a instanceof float[] &amp;&amp; b instanceof float[]) {
                return Arrays.equals((float[]) a, (float[]) b);
            } else if (a instanceof int[] &amp;&amp; b instanceof int[]) {
                return Arrays.equals((int[]) a, (int[]) b);
            } else if (a instanceof long[] &amp;&amp; b instanceof long[]) {
                return Arrays.equals((long[]) a, (long[]) b);
            } else if (a instanceof short[] &amp;&amp; b instanceof short[]) {
                return Arrays.equals((short[]) a, (short[]) b);
            }
            return a.equals(b);
        }
        /**
        * Null-safe equivalent of {@code a.equals(b)}.
        */
        public static boolean equals(Object a, Object b) {
            return (a == null) ? (b == null) : a.equals(b);
        }
        /**
        * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
        * This can be used to compute a hash code for an object&#39;s fields as follows:
        * {@code Objects.hash(a, b, c)}.
        */
        public static int hash(Object... values) {
            return Arrays.hashCode(values);
        }
        /**
        * Returns 0 for null or {@code o.hashCode()}.
        */
        public static int hashCode(Object o) {
           return (o == null) ? 0 : o.hashCode();
        }
        /**
        * Returns {@code o} if non-null, or throws {@code NullPointerException}.
        */
        public static &lt;T&gt; T requireNonNull(T o) {
            if (o == null) {
                throw new NullPointerException();
            }
            return o;
        }
        /**
        * Returns {@code o} if non-null, or throws {@code NullPointerException}
        * with the given detail message.
        */
        public static &lt;T&gt; T requireNonNull(T o, String message) {
            if (o == null) {
                throw new NullPointerException(message);
            }
            return o;
        }
        /**
        * Returns &quot;null&quot; for null or {@code o.toString()}.
        */
        public static String toString(Object o) {
            return (o == null) ? &quot;null&quot; : o.toString();
        }
        /**
        * Returns {@code nullString} for null or {@code o.toString()}.
        */
        public static String toString(Object o, String nullString) {
            return (o == null) ? nullString : o.toString();
        }
    }

It worked for me.

</details>



huangapple
  • 本文由 发表于 2020年1月6日 23:05:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/59614410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定