web-dev-qa-db-ja.com

CountDownTimerでLooper.prepare()を呼び出さなかったスレッド内にハンドラーを作成できません

サービスがあります。そして、onServiceUpdate()と呼ばれるメソッドがあります。このメソッドは、Google Maps APIのonLocationChanged()と同様です。

したがって、onServiceUpdate()メソッド内でCountDownTimerを開始したいのですが、次のようなエラーが表示されます。

Can't create handler inside thread that has not called Looper.prepare()
    Java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at Android.os.Handler.<init>(Handler.Java:200)
            at Android.os.Handler.<init>(Handler.Java:114)
            at Android.os.CountDownTimer$1.<init>(CountDownTimer.Java:114)
            at Android.os.CountDownTimer.<init>(CountDownTimer.Java:114)
            at skripsi.ubm.studenttracking.Service2$6.<init>(Service2.Java:317)
            at skripsi.ubm.studenttracking.Service2.onServiceUpdate(Service2.Java:317)

これは私のコードです:

    @Override
    public void onServiceUpdate(ServiceState state)
    {
final float[] distance = new float[2];
        Location.distanceBetween(state.getGeoPoint().getLatitude(), state.getGeoPoint().getLongitude(), 6.130607787619352,106.81839518499267, distance);
        if (distance[0] > 25.0)
        {

                        CountDownTimer cdt5  = new CountDownTimer(total_onServiceUpdate,1000) {
                            @Override
                            public void onTick(long millisUntilFinished) {
                                total_onServiceUpdate = millisUntilFinished/1000;
                            }

                            @Override
                            public void onFinish() {
                                sendSMS();
                                stopSelf();
                            }
                        }.start();

        }
15

onServiceUpdate()は、実行されて通知する非同期タスクであるため、バックグラウンドスレッドです。あなたがする必要があるのはtimer.start();を呼び出すことだけです。メインスレッドから、サービスは実際にはメインスレッドで実行されますが、そうではないのはintentServiceであり、ソリューションは次の方法に沿っています。

new Handler(Looper.getMainLooper()).post(new Runnable() {           
        @Override
        public void run() {
            CountDownTimer cdt5  = new CountDownTimer(total_onServiceUpdate,1000) {
                        @Override
                        public void onTick(long millisUntilFinished) {
                            total_onServiceUpdate = millisUntilFinished/1000;
                        }

                        @Override
                        public void onFinish() {
                            sendSMS();
                            stopSelf();
                        }
                    }.start();
        }
    });

今、あなたはサーを続けることができます。 メインルーパー の画面で常に浮気者のコードを呼び出します

それが役に立てば幸い

24
Elltz

Android:

ハンドラーを呼び出す前にこれを試してください

if(Looper.MyLooper()== null){Looper.Prepare(); }

1
Amit gupta

ハンドラーはGUIスレッドで作成する必要があるため、ハンドラーを介してサービスからアクティビティGUIを更新することはできません。

代わりに、サービスから ブロードキャストを送信 し、このブロードキャストを取得するアクティビティにローカル broadcast-receiver を実装する必要があります

0
k3b

問題は、sendSMS()で、UIThreadを必要とする何か(ビューの更新など)を実行しようとしていることだと思います。これを試して:

Handler mHandler = new Handler() {
 public void handleMessage(Message msg){
    sendSMS();
}};

OnFinishメソッドを次のように変更します

@Override
public void onFinish() {
    mHandler.sendEmptyMessage(0);
    stopSelf();
}
0
Ungureanu Liviu