Android Crash —— java.lang.Inter
crash堆栈信息
1 java.lang.Thread.nativeCreate(Native Method)
2 java.lang.Thread.start(Thread.java:753)
3 java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:970)
4 java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1388)
5 okhttp3.ConnectionPool.void put(okhttp3.internal.connection.RealConnection)(ConnectionPool.java:153)
6 okhttp3.OkHttpClientChain,boolean)(StreamAllocation.java:114)
10 okhttp3.internal.connection.ConnectInterceptor.okhttp3.Response intercept(okhttp3.InterceptorChain)(CacheInterceptor.java:93)
14 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request,okhttp3.internal.connection.StreamAllocation,okhttp3.internal.http.HttpCodec,okhttp3.internal.connection.RealConnection)(RealInterceptorChain.java:147)
15 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request)(RealInterceptorChain.java:121)
16 okhttp3.internal.http.BridgeInterceptor.okhttp3.Response intercept(okhttp3.InterceptorChain)(RetryAndFollowUpInterceptor.java:126)
19 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request,okhttp3.internal.connection.StreamAllocation,okhttp3.internal.http.HttpCodec,okhttp3.internal.connection.RealConnection)(RealInterceptorChain.java:147)
20 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request)(RealInterceptorChain.java:121)
21 okhttp3.RealCall.okhttp3.Response getResponseWithInterceptorChain()(RealCall.java:200)
22 okhttp3.RealCall.okhttp3.Response execute()(RealCall.java:77)
腾讯bugly解决方案
该异常表示发生了内部错误,而这个错误是线程在runtime宕机时启动造成的。
[解决方案]:这类问题一般是是线程开启的太晚了导致的。我们启动一个线程会调用Thread的start方法,start方法会调用名为nativeCreate的本地方法,具体位置在/android/art/runtime/native/java_lang_Thread.cc,名字换成了CreateNativeThread:我们可以看看它的源码:
void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) {
CHECK(java_peer != nullptr);//即为java层的thread实例,包裹着run方法的具体实现
Thread* self = static_cast<JNIEnvExt>(env)->self;
Runtime runtime = Runtime::Current();// Atomically start the birth of the thread ensuring the runtime isn't shutting down.
bool thread_start_during_shutdown = false;//这段代码用来检测thread是否在runtime宕机时start的
{
MutexLock mu(self, *Locks::runtime_shutdown_lock_);
if (runtime->IsShuttingDownLocked()) {
thread_start_during_shutdown = true;
} else {
runtime->StartThreadBirth();
}
}
if (thread_start_during_shutdown) {//若runtime宕机了就抛出异常
ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/InternalError"));
env->ThrowNew(error_class.get(), "Thread starting during runtime shutdown");
return;
}
..... 省略代码
}
从代码我们可以知道,如果runtime宕机了就会抛出InternalError的异常。我们在启动线程的时候,需要确认一下是否有线程嵌套的情况,不要在线程中再去启动一个线程。
解决方案一:
在启动线程的时候判断当前线程是否是主线程,若是主线程,则创建新的线程,否则不创建。
判断线程是否是主线程的一种方法:/** * 判断是否在当前主线程 * @return */ public static boolean isOnMainThread(){ return Looper.myLooper() == Looper.getMainLooper(); }
解决方案二:
调度到主线程来创建新的线程
private static final Handler handler = new Handler();//需要在主线程中创建handler。 handler.post(new Runnable() { @Override public void run() { thread.start(); } });