有些人爲了圖方便,直接在代碼引用的最外層放上一個try catch,以爲可以捕獲一切異常,降低崩潰率。
事實上,如果try的是新開啓的一個線程,那麼這個線程裏面出現的異常是catch不到。也就是說在A線程中new B線程,B線程中出現的crash跟A線程無關,A也catch不到。
public class TheadExceptionTest {
public static void main(String[] args) {
try {
new Thread(new Runnable() {
@Override
public void run() {
int i = 1 / 0;
}
}).start();
} catch (Exception e) {
}
}
}
這樣的try是不不到異常的。需要在Thread裏面加上try catch。
public class TheadExceptionTest {
public static void main(String[] args) {
try {
new Thread(new Runnable() {
@Override
public void run() {
try {
int i = 1 / 0;
} catch (Exception e) {
System.out.println("cannot / by zero!!!");
}
}
}).start();
} catch (Exception e) {
}
}
}
在單獨主線程中:
try {
Log.e("buder", "111");
int a = 10 / 0;
Log.e("buder", "222");
} catch (Exception e) {
Log.e("buder", "333");
} finally {
Log.e("buder", "444");
}
輸出:
/**
* 05-29 17:02:41.319 8626-8626/com.example.test E/buder: 111
* 05-29 17:02:41.319 8626-8626/com.example.test E/buder: 333
* 05-29 17:02:41.319 8626-8626/com.example.test E/buder: 444
*/
在新建的線程中,和上面也是一樣的輸出:
new Thread(
new Runnable() {
@Override
public void run() {
try {
Log.e("buder", "111");
int a = 10 / 0;
Log.e("buder", "222");
} catch (Exception e) {
Log.e("buder", "333");
} finally {
Log.e("buder", "444");
}
}
}
).start();
/**
* 2020-05-29 14:49:41.495 14845-14887/com.example.test E/buder: 111
* 2020-05-29 14:49:41.495 14845-14887/com.example.test E/buder: 333
* 2020-05-29 14:49:41.495 14845-14887/com.example.test E/buder: 444
*/
在主線程中拋出異常,在子線程中是無法捕捉到的:
final Handler handler = new Handler(Looper.getMainLooper());
new Thread(
new Runnable() {
@Override
public void run() {
try {
Log.e("buder", "111");
handler.postDelayed(new Runnable() {
@Override
public void run() {
int a = 10 / 0;
}
}, 50);
Log.e("buder", "222");
} catch (Exception e) {
Log.e("buder", "333");
} finally {
Log.e("buder", "444");
}
}
}
).start();
/**
* 2020-05-29 14:56:57.619 15585-15609/com.example.test E/buder: 111
* 2020-05-29 14:56:57.619 15585-15609/com.example.test E/buder: 222
* 2020-05-29 14:56:57.619 15585-15609/com.example.test E/buder: 444
*/
只有在各個線程中自己try...catch才能完整捕捉到異常信息:
final Handler handler = new Handler(Looper.getMainLooper());
new Thread(
new Runnable() {
@Override
public void run() {
try {
Log.e("buder", "111");
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
Log.e("buder", "0.111");
int a = 10 / 0;
Log.e("buder", "0.222");
} catch (Exception e) {
Log.e("buder", "0.333");
} finally {
Log.e("buder", "0.444");
}
}
}, 50);
Log.e("buder", "222");
} catch (Exception e) {
Log.e("buder", "333");
} finally {
Log.e("buder", "444");
}
}
}
).start();
/**
* 2020-05-29 15:03:16.291 16114-16139/? E/buder: 111
* 2020-05-29 15:03:16.291 16114-16139/? E/buder: 222
* 2020-05-29 15:03:16.291 16114-16139/? E/buder: 444
* 2020-05-29 15:03:16.361 16114-16114/? E/buder: 0.111
* 2020-05-29 15:03:16.362 16114-16114/? E/buder: 0.333
* 2020-05-29 15:03:16.362 16114-16114/? E/buder: 0.444
*/