2013-08-30 211 views
1

我有一種應用程序,它以兩種不同的方式與其他設備通信:發送聲音信號並通過Wifi發送消息。爲了處理Wifi通信,我創建了一個具有線程監聽廣播消息的服務。對於聲音信號,我也有線程監聽。所以總共有兩個線程,當我想要按一個按鈕時,我想要殺死它。Android:殺死線程

在主要活動我把這種方法,當我按下按鈕:

public void onStop() { 
     super.onStop(); 

     mHelloService.stop(); 
     //This is the Sounds Thread  
     mListenThread = null;      

     if(D) Log.e(TAG, "-- ON STOP --"); 
    } 

而在服務我有這個功能停止WiFi的主題

public synchronized void stop() { 
     System.out.println("Close service"); 
     if (mHelloThread != null) mHelloThread = null; 

    } 

我試試這個,但線程繼續工作。我在另一個問題閱讀,有人建議使用:

mHelloThread.interrupt(); 

但我嘗試過了,我得到了這些錯誤:

08-30 20:18:08.592:d/AndroidRuntime(7312):關閉VM 08-30 20:18:08.592:W/dalvikvm(7312):threadid = 1:線程退出 未捕獲的異常(group = 0x419bc930)08-30 20:18:08.592: E/AndroidRuntime(7312 ):致命例外:main 08-30 20:18:08.592: E/AndroidRuntime(7312):java.lang.NullPointerException 08-30 20:18:08.592:E/AndroidRuntime 7312):at android.nacho.SoundLocalizer.HelloMessage.stop(HelloMessage.java:82) 08-30 20:18:08.592:E/AndroidRuntime(7312):at android.nacho.SoundLocalizer.SoundLocalizer.onStop( SoundLocalizer.java:349) 08-30 20:18:08.592:E/AndroidRuntime(7312):at android.nacho.SoundLocalizer.SoundLocalizer $ 3.onClick(SoundLocalizer.java:405) 08-30 20:18: android.view.View.performClick(View.java:4202)08-30 20:18:08.592: E/AndroidRuntime(7312):at android.view.View $(E)/ AndroidRuntime(7312):at android.view.View $ PerformClick.run(View.java:17340)08-30 20:18:08.592:E/AndroidRuntime(7312):at android.os.Handler.handleCallback(Handler.java:725)08-30 20:18:08.592:E/AndroidRuntime(7312):at android.os.Handler.dispatchMessage(Handler.java:92)08-30 20:18:08.592:E/AndroidRuntime(7312):at android .os.Looper.loop(Looper.java:137)08-30 20:18:08.592: E/AndroidRuntime(7312):at android.app.ActivityThread.main(ActivityThread.java:5039)08-30 20:18:08.592:E/AndroidRuntime(7312):at java.lang.reflect.Method.invokeNative(Native Method)08-30 20:18:08.592:E/AndroidRuntime(7312):at java.lang .reflect.Method.invoke(Method.java:511)08-30 20:18:08.592: E/AndroidRuntime(7312):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java: 793) 08-30 20:18:08.592:E/AndroidRuntime(7312):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)08-30 20:18:08.592:E/AndroidRuntime (7312):at dalvik.system.NativeStart.main(Native Method)

你推薦我做什麼?非常感謝

+0

可能重複的[你如何殺死Java中的線程?](http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java) – Gray

+0

感謝您的反饋,我會閱讀它,看看我能否學到新的東西。但是我問到Android(我幾乎知道Java中的所有東西都可以在Android中使用),但是也許有人知道更好的方法來實現它,這是專門針對Android的。 –

+0

什麼是mHelloService?一個Android'服務'沒有'stop()'方法AFAIA ...編輯:derp nvm,你添加它,我意識到... – ataulm

回答

1

您在正確的軌道上將線程設置爲空,但您可能會誤解這項任務正在做什麼;它對Thread對象本身沒有任何作用。正如羅賓所說,改變保持線程運行的條件。

考慮以下幾點:

public Something implements Runnable { 
    private Thread helloThread; 
    public Something() { 
     helloThread = new Thread(this); 
     helloThread.start(); 
    } 

    @Override 
    public void run() { 
     while (true && helloThread == Thread.currentThread()) { 
      // do something; 
     } 
    }  
} 

當你實例Something,它會創建一個新的工作線程並調用run()方法。它將保持在while循環中,直到條件變爲假。如果您設置了helloThread = null,它將變爲false,並且將從run()方法返回,並且線程將自行停止。

+0

非常感謝。我雖然有一種特殊的方法可以在你需要的時候殺死一個線程。我不是100%確定的,因爲現在我用C++編寫了很長一段時間,但我認爲有一個,而且我也許在Android/Java中也有一個。 感謝您的時間! –

+0

曾經有'stop()',但正如Little Child所說,它已被棄用,因爲它不是殺死線程的安全方法。 – ataulm

2

永不使用stop(),期限。

interrupt()方法將設置中斷標誌。您需要實現自己的機制,以便定期檢查線程是否中斷並採取適當的措施。

if(isInterrupted()){ 
    // do something 
} 

如何檢查線程是否中斷?通過使用isInterrupted()方法。

+0

好的感謝您的反饋,但現在我有兩個問題: 1--爲什麼不應該使用stop() 2-我應該寫什麼insise if()isInterrupted(){...}我應該在那裏寫mHelloThread = null;還是有其他一些方法來停止線程? –

+2

有'join()'可以用來停止線程。至於爲什麼你不應該使用'stop()':http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html –

+0

@LittleChild OP不使用'Thread#stop( )' – ataulm

2

爲什麼不只是改變線程運行的條件/變量。