ユーザーが [開始と中止] を押すボタンに応じて、スレッドを開始、一時停止、再起動する必要があるアプリケーションをプログラミングしています。スレッドを制御するために、次のように、アクティビティと連携するサービスを作成します。
活動のコード
public class SoundLocalizer extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, " ON CREATE ");
// Set up the window layout
setContentView(R.layout.main);
}
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
mHelloService = new HelloMessage(ThisContext, mHandler, LocalIP);
mHelloService.start();
setup();
}
public void onReStart(){
mHelloService.restart();
}
public void onWait(){
mHelloService.stop();
if(D) Log.e(TAG, "-- ON WAIT --");
}
private void setupChat() {
Log.d(TAG, "setupChat()");
mStartButton = (Button) findViewById(R.id.btnStart);
mStartButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//The aplicacion have already been lauched
if(Begin){
onReStart();
}
isRecording = true;
enableButtons(false);
}
});
mAbortButton = (Button) findViewById(R.id.btnAbort);
mAbortButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
enableButtons(true);
Loop=false;
isRecording=false;
WaitForMaster=false;
onWait();
Begin=true;
}
});
}
}
サービスコード
public class HelloMessage {
Context mContext ;
private final Handler mHandler;
private boolean Working=true;
public HelloMessage(Context context, Handler handler, String IP){
mContext=context;
mHandler = handler;
Local_IP_String=IP;
String[] IP_Parts = IP.split("\\.");
LocalIP=Integer.parseInt(IP_Parts[3]);
}
public void restart() {
Working=true;
/*
mHelloThread.notify();
*/
}
public synchronized void start() {
Working=true;
mHelloThread = new HelloThread();
mHelloThread.start();
}
public void stop() {
Working=false;
/*
try {
mHelloThread.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
}
public class HelloThread extends Thread {
DatagramSocket mSocket ;
InetAddress myBcastIP;
public HelloThread() {
try {
//Here I initialize some variables
} catch (IOException e) {
...
}
}
public void run(){
//Listen on socket to receive messages
try{
while(Working){
//Do things
}
}
} catch (IOException e) {
...
}
}
問題: Abort を押すと、アクティビティで mHelloService.stop() が正しく呼び出され、フラグWorkingがfalseになり、サービスのスレッドの「While ループ」が機能しなくなります。
この時点まで、すべてが完璧です。しかし、その後、 WorkingをtrueにするメソッドmHelloService.restart()を呼び出してループを再開したいのですが、スレッドは再び開始されません。私は何を間違っていますか?
------------ 他のバージョンも試してみましたが、さらに悪い結果になりました ---------------
mHelloService.stop() でmHelloThread.wait( ) を使用し、mHelloService.restart()でmHelloThread.notify () を使用する
LogCatでこれを取得しました:
09-02 02:08:54.640: D/AndroidRuntime(17463): VM をシャットダウンしています 09-02 02:08:54.640: W/dalvikvm(17463): threadid=1: キャッチされない例外で終了するスレッド (group=0x413eb300) 09 -02 02:08:54.648: E/AndroidRuntime(17463): 致命的な例外: メイン 09-02 02:08:54.648: E/AndroidRuntime(17463): java.lang.IllegalMonitorStateException: オブジェクトが wait() の前にスレッドによってロックされていません09-02 02:08:54.648: E/AndroidRuntime(17463): java.lang.Object.wait(ネイティブ メソッド) で 09-02 02:08:54.648: E/AndroidRuntime(17463): java.lang.Object で.wait(Object.java:364) 09-02 02:08:54.648: E/AndroidRuntime(17463): android.nacho.SoundLocalizer.HelloMessage.stop(HelloMessage.java:88) 09-02 02:08:54.648 : E/AndroidRuntime(17463): android.nacho.SoundLocalizer.SoundLocalizer.onWait(SoundLocalizer.java:367) 09-02 02:08:54.648: E/AndroidRuntime(17463):android.nacho.SoundLocalizer.SoundLocalizer$3.onClick(SoundLocalizer.java:441) 09-02 02:08:54.648: E/AndroidRuntime(17463): android.view.View.performClick(View.java:4084) 09 -02 02:08:54.648: E/AndroidRuntime(17463): android.view.View$PerformClick.run(View.java:16966) 09-02 02:08:54.648: E/AndroidRuntime(17463): Android で.os.Handler.handleCallback(Handler.java:615) 09-02 02:08:54.648: E/AndroidRuntime(17463): android.os.Handler.dispatchMessage(Handler.java:92) 09-02 02:08 :54.648: E/AndroidRuntime(17463): android.os.Looper.loop(Looper.java:137) 09-02 02:08:54.648: E/AndroidRuntime(17463): android.app.ActivityThread.main( ActivityThread.java:4745) 09-02 02:08:54.648: E/AndroidRuntime(17463): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 09-02 02:08:54.648:E/AndroidRuntime(17463): java.lang.reflect.Method.invoke(Method.java:511) 09-02 02:08:54.648: E/AndroidRuntime(17463): com.android.internal.os.ZygoteInit で$MethodAndArgsCaller.run(ZygoteInit.java:786) 09-02 02:08:54.648: E/AndroidRuntime(17463): com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-02 02 :08:54.648: E/AndroidRuntime(17463): dalvik.system.NativeStart.main(ネイティブメソッド)
お時間をいただきありがとうございました
注 1:
mHelloThread.start() を restart() に追加すると、LogCat で次のようになります。
09-02 03:05:07.664: D/AndroidRuntime(17657): VM をシャットダウンしています 09-02 03:05:07.664: W/dalvikvm(17657): threadid=1: キャッチされない例外で終了するスレッド (group=0x413eb300) 09 -02 03:05:07.672: E/AndroidRuntime(17657): 致命的な例外: メイン 09-02 03:05:07.672: E/AndroidRuntime(17657): java.lang.IllegalThreadStateException: スレッドは既に開始されています。09-02 03:05:07.672: E/AndroidRuntime(17657): java.lang.Thread.start(Thread.java:1045) 09-02 03:05:07.672: E/AndroidRuntime(17657): Android で。 nacho.SoundLocalizer.HelloMessage.restart(HelloMessage.java:67) 09-02 03:05:07.672: E/AndroidRuntime(17657): android.nacho.SoundLocalizer.SoundLocalizer.onReStart(SoundLocalizer.java:353) 09-02 03:05:07.672: E/AndroidRuntime(17657): android.nacho.SoundLocalizer.SoundLocalizer$2.onClick(SoundLocalizer.java:421) 09-02 03:05:07 で。