Android:threadの終了、保留、リカバリ
5672 ワード
Androidアプリケーションの開発では、新しいスレッドを作成することでいくつかのタスクを完了する必要がある場合があります.たとえば、検索動作を行い、検索に時間がかかる場合は、ユーザがデッドラインが発生したと判断しないように、進捗バーを通じてユーザの検索の進捗状況を提示する必要があります.この場合、進捗バーのリフレッシュには別のスレッドが必要です.
しかし、ここでは、マルチスレッド開発時に、作成したスレッドのActivityから終了すると(Activityが破棄される)、Activityで作成したカスタムスレッドも破棄されると勘違いする誤りがあります.実はこれは大間違いです.
上記の場合、作成されたスレッドは自動的に破棄されるのではなく、自分で終了するまでバックグラウンドで無名で実行されることが実証されています.Androidのこのデザインは間違いない.理論的に説明すると、適用される最小実行単位はスレッドであり、最小リソース単位はプロセスであり、1つのプロセスは複数のスレッドを含み、複数のスレッドは同じ所属プロセスのリソースを共有することができる.したがって、Androidの応用は実はプロセスであり、中の各UI、Activityはこのプロセスに依存するスレッドであり、1つのActivityから別のActivityに入る本質は、前のスレッドを掛けて、後のスレッドを作成することである.脱退も同じだ.カスタムスレッドもこの原則に従います.スレッドの終了を制御しない限り、スレッドが本当に終了するのは、スレッドの実行が完了したか、または所属するプロセスが破棄された場合に限られます.
以上,カスタムスレッドがまだ実行されていない場合に,関連動作を終了する必要がある場合には,関連スレッドを終了すると考えられる.たとえば、検索中に検索を続行せずに検索機能を終了するには、カスタム検索スレッドを終了する必要があります.そうしないと重大なエラーを引き起こす可能性があります.たとえば、検索機能に繰り返しアクセスして検索し、検索が終了しないときに終了してからアクセスします.この場合、以前のカスタムスレッドが終了していないため、その後、複数の新しい検索スレッドが作成され、臨界領域の衝突を招きやすく、デバイスがダウンタイムになります.
では、これらのカスタムスレッドをどのように制御しますか?以下、筆者は詳細に説明する.
一.スレッドの終了
実際には、ヘルプドキュメントを通じて、Androidのスレッドクラス自体がスレッドを終了するための共通の方法を提供していることがわかります.
void destroy()
This method is deprecated. Not implemented.
synchronized final void stop(Throwable throwable)
This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state.
final void stop()
This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state
しかし、説明を通じて、これらの方法Android自体は推奨されていません.この方法でスレッドを終了するのは安全ではありません.アプリケーションを終了させ、仮想マシンを予想できない状態にする可能性があります.では、開発の過程で、合理的なニーズの中で、私たちはどのようにして指定されたカスタムスレッドを安全に終了しますか?筆者は救いに来た.
1.カスタムスレッドクラスでブールプライベート変数を定義し、スレッドの実行状態を記録するために偽に初期化できます.
2.run関数から、スレッドが実行状態に入ったことを示す変数を真に設定します.
3.run関数の終了位置で、この変数を偽に設定し、スレッドが終了状態に入ったことを示す.
4.runのスレッド実行部分では、いくつかの粘り強い点を探して、この変数を判断することができます.もし本当なら、実行を続けます.そうしないと、run関数を終了します.
5.上記の状態変数を偽に設定する役割を果たすカスタムスレッドクラスに共通の関数を追加します.
これにより、カスタムスレッドの実行がまだ終了していない場合、5のメソッドを呼び出してスレッドを安全に終了することができます.
思想の本質は、スレッドを安全に強制的に終了させることができない以上、安全に早期に終了させることです.効果は同じです.
プログラムの例:
しかし、ここでは、マルチスレッド開発時に、作成したスレッドのActivityから終了すると(Activityが破棄される)、Activityで作成したカスタムスレッドも破棄されると勘違いする誤りがあります.実はこれは大間違いです.
上記の場合、作成されたスレッドは自動的に破棄されるのではなく、自分で終了するまでバックグラウンドで無名で実行されることが実証されています.Androidのこのデザインは間違いない.理論的に説明すると、適用される最小実行単位はスレッドであり、最小リソース単位はプロセスであり、1つのプロセスは複数のスレッドを含み、複数のスレッドは同じ所属プロセスのリソースを共有することができる.したがって、Androidの応用は実はプロセスであり、中の各UI、Activityはこのプロセスに依存するスレッドであり、1つのActivityから別のActivityに入る本質は、前のスレッドを掛けて、後のスレッドを作成することである.脱退も同じだ.カスタムスレッドもこの原則に従います.スレッドの終了を制御しない限り、スレッドが本当に終了するのは、スレッドの実行が完了したか、または所属するプロセスが破棄された場合に限られます.
以上,カスタムスレッドがまだ実行されていない場合に,関連動作を終了する必要がある場合には,関連スレッドを終了すると考えられる.たとえば、検索中に検索を続行せずに検索機能を終了するには、カスタム検索スレッドを終了する必要があります.そうしないと重大なエラーを引き起こす可能性があります.たとえば、検索機能に繰り返しアクセスして検索し、検索が終了しないときに終了してからアクセスします.この場合、以前のカスタムスレッドが終了していないため、その後、複数の新しい検索スレッドが作成され、臨界領域の衝突を招きやすく、デバイスがダウンタイムになります.
では、これらのカスタムスレッドをどのように制御しますか?以下、筆者は詳細に説明する.
一.スレッドの終了
実際には、ヘルプドキュメントを通じて、Androidのスレッドクラス自体がスレッドを終了するための共通の方法を提供していることがわかります.
void destroy()
This method is deprecated. Not implemented.
synchronized final void stop(Throwable throwable)
This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state.
final void stop()
This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state
しかし、説明を通じて、これらの方法Android自体は推奨されていません.この方法でスレッドを終了するのは安全ではありません.アプリケーションを終了させ、仮想マシンを予想できない状態にする可能性があります.では、開発の過程で、合理的なニーズの中で、私たちはどのようにして指定されたカスタムスレッドを安全に終了しますか?筆者は救いに来た.
1.カスタムスレッドクラスでブールプライベート変数を定義し、スレッドの実行状態を記録するために偽に初期化できます.
2.run関数から、スレッドが実行状態に入ったことを示す変数を真に設定します.
3.run関数の終了位置で、この変数を偽に設定し、スレッドが終了状態に入ったことを示す.
4.runのスレッド実行部分では、いくつかの粘り強い点を探して、この変数を判断することができます.もし本当なら、実行を続けます.そうしないと、run関数を終了します.
5.上記の状態変数を偽に設定する役割を果たすカスタムスレッドクラスに共通の関数を追加します.
これにより、カスタムスレッドの実行がまだ終了していない場合、5のメソッドを呼び出してスレッドを安全に終了することができます.
思想の本質は、スレッドを安全に強制的に終了させることができない以上、安全に早期に終了させることです.効果は同じです.
プログラムの例:
class SearchThread extends Thread {
private Object mPauseLock;
private boolean mPauseFlag;
public SearchThread() {
mPauseLock = new Object();
mPauseFlag = false;
}
public void onPause_thread() {
synchronized (mPauseLock) {
mPauseFlag = true;
}
}
public void onResume_thread() {
synchronized (mPauseLock) {
mPauseFlag = false;
mPauseLock.notifyAll();
}
}
private void pauseThread() {
synchronized (mPauseLock) {
if (mPauseFlag) {
try {
mPauseLock.wait();
} catch (Exception e) {
Log.v("thread", "fails");
}
}
}
}
@Override
public void run() {
//--- , -----
while (!mPauseFlag) {
try {
pauseThread();
if (err_video)
mHandler.obtainMessage(ERROR_HANDLE)
.sendToTarget();
Thread.sleep(5000);
Log.e("robin debug", "thread.go");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Android , , 。 , 。java Thread suspend resume , , , , , , , ( !)
( ), , , 。 , :
private class MyThread extends Thread {
private final Object lock = new Object();
private boolean pause = false;
/**
*
*/
void pauseThread() {
pause = true;
}
/**
*
*/
void resumeThread() {
pause = false;
synchronized (lock) {
lock.notifyAll();
}
}
/**
* : run , ,
*/
void onPause() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
super.run();
try {
int index = 0;
while (true) {
//
while (pause) {
onPause();
}
try {
System.out.println(index);
Thread.sleep(50);
++index;
} catch (InterruptedException e) {
// , break
break;
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
, , , myThread.wait() , 。 onPause() run , 。
? , :
MyThread my = new MyThread();
Thread thread = new Thread(my);
thread.start();
, :
pauseThread();
:
resumeThread(); thead.interrupt(); , InterruptedException ,
while catch break; ,