英文:
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: ['*.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'
//// image slider ///////////
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'
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 < 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) {
}
});
}
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 "java". Under that a package/folder named "util". In this "util" 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 <T> int compare(T a, T b, Comparator<? super T> 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[] && b instanceof Object[]) {
return Arrays.deepEquals((Object[]) a, (Object[]) b);
} else if (a instanceof boolean[] && b instanceof boolean[]) {
return Arrays.equals((boolean[]) a, (boolean[]) b);
} else if (a instanceof byte[] && b instanceof byte[]) {
return Arrays.equals((byte[]) a, (byte[]) b);
} else if (a instanceof char[] && b instanceof char[]) {
return Arrays.equals((char[]) a, (char[]) b);
} else if (a instanceof double[] && b instanceof double[]) {
return Arrays.equals((double[]) a, (double[]) b);
} else if (a instanceof float[] && b instanceof float[]) {
return Arrays.equals((float[]) a, (float[]) b);
} else if (a instanceof int[] && b instanceof int[]) {
return Arrays.equals((int[]) a, (int[]) b);
} else if (a instanceof long[] && b instanceof long[]) {
return Arrays.equals((long[]) a, (long[]) b);
} else if (a instanceof short[] && 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'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 <T> 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 <T> T requireNonNull(T o, String message) {
if (o == null) {
throw new NullPointerException(message);
}
return o;
}
/**
* Returns "null" for null or {@code o.toString()}.
*/
public static String toString(Object o) {
return (o == null) ? "null" : 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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论