Service Automatik bei der Zerstörung der Aktivität

Ich stecke mit dem Problem von Activity + Service dass ich folgende Anzahl von Aktivitäten und Services habe.

Aktivitäten:

LoginActivity => OrderListActivity => AddOrderActivity => ConfirmOrderActivity

  • Wiederholung einer Aufgabe mit einer Zeitverzögerung?
  • Ermittlung der Geschwindigkeit eines Fahrzeugs mit GPS in Android
  • Der Import android.support.v7.app.MediaRouteActionProvider kann nicht behoben werden
  • EditText maxLines funktioniert nicht - Benutzer können noch mehr Zeilen eingeben als gesetzt
  • Android VM stürzt beim Start von Mac ab
  • Wie grau ein Knopf aus?
  • Dienstleistungen:

    1. ReceivingOrderService – Empfangen neuer Daten vom Server
    2. SendingOrderService – Senden neuer Daten an Server

    Über beide Service-Aufruf von einem anderen separaten Service auf Dauer eines Intervalls .

    1. CheckAutoSyncReceivingOrder – Anrufen von ReceivingOrderService (Intervall 15Mins)
    2. CheckAutoSyncSendingOrder – Aufruf von SendingOrderService (Intervall 3Mins)

    CheckAutoSyncReceivingOrder:

     public class CheckAutoSyncReceivingOrder extends Service { Timer timer; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub if(timer != null) { timer.cancel(); Log.i(TAG, "RECEIVING OLD TIMER CANCELLED>>>"); } timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { if(InternetConnection.checkConnection(getApplicationContext())) { if(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists()) startService(new Intent(CheckAutoSyncReceivingOrder.this, ReceivingOrderService.class)); } else { Log.d(TAG, "Connection not available"); } } }, 0, 60000); // 1000*60*15 = 9,00,000 = 15 minutes } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if(timer != null) timer.cancel(); Log.d(TAG, "Stopping Receiving..."); } } 

    CheckAutoSyncSendingOrder:

     public class CheckAutoSyncSendingOrder extends Service { Timer timer; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub if(timer != null) { timer.cancel(); Log.i(TAG, "OLD TIMER CANCELLED>>>"); } timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Log.i(TAG, ">>>>>>>> SENDING AUTO SYNC SERVICE >>>>>>>>"); if(InternetConnection.checkConnection(getApplicationContext())) { if(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists()) startService(new Intent(CheckAutoSyncSendingOrder.this, SendingOrderService.class)); } else { Log.d(TAG, "connection not available"); } } }, 0, 120000); // 1000*120*15 = 1,800,000 = 15 minutes } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if(timer != null) timer.cancel(); Log.d(TAG, "Stopping Sending..."); } } 

    ConfirmOrderActivity # Final Task, die ich aufgerufen habe Insert Data:

     new AsyncTask<Void, Void, Integer>() { ProgressDialog progressDialog; @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); progressDialog = new ProgressDialog( ConfirmOrderProductActivity.this); progressDialog.setMessage("Inserting " + (isInquiry ? "Inquiry" : "Order") + "..."); progressDialog.setCancelable(false); progressDialog .setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.show(); } @Override protected Integer doInBackground(Void... params) { // TODO Auto-generated method stub int account_id = context.getSharedPreferences(PREF_DATA, MODE_APPEND).getInt(DATA_ACCOUNT_ID, 0); /** * Check Whether isInquiry or not... */ product_type = isWeight ? 1 : 0; if (isInquiry) { /* * INSERTING DATA IN INQUIRY TABLE */ return m_inquiry_id; } else { /* * INSERTING DATA IN ORDER TABLE */ return m_order_id; } } @Override protected void onPostExecute(Integer m_order_id) { // TODO Auto-generated method stub super.onPostExecute(m_order_id); progressDialog.dismiss(); if (dbHelper.db.isOpen()) dbHelper.close(); String title = "Retry"; String message = "There is some problem, Go Back and Try Again"; AlertDialog.Builder alert = new AlertDialog.Builder( ConfirmOrderProductActivity.this); if (m_order_id != -1) { title = isInquiry ? "New Inquiry" : "New Order"; message = isInquiry ? "Your Inquiry Send Successfully." : "Your Order Saved Successfully."; alert.setIcon(R.drawable.success).setCancelable(false); } else { alert.setIcon(R.drawable.fail).setCancelable(false); } alert.setTitle(title).setMessage(message) .setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub dialog.dismiss(); startActivity(new Intent( ConfirmOrderProductActivity.this, FragmentChangeActivity.class) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); /* Opening Left to Right Animation */ overridePendingTransition(R.anim.right_out, R.anim.right_in); } }); AlertDialog alertDialog = alert.create(); alertDialog.show(); } }.execute(); 

    Alles funktioniert gut wie nach dem Einfügen von Datensätzen in der Datenbank.

    Nach dem Hinzufügen von Anfrage:

    Bildbeschreibung hier eingeben

    Zerstörende Aktivität und folgende Logcat:

    Bildbeschreibung hier eingeben

    Hauptproblem:

    Wenn ich den Auftrag erfolgreich von ConfirmOrderActivity platzierte , zeigt er AlertDialog of Success Message an, der false . Wenn ich die Anwendung von dieser Aktivität CheckAutoSyncReceivingOrder , ruft er sowohl CheckAutoSyncReceivingOrder als auch CheckAutoSyncSendingOrder automatisch an.

    Bearbeitet:

    Ich rufe beide Service nur von LoginActivity , danach wird es automatisch nach vorgegebenen Intervallen aufgerufen. Aber Problem tritt auf, wenn ich ConfirmOrderActivity zerstöre, wenn der Dialog angezeigt wird.

    Ich wusste nicht, warum es passiert, dass, warum es läuft automatisch, wenn ich die Aktivität direkt zu stoppen.

    Ich habe versucht onStartCommand() mit START_NON_STICKY in Service aber nicht funktioniert. (als START_STICKY ist Standard.)

     @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY; } 

    Gibt es eine Lösung?

  • Wie benutzt man Facebook Access Token in Android App Webview
  • Wie kann man Google Map laden?
  • Android ProgressBar.setProgressDrawable funktioniert nur einmal?
  • Chrome devTools sehen keine USB-Geräte mehr zum Debuggen
  • Kann Android KitKat Geräte, die Bluetooth LE unterstützen, als Peripheriegerät fungieren?
  • Erste Schritte mit Android
  • 4 Solutions collect form web for “Service Automatik bei der Zerstörung der Aktivität”

    Sie müssen entweder Ihren Dienst in den Vordergrund laufen, so dass, wenn die Aktivität zerstört wird, so wird der Dienst oder verwenden Sie einen gebundenen Service und verwalten Sie die Bindung mit dem Aktivitätslebenszyklus, so dass es nicht ständig neu gestartet wird, wenn die Aktivität zerstört wird.

    Von diesem androiden docs tutorial Bound Services

    Sie müssen dies für jeden Service tun.

     public class CheckAutoSyncReceivingOrder extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); public class LocalBinder extends Binder { CheckAutoSyncReceivingOrder getService() { return CheckAutoSyncReceivingOrder.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } 

    Von deiner Aktivität, die den Dienst schafft und anruft, wenn du zerstört wurdest, willst du deinen Dienst zerstört haben.

     public class BindingActivity extends Activity { CheckAutoSyncReceivingOr mService; boolean mBound = false; @Override protected void onStart() { super.onStart(); // Bind to CheckAutoSyncReceivingOr Intent intent = new Intent(this, CheckAutoSyncReceivingOr.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to CheckAutoSyncReceivingOr, cast the IBinder and get CheckAutoSyncReceivingOr instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; } 

    Und den Service-Lebenszyklus zu verwalten . Starten Sie denselben Dienst mit Ihrem Timer neu, erstellen Sie keinen neuen Dienst.

     public class ExampleService extends Service { int mStartMode; // indicates how to behave if the service is killed IBinder mBinder; // interface for clients that bind boolean mAllowRebind; // indicates whether onRebind should be used @Override public void onCreate() { // The service is being created } @Override public int onStartCommand(Intent intent, int flags, int startId) { // The service is starting, due to a call to startService() return mStartMode; } @Override public IBinder onBind(Intent intent) { // A client is binding to the service with bindService() return mBinder; } @Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() return mAllowRebind; } @Override public void onRebind(Intent intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } @Override public void onDestroy() { // The service is no longer used and is being destroyed } } 

    Hinweis START_NOT_STICKY wird nur verhindern, dass der Dienst neu startet, wenn das Gerät im Speicher START_NOT_STICKY ist.

    Achten Sie darauf, dass Sie, wo Sie starten Dienstleistungen, nur starten Sie es einmal und lassen Sie den Service zu halten, es ist eigenen Lebenszyklus, bis Sie es mit Ihrer Aktivität zu zerstören.

    Dies ist in Antwort auf Ihre ursprüngliche unzählige Frage, als die App geheimnisvoll zusammenstürzte:

    Sie müssen den Dialog vor dem Kontextfenster zerstören, an dem der Dialog angeschlossen ist. Das wird ein Problem verursachen. So ist hier der Programmablauf und die Reihenfolge der Schließung und Reinigung der Ressourcen wichtig. Sie müssen in der umgekehrten Reihenfolge häufig zerstört werden, wenn sie von den Elternfenstern abhängig sind (was oft in Form einer bestimmten Aktivität liegt).

    Es ist schwierig, deinen Code zu verfolgen, also ist dies eine generische Antwort.

    Nutzen Sie onPause und onDestroy in Ihren Aktivitäten.

    In all Ihren Aktivitäten, verwalten Sie alle Ressourcen, die Sie innerhalb dieser Aktivität erstellt haben und mit einem Null-Check, schließen Sie sie nach unten. Wie du in deiner Dienstklasse hast. Wenn du das übergeordnete OnDestroy überschreiben willst, platziere deinen benutzerdefinierten Code vor super.onDestroy.

     protected void onDestroy() { if(timer != null) timer.cancel(); Log.d(TAG, "Stopping Sending..."); super.onDestroy(); } 

    (1) Für deinen Dialog:

    Die Lösung lautet die dismiss() auf den Dialog du erstellt hast, bevor du die Activity onDestroy() , zB in onDestroy() . Alle Windows & Dialog sollten vor dem Verlassen einer Activity .

    (2) Für Ihren Service Autostart:

    Sie müssen sich den Wert ansehen, den der Dienst von seiner onStartCommand-Methode zurückgibt. Der Standardwert ist START_STICKY, der den Dienst nach dem Zerstören neu starten wird. Schauen Sie sich die onStartCommand Dokumentation für weitere Details an:

    Wenn der Prozess, der Ihren Dienst ausführt, getötet wird, wird das Android-System es automatisch neu starten, ist es Standardverhalten.

    Dieses Verhalten wird durch den Rückgabewert von onStartCommand() in Ihrer Service-Implementierung definiert. Die Konstante START_NOT_STICKY sagt, dass Android den Dienst nicht neu starten muss, wenn es läuft, während der Prozess "getötet" wird.

    Sie müssen die Methode onStartCommand() in Ihrer Serviceklasse onStartCommand() und alle Code aus der onStart() Methode in die onStartCommand() Methode verschieben.

    Laut der Android-Dokumentation:

    Für gestartete Dienste gibt es zwei zusätzliche Hauptbetriebsarten, die sie je nach dem Wert, den sie von onStartCommand() entscheiden können onStartCommand() : START_STICKY wird für Dienste verwendet, die explizit gestartet und gestoppt werden, während START_NOT_STICKY oder START_REDELIVER_INTENT verwendet werden für Dienste, die nur während der Verarbeitung von Befehlen, die an sie gesendet werden, laufen bleiben

    onStart() -Methode ruft jedes Mal auf, wenn der Dienst neu gestartet wird, aber onStartCommand() -Methode wird nicht aufgerufen, wenn Sie START_NON_STICKY .

    Verwenden Sie nicht onStart () nicht mehr, es ist veraltet.

    Ich hoffe es hilft dir.

    Services wurden getötet, wenn die Anwendung getötet wurde (fügen Sie Protokolle in Service onStartCommand() und onDestroy() -Funktion hinzu und versuchen Sie, App aus der aktuellen Liste zu onDestroy() und Sie werden sehen, onDestroy() wird aufgerufen. Android wird den Service neu starten, wenn Sie START_STICKY Absicht zurückgegeben haben onStartCommand() ).

    Es gibt zwei Ansätze, um Ihr Problem zu beheben.

    1. Entweder machen Sie Ihre zwei Dienste als Vordergrund Service .

    2. Anstatt mit CheckAutoSyncReceivingOrder und CheckAutoSyncSendingOrder den Start eines anderen Services zu planen, sollten Sie AlarmManager um Ihre Aufgabe zu planen.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.