İ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 Activity
Oturum Açma Activity
L veya uygulamanın ana Activity
B 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 Activity
L 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 MyApp
sı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_TASK
B ve C Faaliyetleri kullanmak hala çalışıyor olmasıdır. Girişteki geri düğmesine basarsam Activity
C'yi görürüm, ancak ana ekrana geri dönmek istiyorum.
Eğer ben ayarlamazsanız FLAG_ACTIVITY_NEW_TASK
hatayı 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ü ServiceIntent
D, 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?