服务继续崩溃OnDestroy()

时间:2018-02-20 21:48:39

标签: android android-activity service ondestroy

我正在创建一个在一段时间内运行媒体播放器的服务。此服务获取我在另一个类中定义的常量值,并根据确定播放的持续时间。

我看了整个网络,但找不到解决方案或类似问题,花了好几个小时试图无济于事

  package com.quantyam.sleepbaby.sleepbaby;

 import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;

 public class ContinousService extends IntentService {

private static final String TAG = "HelloService";
MediaPlayer player;
private boolean isRunning = false;
int time = 0;
Thread runner;
boolean keepplaying=true;

Handler mHandler = new Handler();

boolean keepgoiong = true;

public ContinousService() {
    super("ContinousPlayer");
}


private void sendMessageToActivity(int msg) {
    Intent intent = new Intent("intentKey");

    intent.putExtra("current_timing", msg);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}


@Override
public void onCreate() {
    Log.i(TAG, "Service onCreate");

    isRunning = true;
}

public static String
        ACTION_CONTINOUS_PLAY = "";


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    System.out.println("******************************************* selected DUration  = " + Constant.PlayDuration);
    Log.i(TAG, "Service onStartCommand");

    //Creating new thread for my service
    //Always write your long running tasks in a separate thread, to avoid ANR
    new Thread(new Runnable() {

        @Override
        public void run() {
            runner = Thread.currentThread();

            //Your logic that service will perform will be placed here
            //In this example we are just looping and waits for 1000 milliseconds in each loop.
            while (keepgoiong) {
                try {
                    Thread.sleep(1000);

                    startplaying();
                    time++;
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (isRunning) {
                    Log.i(TAG, "Service running and time is = " + time);
                }
            }

            //Stop service once it finishes its task
            stopSelf();
        }
    }).start();

    return Service.START_STICKY;
}


public void startplaying() {

    try {

        if(keepplaying) {
            if (player == null) {
                AssetFileDescriptor afd = getAssets().openFd("music/" + Constant.SelectedMusic);
                player = new MediaPlayer();
                player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                player.prepare();
                player.start();
                System.out.println("============================= player Started!");
            }


            final int duration = Integer.parseInt(Constant.PlayDuration) * 15;
            int timeleft = duration - time;
            sendMessageToActivity(timeleft);
            System.out.println("============================= time left = " + timeleft);
            if (player.isPlaying() && timeleft > 0) {


            } else if (!player.isPlaying() && timeleft > 0) {
                System.out.println("================================== Run Again!");

                //    player.prepare();
                player.start();
            } else if (player.isPlaying() && timeleft <= 0) {

                System.out.println("============================= Time is up!");
                player.stop();
                keepplaying=false;
                keepgoiong = false;

            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}


@Override
public IBinder onBind(Intent arg0) {
    Log.i(TAG, "Service onBind");

    return null;
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {

}

Handler handler = new Handler();

@Override
public void onDestroy() {
    keepgoiong = false;
    isRunning=false;
    keepplaying=false;
    player.stop();
 super.onDestroy();
 //   stopSelf();

    Log.i(TAG, "Service onDestroy");
}

}

当时间到了,我调用stopSelf(),但每次我收到以下错误信息:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.quantyam.sleepbaby.sleepbaby, PID: 6550
              java.lang.RuntimeException: Unable to stop service com.quantyam.sleepbaby.sleepbaby.ContinousService@cbde8b0: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.Looper.quit()' on a null object reference
                  at android.app.ActivityThread.handleStopService(ActivityThread.java:3732)
                  at android.app.ActivityThread.-wrap30(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1745)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6692)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.Looper.quit()' on a null object reference
                  at android.app.IntentService.onDestroy(IntentService.java:138)
                  at com.quantyam.sleepbaby.sleepbaby.ContinousService.onDestroy(ContinousService.java:153)
                  at android.app.ActivityThread.handleStopService(ActivityThread.java:3715)
                  at android.app.ActivityThread.-wrap30(ActivityThread.java) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1745) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:154) 
                  at android.app.ActivityThread.main(ActivityThread.java:6692) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 

我的代码https://codeshare.io/5MJEVQ

1 个答案:

答案 0 :(得分:0)

IntentService在自己的线程上运行。 所以你正在做的是启动一个线程,启动另一个启动媒体播放器的线程,并在第一个线程上调用stopSelf()之前等待。 意图服务只有在有效的情况下才可用。 如果意图服务启动另一个线程......它的工作已完成,它将消失。

当你调用stopSelf()方法时,你的Intent服务已经消失,因为它启动了线程并完成了它的工作......

我首先建议当意图服务启动时启动媒体播放器。然后使用PostDelayed runnable在媒体播放器完成时停止它。像下面的东西。注意:这仍然无法正常工作,因为IntentService将在启动postDelayed Runnable后完成其工作。解决方案是使用服务而不是IntentService。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    System.out.println("******************************************* selected DUration  = " + Constant.PlayDuration);
    Log.i(TAG, "Service onStartCommand");
    startMediaPlayer();
    new Handler().postDelayed(new Runnable() {
    public void run () {
        stopSelf();
        }
    }, playDuration);
    return Service.START_STICKY;
}

我建议您使用服务而不是IntentService。

Here is an example of a media player in a service.它使用状态和意图从UI接收动作,并使用广播接收器在需要时更新ui。

祝你好运,编码愉快。