ประการแรกฉันรู้ว่าไม่ควรฆ่า / รีสตาร์ทแอปพลิเคชันบน Android ในกรณีการใช้งานของฉันฉันต้องการรีเซ็ตแอปพลิเคชันจากโรงงานในกรณีเฉพาะที่เซิร์ฟเวอร์ส่งข้อมูลเฉพาะไปยังลูกค้า
ผู้ใช้สามารถลงชื่อเข้าใช้บนเซิร์ฟเวอร์ด้วยอินสแตนซ์ของแอปพลิเคชันเดียวเท่านั้น (เช่นไม่อนุญาตให้ใช้อุปกรณ์หลายเครื่อง) หากอินสแตนซ์อื่นได้รับการ "ล็อคอิน" - ล็อคอินสแตนซ์อื่น ๆ ทั้งหมดของผู้ใช้นั้นจะต้องลบข้อมูล (รีเซ็ตเป็นค่าจากโรงงาน) เพื่อรักษาความสอดคล้อง
เป็นไปได้ที่จะบังคับให้ล็อกเพราะผู้ใช้อาจลบแอพและติดตั้งใหม่ซึ่งจะทำให้เกิดอินสแตนซ์ - id อื่นและผู้ใช้จะไม่สามารถปลดล็อคได้อีก ดังนั้นจึงเป็นไปได้ที่จะบังคับให้ล็อค
เนื่องจากความเป็นไปได้ในการบังคับนั้นเราจำเป็นต้องตรวจสอบอินสแตนซ์ที่เป็นรูปธรรมเสมอว่ามันมีล็อค ที่ทำบน (เกือบ) แต่ละคำขอไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์อาจส่ง "รหัสล็อคผิด" หากตรวจพบว่าแอปพลิเคชันไคลเอนต์ต้องลบทุกอย่าง
นั่นคือกรณีใช้งาน
ฉันมีActivity
A ที่เริ่มเข้าสู่ระบบActivity
L หรือActivity
B หลักของแอปขึ้นอยู่กับค่าที่ใช้ร่วมกัน Prefs หลังจากเริ่ม L หรือ B มันจะปิดตัวเองเพื่อให้เฉพาะ L หรือ B กำลังทำงาน ดังนั้นในกรณีที่ผู้ใช้เข้าสู่ระบบแล้ว B กำลังทำงานอยู่ในขณะนี้
B เริ่มต้น C. C เรียกstartService
หาIntentService
D ผลลัพธ์ในสแต็กนี้:
(A)> B> C> D
จากเมธอด onHandleIntent ของ D เหตุการณ์ถูกส่งไปที่ResultReceiver R
R ตอนนี้จัดการกับเหตุการณ์นั้นโดยให้ผู้ใช้โต้ตอบที่เขาสามารถเลือกรีเซ็ตแอปพลิเคชันจากโรงงาน (ลบฐานข้อมูล sharedPrefs ฯลฯ )
หลังจากรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานฉันต้องการรีสตาร์ทแอปพลิเคชั่น (เพื่อปิดกิจกรรมทั้งหมด) และเริ่ม A อีกครั้งเท่านั้นจากนั้นจึงเปิดใช้งานการเข้าสู่ระบบ Activity
L และเสร็จสิ้น:
(A)> L
วิธีการโต้ตอบของ Dialog มีลักษณะดังนี้:
@Override
public void onClick(DialogInterface dialog, int which) {
// Will call onCancelListener
MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
Intent i = new Intent(MyApp.getContext(), A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.getContext().startActivity(i);
}
และนั่นคือMyApp
ชั้นเรียน:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
public static void factoryReset() {
// ...
}
}
ปัญหาคือถ้าฉันใช้FLAG_ACTIVITY_NEW_TASK
กิจกรรม B และ C ยังคงทำงานอยู่ ถ้าฉันกดปุ่มย้อนกลับในการเข้าสู่ระบบActivity
ฉันเห็น C แต่ฉันต้องการกลับไปที่หน้าจอหลัก
หากฉันไม่ได้ตั้งค่าFLAG_ACTIVITY_NEW_TASK
ฉันจะได้รับข้อผิดพลาด:
07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
ฉันไม่สามารถใช้กิจกรรม ' Context
ได้เนื่องจากServiceIntent
D อาจถูกเรียกใช้จากงานเบื้องหลังซึ่งเริ่มโดยAlarmManager
ยังอาจจะเรียกว่าจากงานพื้นหลังซึ่งจะเริ่มจาก
ดังนั้นฉันจะแก้ปัญหานี้ให้กลายเป็นกิจกรรมสแต็ก (A)> L ได้อย่างไร