Mit Hintergrund meine ich, dass keine der Aktivitäten der Anwendung derzeit für den Benutzer sichtbar sind?
Antworten
Zu viele Anzeigen?Wenn Sie die Entwicklereinstellungen "Aktivitäten nicht behalten" aktivieren, reicht es nicht aus, nur die Anzahl der erstellten Aktivitäten zu überprüfen. Sie müssen auch prüfen isSaveInstanceState . Meine eigene Methode isApplicationRunning() Prüfen Sie, ob die Android-App läuft:
Hier mein Arbeitscode:
public class AppLifecycleService implements Application.ActivityLifecycleCallbacks {
private int created;
private boolean isSaveInstanceState;
private static AppLifecycleService instance;
private final static String TAG = AppLifecycleService.class.getName();
public static AppLifecycleService getInstance() {
if (instance == null) {
instance = new AppLifecycleService();
}
return instance;
}
public static boolean isApplicationRunning() {
boolean isApplicationRunning = true;
if (getCountCreatedActvities() == 0 && !isSaveInstanceState()) {
isApplicationRunning = false;
}
return isApplicationRunning;
}
public static boolean isSaveInstanceState() {
return AppLifecycleService.getInstance().isSaveInstanceState;
}
public static int getCountCreatedActvities() {
return AppLifecycleService.getInstance().created;
}
private AppLifecycleService() {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
this.isSaveInstanceState = true;
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
++created;
}
@Override
public void onActivityDestroyed(Activity activity) {
--created;
}
@Override
public void onActivityResumed(Activity activity) { }
@Override
public void onActivityPaused(Activity activity) { }
@Override
public void onActivityStarted(Activity activity) { }
@Override
public void onActivityStopped(Activity activity) { }
}
Ich habe meine eigene Implementierung von ActivityLifecycleCallbacks. Ich bin mit SherlockActivity, aber für normale Aktivität Klasse könnte funktionieren.
Zunächst erstelle ich eine Schnittstelle, die alle Methoden zur Verfolgung des Lebenszyklus der Aktivitäten enthält:
public interface ActivityLifecycleCallbacks{
public void onActivityStopped(Activity activity);
public void onActivityStarted(Activity activity);
public void onActivitySaveInstanceState(Activity activity, Bundle outState);
public void onActivityResumed(Activity activity);
public void onActivityPaused(Activity activity);
public void onActivityDestroyed(Activity activity);
public void onActivityCreated(Activity activity, Bundle savedInstanceState);
}
Zweitens habe ich diese Schnittstelle in der Klasse meiner Anwendung implementiert:
public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onActivityStopped(Activity activity) {
Log.i("Tracking Activity Stopped", activity.getLocalClassName());
}
@Override
public void onActivityStarted(Activity activity) {
Log.i("Tracking Activity Started", activity.getLocalClassName());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
}
@Override
public void onActivityResumed(Activity activity) {
Log.i("Tracking Activity Resumed", activity.getLocalClassName());
}
@Override
public void onActivityPaused(Activity activity) {
Log.i("Tracking Activity Paused", activity.getLocalClassName());
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Tracking Activity Created", activity.getLocalClassName());
}
}
Drittens erstelle ich eine Klasse, die von SherlockActivity erweitert wird:
public class MySherlockActivity extends SherlockActivity {
protected MyApplication nMyApplication;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
nMyApplication = (MyApplication) getApplication();
nMyApplication.onActivityCreated(this, savedInstanceState);
}
protected void onResume() {
// TODO Auto-generated method stub
nMyApplication.onActivityResumed(this);
super.onResume();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
nMyApplication.onActivityPaused(this);
super.onPause();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
nMyApplication.onActivityDestroyed(this);
super.onDestroy();
}
@Override
protected void onStart() {
nMyApplication.onActivityStarted(this);
super.onStart();
}
@Override
protected void onStop() {
nMyApplication.onActivityStopped(this);
super.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
nMyApplication.onActivitySaveInstanceState(this, outState);
super.onSaveInstanceState(outState);
}
}
Viertens, alle Klassen, die von SherlockActivity erweitern, habe ich für MySherlockActivity ersetzt:
public class MainActivity extends MySherlockActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
In logcat sehen Sie nun die Protokolle, die in der Schnittstellenimplementierung in MyApplication programmiert wurden.
Es gibt nur eine richtige Lösung:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
MyApp.mainActivity = this;
super.onCreate(savedInstanceState);
...
}
MyApp.java:
public class MyApp extends Application implements LifecycleObserver {
public static MainActivity mainActivity = null;
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onAppBackgrounded() {
// app in background
if (mainActivity != null) {
...
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onAppForegrounded() {
// app in foreground
if (mainActivity != null) {
...
}
}
}
Das System unterscheidet zwischen Anwendungen im Vordergrund und im Hintergrund. (Die Definition von Hintergrund für die Zwecke der Diensteinschränkungen unterscheidet sich von der Definition, die von der Speicherverwaltung verwendet wird; eine Anwendung kann sich im Hintergrund befinden in Bezug auf Speicherverwaltung sondern im Vordergrund, was ihre Fähigkeit betrifft, Dienste zu starten). Eine Anwendung wird als im Vordergrund befindlich betrachtet, wenn einer der folgenden Punkte zutrifft:
- Sie hat eine sichtbare Aktivität, unabhängig davon, ob die Aktivität gestartet oder pausiert ist.
- Sie hat einen Vordergrunddienst.
- Eine andere Vordergrundanwendung ist mit der Anwendung verbunden, entweder durch Bindung an einen ihrer Dienste oder durch Inanspruchnahme eines ihrer Inhaltsanbieter. Die App ist beispielsweise im Vordergrund, wenn eine andere App eine Bindung mit ihr eingeht:
- IME
- Tapetendienst
- Hörer für Benachrichtigungen
- Sprach- oder Textdienst
Wenn keine dieser Bedingungen zutrifft, wird die Anwendung als im Hintergrund laufend betrachtet.
Um das, was CommonsWare und Key gesagt haben, zu ergänzen, könnten Sie vielleicht die Klasse Application erweitern und alle Ihre Aktivitäten diese bei ihren onPause/onResume-Methoden aufrufen lassen. Dies würde Ihnen ermöglichen, zu wissen, welche Aktivität(en) sichtbar sind, aber dies könnte wahrscheinlich besser gehandhabt werden.
Können Sie näher erläutern, was Sie genau vorhaben? Wenn Sie sagen, dass die Anwendung im Hintergrund läuft, meinen Sie dann einfach, dass sie sich noch im Speicher befindet, obwohl sie gerade nicht auf dem Bildschirm ist? Haben Sie die Verwendung von Diensten als eine dauerhaftere Möglichkeit, Ihre Anwendung zu verwalten, wenn sie nicht im Fokus ist, in Betracht gezogen?