İlk olarak, Android'de bir uygulamayı gerçekten öldürmemesi / yeniden başlatmaması gerektiğini biliyorum. Kullanım durumumda, sunucunun istemciye belirli bir bilgi gönderdiği belirli bir durumda uygulamamı fabrika ayarlarına sıfırlamak istiyorum.
Kullanıcı sunucuda yalnızca uygulamanın BİR örneği ile oturum açabilir (yani birden çok cihaza izin verilmez). Başka bir örnek "oturum açıldı" kilidini alırsa, tutarlılığı korumak için kullanıcının diğer tüm örneklerinin verilerini silmesi (fabrika ayarlarına sıfırlama) gerekir.
Kilidi zorla almak mümkündür, çünkü kullanıcı uygulamayı silebilir ve farklı bir örnek kimliğine neden olacak şekilde yeniden yükleyebilir ve kullanıcı kilidi artık serbest bırakamaz. Bu nedenle kilidi zorla almak mümkündür.
Bu güç olasılığı nedeniyle, somut bir durumda her zaman kilidinin olduğunu kontrol etmeliyiz. Bu sunucuya neredeyse her istek üzerine yapılır. Sunucu bir "yanlış kilit kimliği" gönderebilir. Bu tespit edilirse, istemci uygulamasının her şeyi silmesi gerekir.
Kullanım davası buydu.
Bir paylaşılanPrefs değerine bağlı olarak ActivityOturum Açma ActivityL veya uygulamanın ana ActivityB başlatan bir A var . L veya B'yi başlattıktan sonra kendini kapatır, böylece sadece L veya B çalışır. Yani kullanıcının giriş yapmış olması durumunda zaten B çalışıyor.
B C'yi başlatır. C D'yi çağırır startService.IntentService
(A)> B> C> D
OnHandleIntent D yönteminden ResultReceiver R'ye bir olay gönderilir.
R artık kullanıcıya uygulamayı fabrika ayarlarına sıfırlamayı (veritabanını silme, sharedPrefs, vb.) Seçebileceği bir iletişim kutusu sağlayarak bu olayı işler.
Sonra (bütün faaliyetleri kapatmak için) ve ancak o zaman giriş açılacağı tekrar A başlatmak uygulamayı yeniden başlatmak istiyorum fabrikada-reset ActivityL ve kendisini bitirir:
(A)> L
İletişim Kutusunun onClick yöntemi şuna benzer:
@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);
}
Ve bu MyAppsınıf:
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() {
// ...
}
}
Sorun FLAG_ACTIVITY_NEW_TASKB ve C Faaliyetleri kullanmak hala çalışıyor olmasıdır. Girişteki geri düğmesine basarsam ActivityC'yi görürüm, ancak ana ekrana geri dönmek istiyorum.
Eğer ben ayarlamazsanız FLAG_ACTIVITY_NEW_TASKhatayı alıyorum:
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?
Etkinlikler'i kullanamıyorum Context, çünkü ServiceIntentD, tarafından başlatılan bir arka plan görevinden de çağrılabilir AlarmManager.
Peki bunu (A)> L olan aktivite yığınına nasıl çözebilirim?