我正在创建一个在一段时间内运行媒体播放器的服务。此服务获取我在另一个类中定义的常量值,并根据确定播放的持续时间。
我看了整个网络,但找不到解决方案或类似问题,花了好几个小时试图无济于事
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)
答案 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。
祝你好运,编码愉快。