Ich möchte wissen, wie man einen Thread in Android am besten stoppt. Ich weiß, dass ich AsyncTask
stattdessen verwenden kann und dass es eine cancel()
Methode gibt. Ich muss Thread
s in meiner Situation verwenden. Hier ist, wie ich benutze Thread
:
Runnable runnable = new Runnable() {
@Override
public void run() {
//doing some work
}
};
new Thread(runnable).start();
Hat jemand eine Idee, wie man einen Thread am besten stoppen kann?
android
thread-safety
Android-Droid
quelle
quelle
stop()
Methode ist veraltet und Sie sollten das nicht mehr verwenden.Diese Situation unterscheidet sich in keiner Weise von der Standard-Java. Sie können die Standardmethode zum Stoppen eines Threads verwenden:
class WorkerThread extends Thread { volatile boolean running = true; public void run() { // Do work... if (!running) return; //Continue doing the work } }
Die Hauptidee ist, von Zeit zu Zeit den Wert des Feldes zu überprüfen. Wenn Sie Ihren Thread stoppen müssen, setzen Sie
running
auf false. Wie Chris bereits betont hat, können Sie auch den Unterbrechungsmechanismus verwenden.Übrigens, wenn Sie AsyncTask verwenden, wird sich Ihr Ansatz nicht wesentlich unterscheiden. Der einzige Unterschied besteht darin, dass Sie die
isCancel()
Methode Ihrer Aufgabe aufrufen müssen, anstatt ein spezielles Feld zu haben. Wenn Siecancel(true)
diesen Mechanismus aufrufen , aber nicht implementieren, stoppt der Thread immer noch nicht von selbst, sondern läuft bis zum Ende.quelle
Unter Android gelten die gleichen Regeln wie in einer normalen Java-Umgebung. In Java werden Threads nicht getötet, aber das Stoppen eines Threads erfolgt auf kooperative Weise . Der Thread wird zum Beenden aufgefordert und der Thread kann dann ordnungsgemäß heruntergefahren werden.
Oft wird ein
volatile boolean
Feld verwendet, das der Thread regelmäßig überprüft und beendet, wenn er auf den entsprechenden Wert gesetzt wird.Ich würde a nicht verwenden
boolean
, um zu überprüfen, ob der Thread beendet werden soll . Wenn Sievolatile
als Feldmodifikator verwenden, funktioniert dies zuverlässig. Wenn Ihr Code jedoch komplexer wird und stattdessen andere Blockierungsmethoden innerhalb derwhile
Schleife verwendet, kann es vorkommen, dass Ihr Code überhaupt nicht beendet wird oder zumindest länger dauert als Sie könnte wollen.Jeder Thread hat bereits einen Status eines unterbrochenen Booleschen Flags, den Sie verwenden sollten. Es kann folgendermaßen implementiert werden:
public void run() { try { while(!Thread.currentThread().isInterrupted()) { // ... } } catch (InterruptedException consumed) /* Allow thread to exit */ } } public void cancel() { interrupt(); }
Quellcode aus Java Concurrency in der Praxis . Da die
cancel()
Methode öffentlich ist, können Sie einen anderen Thread diese Methode wie gewünscht aufrufen lassen.Es gibt auch eine schlecht benannte statische Methode,
interrupted
die den unterbrochenen Status des aktuellen Threads löscht.quelle
if (Thread.interrupted()) { throw new InterruptedException();}
Die
Thread.stop()
Methode zum Stoppen eines Threads ist veraltet. Für weitere Informationen siehe; Warum sind Thread.stop, Thread.suspend und Thread.resume veraltet? .Am besten haben Sie eine Variable, die der Thread selbst konsultiert und freiwillig beendet, wenn die Variable einem bestimmten Wert entspricht. Anschließend bearbeiten Sie die Variable in Ihrem Code, wenn der Thread beendet werden soll. Alternativ können Sie natürlich auch eine
AsyncTask
verwenden.quelle
Derzeit und leider können wir nichts tun, um den Thread zu stoppen ....
Fügen Sie etwas zu Matts Antwort hinzu, die wir aufrufen können,
interrupt()
aber das stoppt den Thread nicht ... Weist das System nur an, den Thread zu stoppen, wenn das System einige Threads beenden möchte. Der Rest wird vom System erledigt und wir können ihn durch einen Anruf überprüfeninterrupted()
.[ps: Wenn Sie wirklich mitmachen,
interrupt()
würde ich Sie bitten, nach dem Anruf einige Experimente mit einem kurzen Schlaf durchzuführeninterrupt()
]quelle
Es gibt zwei Möglichkeiten, einen Thread zu stoppen.
Erstellen Sie eine flüchtige boolesche Variable, ändern Sie ihren Wert in false und überprüfen Sie sie im Thread.
flüchtig isRunning = false;
public void run () {if (! isRunning) {return;}}
Oder Sie können die Interrupt () -Methode verwenden, die innerhalb eines Threads empfangen werden kann.
SomeThread.interrupt ();
public void run () {if (Thread.currentThread.isInterrupted ()) {return;}}
quelle
Versuchen Sie es so
Thread thread = new Thread() { @Override public void run() { Looper.prepare(); while(true){ Log.d("Current Thread", "Running"); try{ Thread.sleep(1000); }catch(Exeption Ex){ } } } } thread.start(); thread.interrupt();
quelle
Ich habe diese Methode angewendet.
Looper.myLooper().quit();
Du kannst es versuchen.
quelle
Das hat bei mir so funktioniert. Führen Sie eine statische Variable in die Hauptaktivität ein und überprüfen Sie regelmäßig, wie ich es unten getan habe.
public class MainActivity extends AppCompatActivity { //This is the static variable introduced in main activity public static boolean stopThread =false; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread thread = new Thread(new Thread1()); thread.start(); Button stp_thread= findViewById(R.id.button_stop); stp_thread.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v){ stopThread = true; } } } class Thread1 implements Runnable{ public void run() { // YOU CAN DO IT ON BELOW WAY while(!MainActivity.stopThread) { Do Something here } //OR YOU CAN CALL RETURN AFTER EVERY LINE LIKE BELOW process 1 goes here; //Below method also could be used if(stopThread==true){ return ; } // use this after every line process 2 goes here; //Below method also could be used if(stopThread==true){ return ; } // use this after every line process 3 goes here; //Below method also could be used if(stopThread==true){ return ; } // use this after every line process 4 goes here; } } }
quelle
Wenn Ihr Projekt eine Thread-Klasse mit einem Handler enthält, können Sie beim Starten von einer der Fragmentklassen, wenn Sie hier anhalten möchten, die App stoppen und einen Absturz vermeiden, wenn das Fragment vom Stapel entfernt wird.
Dieser Code ist in Kotlin . Es funktioniert perfekt.
class NewsFragment : Fragment() { private var mGetRSSFeedsThread: GetRSSFeedsThread? = null private val mHandler = object : Handler() { override fun handleMessage(msg: Message?) { if (msg?.what == GetRSSFeedsThread.GETRSSFEEDSTHREAD_SUCCESS) { val updateXMLdata = msg.obj as String if (!updateXMLdata.isNullOrEmpty()) parseUpdatePager(CommonUtils.getJSONObjectFromXML(updateXMLdata).toString()) } else if (msg?.what == GetRSSFeedsThread.GETRSSFEEDSTHREAD_SUCCESS) { BaseActivity.make_toast(activity, resources.getString(R.string.pleaseTryAgain)) } } } private var rootview: View? = null; override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { rootview = inflater?.inflate(R.layout.fragment_news, container, false); news_listView = rootview?.findViewById(R.id.news_listView) mGetRSSFeedsThread = GetRSSFeedsThread(this.activity, mHandler) if (CommonUtils.isInternetAvailable(activity)) { mGetRSSFeedsThread?.start() } return rootview } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true); } override fun onAttach(context: Context?) { super.onAttach(context) println("onAttach") } override fun onPause() { super.onPause() println("onPause fragment may return to active state again") Thread.interrupted() } override fun onStart() { super.onStart() println("onStart") } override fun onResume() { super.onResume() println("onResume fragment may return to active state again") } override fun onDetach() { super.onDetach() println("onDetach fragment never return to active state again") } override fun onDestroy() { super.onDestroy() println("onDestroy fragment never return to active state again") //check the state of the task if (mGetRSSFeedsThread != null && mGetRSSFeedsThread?.isAlive!!) { mGetRSSFeedsThread?.interrupt(); } else { } } override fun onDestroyView() { super.onDestroyView() println("onDestroyView fragment may return to active state again") } override fun onStop() { super.onStop() println("onStop fragment may return to active state again") } }
Der obige Code stoppt den laufenden Thread, wenn Sie vom aktuellen Fragment zu einem anderen Fragment oder einer anderen Aktivität wechseln. Außerdem wird es neu erstellt, wenn Sie zum aktuellen Fragment zurückkehren
quelle
Die Sache ist, müssen Sie überprüfen, ob der Thread läuft oder nicht !?
Feld:
private boolean runningThread = false;
Im Thread:
new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep((long) Math.floor(speed)); if (!runningThread) { return; } yourWork(); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start();
Wenn Sie den Thread stoppen möchten, sollten Sie das folgende Feld erstellen
private boolean runningThread = false;
quelle
Thread
, es wird nur aufhörenyourWork();
, aufgerufen zu werden. Um dies zu testen, können Sie eineLog
unten hinzufügenpublic void run() {
If you want to stop the thread you should make the below field: private boolean runningThread = false;
. Das ist nicht richtig.Meine Anforderung war etwas anders als die Frage, dennoch ist dies auch eine nützliche Möglichkeit, den Thread anzuhalten, um seine Aufgaben auszuführen. Alles, was ich tun wollte, ist, den Thread beim Verlassen des Bildschirms anzuhalten und fortzusetzen, während ich zum Bildschirm zurückkehre.
Gemäß den Android-Dokumenten wäre dies der vorgeschlagene Ersatz für die Stop- Methode, die von API 15 nicht mehr unterstützt wird
Meine Thread-Klasse
class ThreadClass implements Runnable { ... @Override public void run() { while (count < name.length()) { if (!exited) // checks boolean { // perform your task } ...
OnStop und OnResume würden so aussehen
@Override protected void onStop() { super.onStop(); exited = true; } @Override protected void onResume() { super.onResume(); exited = false; }
quelle
Da wir wissen, dass Thread.stop () in JAVA veraltet ist, ruft Thread.stop unter der Haube die Interrupt () -Methode für den Thread auf, um ihn zu stoppen. Interrupt soll von den Methoden ausgelöst werden, auf die der Thread wartet Ein anderer Thread, der nach Abschluss der Ausführung benachrichtigt werden soll. Ein Interrupt verursacht nichts für den Thread, wenn er bei der Ausführung eines Threads nicht behandelt wird, wie z. B.
if(Thread.interrupted())return;
Alles in allem müssen wir also den Start und Stopp des Threads so verwalten, als würde diestart()
Methode aufgerufen , wieThread.start()
einwhile(true)
innerhalb derrun()
Methode des Threads Thread und prüft in jeder Iteration auf unterbrochenen Status und kehrt vom Thread zurück.Bitte beachten Sie, dass ein Thread in den folgenden Situationen nicht stirbt:
quelle
Innerhalb einer Activity-Klasse erstellen Sie eine Methode, die der Thread-Instanz NULL zuweist, die als Alternative zur veralteten stop () -Methode zum Stoppen der Thread-Ausführung verwendet werden kann:
public class MyActivity extends Activity { private Thread mThread; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mThread = new Thread(){ @Override public void run(){ // Perform thread commands... for (int i=0; i < 5000; i++) { // do something... } // Call the stopThread() method. stopThread(this); } }; // Start the thread. mThread.start(); } private synchronized void stopThread(Thread theThread) { if (theThread != null) { theThread = null; } } }
Das funktioniert bei mir problemlos.
quelle
Thread
Variable auf setzen,null
wird der Thread nicht gestoppt. Das Argument nachnull
innen zu setzenstopThread
ist reine Zeitverschwendung.