java.lang.NoClassDefFoundError:com.example.api.retrofit.AuthenticationInterceptor $ intercept $ 1
我最近添加了retrofit2到我的应用程序。 它在运行Android 8.0的Nexus 6P上运行良好,但是在运行Android 6.0.1的旧版OnePlus One上运行时遇到了一个错误:
java.lang.NoClassDefFoundError: com.example.api.retrofit.AuthenticationInterceptor$intercept$1 at com.example.api.retrofit.AuthenticationInterceptor.intercept(AuthenticationInterceptor.kt:21) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) at okhttp3.RealCall.execute(RealCall.java:69) at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:91) at com.example.fragment.xx.XXFragment$onViewCreated$2.getItemsForConstraint(XXFragment.kt:53) at com.example.view.MyAutoCompleteTextView$Adapter$getFilter$1.performFiltering(MyAutoCompleteTextView.kt:114) at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.os.HandlerThread.run(HandlerThread.java:61)
这是我的代码:
的build.gradle
buildscript { ext { okhttpVersion = '3.8.0' retrofitVersion = '2.3.0' } ... }
应用程序/的build.gradle:
compile "com.squareup.okhttp3:okhttp:$okhttpVersion" compile "com.squareup.okhttp3:logging-interceptor:$okhttpVersion" compile 'com.google.code.gson:gson:2.8.1' compile("com.squareup.retrofit2:retrofit:$retrofitVersion") { exclude module: 'okhttp' } compile "com.squareup.retrofit2:converter-gson:$retrofitVersion"
建立服务:
OkHttpClient client = new OkHttpClient().newBuilder() .addInterceptor(new AuthenticationInterceptor(ctx)) .addInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(HOST + VERSION + "/") .client(client) .addConverterFactory(new EnvelopingConverter()) .addConverterFactory(GsonConverterFactory.create()) .build(); retrofitService = retrofit.create(ApiService.class);
拦截器:
import android.content.Context import com.example.api.Api import com.example.controller.AuthManager import okhttp3.Interceptor import okhttp3.Response class AuthenticationInterceptor(val context: Context) : Interceptor { override fun intercept(chain: Interceptor.Chain?): Response? { var request = chain?.request() val headers = AuthManager.getAuthHeaders(context) if (request != null) { val requestBuilder = request.newBuilder() requestBuilder.addHeader(Api.HEADER_ACCEPT, Api.HEADER_APP_JSON) headers.forEach { key, value -> // this is line 21 requestBuilder.addHeader(key, value) } request = requestBuilder.build() } return chain?.proceed(request) } }
我不确定这个问题可能是什么? 任何人有任何想法?
更新:
在java中编写拦截器,它似乎工作。 为什么? 我真的想坚持Kotlin这个项目。
public class AuthInterceptor implements Interceptor { private Context context; public AuthInterceptor(Context ctx) { context = ctx; } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Map<String, String> headers = AuthManager.getAuthHeaders(context); if (request != null) { Request.Builder requestBuilder = request.newBuilder(); requestBuilder.addHeader(Api.HEADER_ACCEPT, Api.HEADER_APP_JSON); for (String key : headers.keySet()) { requestBuilder.addHeader(key, headers.get(key)); } request = requestBuilder.build(); } return chain.proceed(request); } }
尝试禁用即时运行。
1 2 3
经过几个小时的调试,我发现了什么事情:
在我的gradle文件中,我也compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
正因为如此,它允许我使用下面的代码:
headers.forEach { key, value -> // this is line 21 requestBuilder.addHeader(key, value) }
在反编译和查看java代码时,它将如下所示:
e.forEach((BiConsumer)(new BiConsumer() { // $FF: synthetic method // $FF: bridge method public void accept(Object var1, Object var2) { this.accept((String)var1, (String)var2); } public final void accept(String key, String value) { requestBuilder.addHeader(key, value); } }));
这里的问题是在API级别24中添加了类BiConsumer 。 这就是为什么它在Android 8.0(API级别26)上工作,并且在Android 6.0.1(API级别23)上不工作。
所以,我最终使用了一个普通的for循环,而不是我最初使用的forEach。
这里的主要问题是异常: java.lang.NoClassDefFoundError: com.example.api.retrofit.AuthenticationInterceptor$intercept$1
。 如果它会说java.lang.NoClassDefFoundError: java.util.function.BiConsumer
,我认为这将是更容易调试。