Đầu tiên, tôi biết rằng một người không nên thực sự giết / khởi động lại một ứng dụng trên Android. Trong trường hợp sử dụng của tôi, tôi muốn thiết lập lại ứng dụng của mình trong một trường hợp cụ thể trong đó máy chủ gửi thông tin cụ thể đến máy khách.
Người dùng chỉ có thể đăng nhập trên máy chủ với MỘT phiên bản của ứng dụng (tức là không cho phép nhiều thiết bị). Nếu một phiên bản khác nhận được rằng "đã đăng nhập" -lock thì tất cả các phiên bản khác của người dùng đó phải xóa dữ liệu của họ (khôi phục cài đặt gốc), để duy trì tính nhất quán.
Có thể buộc phải khóa, vì người dùng có thể xóa ứng dụng và cài đặt lại, điều này sẽ dẫn đến một id-id khác và người dùng sẽ không thể giải phóng khóa nữa. Do đó, có thể buộc phải có được khóa.
Do khả năng bắt buộc đó, chúng tôi cần phải luôn kiểm tra trong trường hợp cụ thể rằng nó có khóa. Điều đó được thực hiện trên (gần như) mỗi yêu cầu đến máy chủ. Máy chủ có thể gửi "id khóa sai". Nếu điều đó được phát hiện, ứng dụng khách phải xóa mọi thứ.
Đó là trường hợp sử dụng.
Tôi có một Activity
A bắt đầu Đăng nhập Activity
L hoặc Activity
B chính của ứng dụng tùy thuộc vào giá trị sharedPrefs. Sau khi bắt đầu L hoặc B, nó tự đóng lại để chỉ L hoặc B đang chạy. Vì vậy, trong trường hợp người dùng đã đăng nhập thì B đang chạy.
B bắt đầu C. C gọi startService
cho IntentService
D. Điều đó dẫn đến ngăn xếp này:
(A)> B> C> D
Từ phương thức onHandleIntent của D, một sự kiện được gửi tới resultReceiver R.
Bây giờ R xử lý sự kiện đó bằng cách cung cấp cho người dùng một hộp thoại trong đó anh ta có thể chọn đặt lại nhà máy ứng dụng (xóa cơ sở dữ liệu, sharedPrefs, v.v.)
Sau khi khôi phục cài đặt gốc, tôi muốn khởi động lại ứng dụng (để đóng tất cả các hoạt động) và chỉ khởi động lại A sau đó khởi chạy Activity
L đăng nhập và tự hoàn tất:
(A)> L
Phương thức onClick của Dialog trông như thế này:
@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);
}
Và đó là MyApp
lớp học:
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() {
// ...
}
}
Vấn đề là nếu tôi sử dụng FLAG_ACTIVITY_NEW_TASK
Hoạt động B và C vẫn đang chạy. Nếu tôi nhấn nút quay lại khi đăng nhập, Activity
tôi thấy C, nhưng tôi muốn quay lại màn hình chính.
Nếu tôi không đặt, FLAG_ACTIVITY_NEW_TASK
tôi nhận được lỗi:
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?
Tôi không thể sử dụng Hoạt động ' Context
, vì ServiceIntent
D cũng có thể được gọi từ tác vụ nền được khởi động bởi AlarmManager
.
Vậy làm thế nào tôi có thể giải quyết điều này để ngăn xếp hoạt động trở thành (A)> L?