2016-05-26 6 views
-1

サービス内にハンドラがあり、ユーザがサービスを停止するまでこのスレッドをブロックします。 CPU使用量を少なくするために、私はThread.sleep()を使用して、10 minutesの間隔の後にブロック条件を繰り返し確認しようとしています。ここに私のhandlemessageの私の実装です:スレッドをハンドラに送信してThread.sleep()を解除するにはどうすればよいですか?

@Override 
public void handleMessage(Message msg) { 
    Log.e("Service", "looper started"); 
    GPSThread gp=new GPSThread(getApplicationContext()); 
    gp.start();   
    ModeController mc=new ModeController(getApplicationContext()); 
    mc.start(); 
    NetworkSniffer nh=new NetworkSniffer(getApplicationContext()); 
    nh.start(); 
    while(stopService) //stopService is a volatile boolean i use to block until user opts to stop the service 
    {     
     try { 
      Thread.sleep(10*60*1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
       e.printStackTrace(); 
     }    
    }  
    mc.stopThread(); 
    gp.stopThread(); 
    nh.stopNetworkThread(); 
    stopSelf(msg.arg1); 
} 

今私の問題は、私は(パブリック関数を通じて)falseにstopServiceの値を変更した場合、それは、whileループを終了するために10分件までかかる場合がありますということです。スレッドの場合は、Thread.interrupt()を使用してwhileループを終了します。

私の質問は、Handlerの場合と同様に、ハンドラ内でThread.sleep()のInterruptedExceptionをスローする方法です。

答えて

1

スレッドの場合は、Thread.interrupt()を使用してwhileループを終了します。

実は、コードは>>スレッド上で実行されている< <あるので、あなたが、あなたがそのスレッドが何であるかを仕事ができるならば、あなたはそれを中断できます。

これを行う方法は、スレッドコールService.stopServiceを中断しようとしたコードを置くことです。

参考文献:

眠っているスレッドは、サービスのハンドラスレッドの場合、このアプローチは動作します。明示的にスレッドを作成した場合は、作成したスレッドを追跡し、Thread.interruptを使用する必要があります。 (そして、あなたはカスタムstopServiceフラグではなくThread.interrupted状態を使用することができます。)

はしかし、良いアイデアはsleepループを避けるために、次のようになります。@Stephen Cへhttps://stackoverflow.com/a/845291/139985

+0

ありがとうございました。私はリンクしていただきありがとうございます。私はちょうど1つの事を得なかった。あなたは私がそれに割り込みを呼び出すことができるスレッドを解決することができたと述べた。どのように私はスレッドの卿を働かせることができますか? –

+0

それはおそらく難しいでしょう。 (古典的なJavaの世界では、おそらくThreadGroup階層を使用し、名前でスレッドを見つけることになるでしょう)。serviceStopを使用できない場合は、スレッド参照をどこかの変数に記録することをお勧めします... –

+0

ありがとうございました、ついにそれを働かせました。私は 'HandlerThread thread = new HandlerThread(" ServiceStartArguments "、Process.THREAD_PRIORITY_BACKGROUND);を使用するHandlerThreadオブジェクトからThreadインスタンスを取得しました。最後に、 'stopServiceMethod()'のこのスレッド変数に対して割り込みを呼び出しました。 –

1

おかげでようやくそれが動作するようになったし。将来的に他人を助けることを期待してコードを投稿してください。

package com.example.userpc.roadtracker; 


import android.app.Service; 
import android.content.Intent; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.os.IBinder; 
import android.os.Looper; 
import android.os.Message; 
import android.os.Process; 
import android.util.Log; 

/** 
* Created by USER PC on 5/21/2016. 
*/ 
public class MainServiceThread extends Service { 

    private Looper mServiceLooper; 
    private ServiceHandler mServiceHandler; 
    private volatile static boolean stopService=true; 
    private static HandlerThread mThread; 

    public static void stopServiceThread() 
    { 
     stopService=false; 
     mThread.interrupt(); 
    } 

    private final class ServiceHandler extends Handler { 
     public ServiceHandler(Looper looper) { 
      super(looper); 
     } 
     @Override 
     public void handleMessage(Message msg) { 
      Log.e("Service", "looper started"); 
      GPSThread gp=new GPSThread(getApplicationContext()); 
      gp.start();   
      ModeController mc=new ModeController(getApplicationContext()); 
      mc.start(); 
      NetworkSniffer nh=new NetworkSniffer(getApplicationContext()); 
      nh.start(); 
      while(stopService) 
      {     
       try { 
        Thread.sleep(10*60*1000); 

       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       }    
      }  
      mc.stopThread(); 
      gp.stopThread(); 
      nh.stopNetworkThread(); 
      stopSelf(msg.arg1); 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     Log.e("Service", "in onCreate"); 
     stopService=true; 
     HandlerThread thread = new HandlerThread("ServiceStartArguments", 
       Process.THREAD_PRIORITY_BACKGROUND); 
     mThread=thread; 
     thread.start(); 
     mServiceLooper = thread.getLooper(); 
     mServiceHandler = new ServiceHandler(mServiceLooper); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.e("Service","Started"); 
     Message msg = mServiceHandler.obtainMessage(); 
     msg.arg1 = startId; 
     mServiceHandler.sendMessage(msg); 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mThread=null; 
     Log.e("Service","Destroyed"); 
    } 


} 
関連する問題