我的应用程序出现 NoClassDefFoundError。我正在使用 dnsjava、okhttp3 和改造。我的最小 API 是 19。
我读到 API 26 中添加了 java.time 包。这是否意味着我不能将 dnsjava 用于低于 26 的 Android API?还是其他原因导致此错误(例如proguard)?可以使用较旧的 dnsjava 版本帮助吗?我找不到任何有关 dnsjava 最小 API 的信息。
编辑:我在 dnsjava Github 页面上找到了这个。
从版本 2.1.x 迁移到 v3
不推荐使用使用 java.util.Date 的方法。将新版本与 java.time.Instant 或 java.time.Duration 一起使用
那么这是否意味着我可以使用 2.1.x 版本?
FATAL EXCEPTION: OkHttp Dispatcher
Process: de.url.myproject, PID: 10723
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Duration;
at org.xbill.DNS.ExtendedResolver.<clinit>(ExtendedResolver.java)
at org.xbill.DNS.Lookup.refreshDefault(Lookup.java:1)
at org.xbill.DNS.Lookup.<clinit>(Lookup.java:1)
at org.xbill.DNS.Lookup.getDefaultResolver(Lookup.java)
at de.url.myproject.MyDNS.init(MyDNS.java)
at de.url.myproject.MyDNS.lookup(MyDNS.java)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:19)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:19)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:19)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:19)
at okhttp3.internal.connection.StreamAllocation.e(StreamAllocation.java)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:10)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:10)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:103)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:103)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:27)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:27)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:7)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:12)
at okhttp3.RealCall$AsyncCall.a(RealCall.java)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.Duration" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/androidx.test.tools.crawler-1/base.apk", zip file "/data/app/de.url.myproject-1/base.apk", zip file "/data/app/de.url.myproject-1/split_config.xxhdpi.apk"],nativeLibraryDirectories=[/data/app/androidx.test.tools.crawler-1/lib/arm64, /data/app/de.url.myproject-1/lib/arm64, /system/lib64, /vendor/lib64, /system/vendor/lib64, /product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 22 more
Suppressed: java.io.IOException: No original dex files found for dex location /data/app/de.url.myproject-1/split_config.xxhdpi.apk
at dalvik.system.DexFile.openDexFileNative(DexFile.java)
at dalvik.system.DexFile.openDexFile(DexFile.java:373)
at dalvik.system.DexFile.<init>(DexFile.java:113)
at dalvik.system.DexFile.<init>(DexFile.java:78)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:359)
at dalvik.system.DexPathList.makeElements(DexPathList.java:323)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:263)
at dalvik.system.DexPathList.<init>(DexPathList.java:126)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48)
at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64)
at com.android.internal.os.PathClassLoaderFactory.createClassLoader(PathClassLoaderFactory.java:43)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:58)
at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:540)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:573)
at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1990)
at android.app.LoadedApk.getResources(LoadedApk.java:799)
at android.app.ContextImpl.<init>(ContextImpl.java:2217)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2162)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5547)
at android.app.ActivityThread.-wrap2(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1637)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6524)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
我的代码:
package de.url.myproject;
import android.util.Log;
import androidx.annotation.NonNull;
import org.xbill.DNS.Address;
import org.xbill.DNS.ExtendedResolver;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.SimpleResolver;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import okhttp3.Dns;
public class MyDNS implements Dns {
private static final String LIVE_API_HOST = "api.myproject.de";
private static final String LIVE_API_IP = "12.345.67.890";
private boolean mInitialized;
private InetAddress mLiveApiStaticIpAddress;
@NonNull
@Override
public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
// I'm initializing the DNS resolvers here to take advantage of this method being called in a background-thread managed by OkHttp
init();
try {
return Collections.singletonList(Address.getByName(hostname));
} catch (UnknownHostException e) {
// fallback to the API's static IP
if (LIVE_API_HOST.equals(hostname) && mLiveApiStaticIpAddress != null) {
return Collections.singletonList(mLiveApiStaticIpAddress);
} else {
throw e;
}
}
}
private void init() {
if (mInitialized) return; else mInitialized = true;
try {
mLiveApiStaticIpAddress = InetAddress.getByName(LIVE_API_IP);
} catch (UnknownHostException e) {
Log.w("DNS", "Couldn't initialize static IP address");
}
try {
// configure the resolvers, starting with the default ones (based on the current network connection)
Resolver defaultResolver = Lookup.getDefaultResolver();
// use Google's public DNS services
Resolver googleFirstResolver = new SimpleResolver("8.8.8.8");
Resolver googleSecondResolver = new SimpleResolver("8.8.4.4");
// also try using Amazon
Resolver amazonResolver = new SimpleResolver("205.251.198.30");
Lookup.setDefaultResolver(new ExtendedResolver(new Resolver[]{
defaultResolver, googleFirstResolver, googleSecondResolver, amazonResolver}));
} catch (UnknownHostException e) {
Log.w("DNS", "Couldn't initialize custom resolvers");
}
}
}