ฉันใช้ OkHttp และฉันเพิ่งพบปัญหานี้
สำหรับส่วนแรก@thucnguyen อยู่บนเส้นทางที่ถูกต้อง
สิ่งนี้เกิดขึ้นเมื่อคุณเรียกใช้ getActivity () ในเธรดอื่นที่เสร็จสิ้นหลังจากที่แฟรกเมนต์ถูกลบ กรณีทั่วไปกำลังเรียกใช้ getActivity () (เช่น Toast) เมื่อคำขอ HTTP เสร็จสิ้น (เช่น onResponse เป็นต้น)
การเรียก HTTP บางอย่างถูกดำเนินการแม้หลังจากกิจกรรมถูกปิด (เพราะอาจใช้เวลาสักครู่ก่อนที่คำขอ HTTP จะเสร็จสมบูรณ์) จากนั้นผมก็ผ่านการHttpCallback
พยายามที่จะปรับปรุงเขตข้อมูลส่วนบางอย่างและมีข้อยกเว้นเมื่อพยายามที่จะnull
getActivity()
http.newCall(request).enqueue(new Callback(...
onResponse(Call call, Response response) {
...
getActivity().runOnUiThread(...) // <-- getActivity() was null when it had been destroyed already
IMO วิธีแก้ไขคือป้องกันการโทรกลับเกิดขึ้นเมื่อแฟรกเมนต์ไม่เหลืออีกต่อไป (ซึ่งไม่ใช่แค่ Okhttp)
การแก้ไข: การป้องกัน
หากคุณดูวงจรชีวิตของชิ้นส่วน (ข้อมูลเพิ่มเติมที่นี่ ) คุณจะสังเกตเห็นว่ามีonAttach(Context context)
และonDetach()
วิธีการต่างๆ สิ่งเหล่านี้ถูกเรียกหลังจากที่แฟรกเมนต์เป็นของกิจกรรมและก่อนที่จะหยุดตามลำดับ
นั่นหมายความว่าเราสามารถป้องกันการโทรกลับนั้นเกิดขึ้นได้ด้วยการควบคุมในonDetach
วิธีการ
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Initialize HTTP we're going to use later.
http = new OkHttpClient.Builder().build();
}
@Override
public void onDetach() {
super.onDetach();
// We don't want to receive any more information about the current HTTP calls after this point.
// With Okhttp we can simply cancel the on-going ones (credits to https://github.com/square/okhttp/issues/2205#issuecomment-169363942).
for (Call call : http.dispatcher().queuedCalls()) {
call.cancel();
}
for (Call call : http.dispatcher().runningCalls()) {
call.cancel();
}
}
getActivity()
แต่คุณต้องวงเล็บหลัง นอกจากนี้คุณจะยกตัวอย่างชิ้นส่วนได้อย่างไร คุณมีมันใน layout.xml ของคุณหรือไม่