Android Crash —— java.lang.Inter

2020-10-09  本文已影响0人  wolfaherd

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.OkHttpClient1.void put(okhttp3.ConnectionPool,okhttp3.internal.connection.RealConnection)(OkHttpClient.java:168) 7 okhttp3.internal.connection.StreamAllocation.okhttp3.internal.connection.RealConnection findConnection(int,int,int,int,boolean)(StreamAllocation.java:266) 8 okhttp3.internal.connection.StreamAllocation.okhttp3.internal.connection.RealConnection findHealthyConnection(int,int,int,int,boolean,boolean)(StreamAllocation.java:135) 9 okhttp3.internal.connection.StreamAllocation.okhttp3.internal.http.HttpCodec newStream(okhttp3.OkHttpClient,okhttp3.InterceptorChain,boolean)(StreamAllocation.java:114)
10 okhttp3.internal.connection.ConnectInterceptor.okhttp3.Response intercept(okhttp3.InterceptorChain)(ConnectInterceptor.java:42) 11 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request,okhttp3.internal.connection.StreamAllocation,okhttp3.internal.http.HttpCodec,okhttp3.internal.connection.RealConnection)(RealInterceptorChain.java:147) 12 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request)(RealInterceptorChain.java:121) 13 okhttp3.internal.cache.CacheInterceptor.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)(BridgeInterceptor.java:93) 17 okhttp3.internal.http.RealInterceptorChain.okhttp3.Response proceed(okhttp3.Request,okhttp3.internal.connection.StreamAllocation,okhttp3.internal.http.HttpCodec,okhttp3.internal.connection.RealConnection)(RealInterceptorChain.java:147) 18 okhttp3.internal.http.RetryAndFollowUpInterceptor.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();
           }
       });

上一篇下一篇

猜你喜欢

热点阅读