2013-04-23 8 views
6

unsere Android App launcht einen Logcat Shell-Prozess und liest dann das Ergebnis für die Verarbeitung. Wenn die App jedoch beendet wird (z. B. wenn sie nach der Neukompilierung während der Entwicklung neu gestartet wird), wird der Logcat-Prozess weiter ausgeführt. Hier ist ein Beispiel für dieses Verhalten:Android: Kind Prozess (Logcat) läuft weiter nach Elternprozess (App) gestorben

processes = new ArrayList<Process>(); 

try { 
    processes.add(Runtime.getRuntime().exec("logcat -v time")); 
    processes.add(Runtime.getRuntime().exec("logcat -v time")); 
    processes.add(Runtime.getRuntime().exec("logcat -v time")); 
    processes.add(Runtime.getRuntime().exec("logcat -v time")); 
} catch (IOException e) { 
    // oh no! 
} 

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
    for (Process p : processes) { 
     p.destroy(); 
    } 
    }; 
}); 

hinzufügen Zu den onCreate() -Methode eines Test-App, starten Sie es, dann zwang stoppen sie die Einstellung Manager. Die untergeordneten Prozesse werden weiter ausgeführt, jetzt mit einer übergeordneten ID 1.

In How to kill logcat process initiated by Android application? wurde vorgeschlagen, ProcessBuilder zu verwenden, aber das war keine Lösung und der Prozess wird auch weiterhin ausgeführt.

In Stop child process when parent process stops wurde vorgeschlagen, einen Shutdown-Hook zu verwenden - das funktioniert auch nicht wie oben gezeigt.

Danke!

+0

Haben Sie versucht, p.waitFor() nach p.destroy() aufzurufen? Der frühere Aufruf wartet darauf, dass der Kindprozess beendet wird, und erhält den Rückkehrstatus, bevor er fortfährt, den nächsten zu zerstören. – Vikdor

+0

@Vikdor Danke, aber nein, funktioniert nicht. Tatsächlich fügt das Hinzufügen eines Protokollierungsaufrufs im Shutdown-Hook hinzu, dass es überhaupt nicht aufgerufen wird, wenn die Anwendung (force) beendet wird. – hez

+0

Ich denke, die Kopie von 'processes' in' new Thread() 'ist leer. Haben Sie sich von der for-Schleife oder von außerhalb der Schleife angemeldet? Können Sie Prozesse als flüchtig markieren, sodass Threads die Kopie nicht zwischenspeichern und dann prüfen? – Vikdor

Antwort

1

Was Sie könnte Do spnaning ein anderes Skript, dessen einziger Zweck ist es, Ihr Java-Programm zu sehen. Wenn es stirbt, töte auch alle seine Kinder.

Ein fragiles Beispiel:

int pid = android.os.Process.myPid(); 
String script = "while [ -d /proc/" + pid + " ];do sleep 1;done; killall logcat"; 
Process p = Runtime.getRuntime().exec("/system/bin/sh", "-c", script); 

Dies setzt voraus, dass Ihr Prozess nicht als root ausgeführt wird, wodurch nur Prozesse ihrer eigenen logcat töten. In Ihrer Shutdown-Funktion sollten Sie zuerst die anderen Prozesse (logcat) beenden und dann p.destroy(); ausführen, um dieses Killer-Skript zu stoppen.

Das obige Skript kann durch Entfernen der Verwendung von killall verbessert werden. Rufen Sie stattdessen die Prozess-IDs Ihrer logcat Prozesse mit Reflection (this answer Punkte bis http://www.golesny.de/p/code/javagetpid) ab und übergeben Sie sie an kill.

+0

Brilliant, du bist so schlau. Danke, eine Milliarde Menschen! – Krypton

Verwandte Themen