android 服务 - 错误:服务未注册
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12277673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android services - error: service not registered
提问by dorjeduck
I am trying to understand bounded services. Below my sample program in which I try to follow http://developer.android.com/guide/components/bound-services.html. The service functions as far as I can play, pause, and stop the audio yet when I switch to another app I get the following Service not registered error.
我试图了解有界服务。在我尝试遵循http://developer.android.com/guide/components/bound-services.html 的示例程序下方。该服务可以播放、暂停和停止音频,但当我切换到另一个应用程序时,我收到以下服务未注册错误。
java.lang.RuntimeException: Unable to stop activity {com.example.dd_services_audio_01/com.example.dd_services_audio_01.MainActivity}: java.lang.IllegalArgumentException: Service not registered: com.example.dd_services_audio_01.MainActivity@2afca5d8
09-05 14:04:32.625: E/AndroidRuntime(5810): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2451)
09-05 14:04:32.625: E/AndroidRuntime(5810): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:2496)
As the coding seems to follow the documentation example closely I have no clue where things go wrong. I run this app with minSdk level 8. The error happens in MainActivity.onStop at the line
由于编码似乎紧密遵循文档示例,我不知道哪里出了问题。我使用 minSdk 级别 8 运行此应用程序。该错误发生在 MainActivity.onStop 行中
mService.unbindService(mConnection);
Any suggestions to solve this would be great.
任何解决这个问题的建议都会很棒。
Thanks
谢谢
martin
马丁
package com.example.dd_services_audio_01;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.example.dd_services_audio_01.AudioPlayerService.AudioPlayerBinder;
public class MainActivity extends Activity {
private final String TAG = "MainActivity";
AudioPlayerService mService;
boolean mBound = false;
Button mPlay, mPause, mStop;
String audioFile = Environment.getExternalStorageDirectory()
+ "/justdzongsar/DJKR_AboutToGetIt.mp3";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG,"onCreate");
setContentView(R.layout.activity_main);
mPlay = (Button) findViewById(R.id.buttonPlay);
mPause = (Button) findViewById(R.id.buttonPause);
mStop = (Button) findViewById(R.id.buttonStop);
mPlay.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mService.play(audioFile);
}
});
mPause.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mService.pause();
}
});
mStop.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mService.stop();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, AudioPlayerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
if (mBound) {
mService.unbindService(mConnection);
mBound=false;
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// We've bound to LocalService, cast the IBinder and get
// LocalService instance
AudioPlayerBinder binder = (AudioPlayerBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mService = null;
mBound = false;
}
};
}
and
和
package com.example.dd_services_audio_01;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class AudioPlayerService extends Service implements OnPreparedListener,
OnCompletionListener {
private final String TAG = "AudioPlayerService";
private final IBinder mBinder = new AudioPlayerBinder();
private MediaPlayer mMediaPlayer;
private String currentDataSource;
public class AudioPlayerBinder extends Binder {
public AudioPlayerService getService() {
Log.v(TAG, "AudioPlayerBinder: getService() called");
return AudioPlayerService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return false;
}
@Override
public void onStart(Intent intent, int startId) {
Log.i(TAG,
"AudioPlayerService: onStart() called, instance="
+ this.hashCode());
}
@Override
public void onDestroy() {
Log.i(TAG, "AudioPlayerService: onDestroy() called");
releaseMediaPlayer();
}
// -----
public void play(String audioFile) {
Log.d(TAG, "audio play called with file " + audioFile);
if (mMediaPlayer != null && audioFile.compareTo(currentDataSource) == 0) {
if (mMediaPlayer.isPlaying() == true) {
return;
}
mMediaPlayer.start();
return;
}
releaseMediaPlayer();
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(audioFile);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnCompletionListener(this);
currentDataSource = audioFile;
mMediaPlayer.prepareAsync();
} catch (IOException ioe) {
Log.e(TAG, "error trying to play " + audioFile, ioe);
}
}
public void pause() {
Log.d(TAG, "audio pause");
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
}
public void seek(int timeInMillis) {
if (mMediaPlayer != null) {
mMediaPlayer.seekTo(timeInMillis);
}
}
public int elapsed() {
if (mMediaPlayer == null) {
return 0;
}
return mMediaPlayer.getCurrentPosition();
}
public void stop() {
Log.d(TAG, "audio stop");
releaseMediaPlayer();
}
// --
private void releaseMediaPlayer() {
if (mMediaPlayer == null) {
return;
}
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
@Override
public void onCompletion(MediaPlayer arg0) {
// TODO Auto-generated method stub
releaseMediaPlayer();
}
@Override
public void onPrepared(MediaPlayer mp) {
if (mp != null) {
mp.start();
}
// TODO Auto-generated method stub
}
}
回答by Salvatorelab
Had a similar problem, but the accepted answer was not the solution for me. Luckily one of the comments gave me the answer:
有一个类似的问题,但接受的答案不是我的解决方案。幸运的是,其中一条评论给了我答案:
onServiceDisconnectedis not supposed to be raised when you unbind your service, so don't rely on it. It is supposed to inform you in case the connection between your Service and ServiceConnection is dropped.
当您解除服务绑定时,不应引发onServiceDisconnected,因此不要依赖它。如果您的 Service 和 ServiceConnection 之间的连接断开,它应该会通知您。
Thanks to @Waqas I found the error: I was updating the boolean binded
flag only inside onServiceConnected()
and onServiceDisconnected()
. Now I've added "binded=false" every time I call unbindService()
and the problem has gone. That's it, don't rely on onServiceDisconnected
感谢@Waqas,我发现了错误:我boolean binded
只在内部onServiceConnected()
和onServiceDisconnected()
. 现在我每次打电话时都添加了“bind=false” unbindService()
,问题就解决了。就是这样,不要依赖于ServiceDisconnected
回答by dorjeduck
Ah, one of these days
啊,其中一天
mService.unbindService(mConnection);
is obviously nonsense, calling unbind in the wrong context. It should be
显然是无稽之谈,在错误的上下文中调用 unbind 。它应该是
unbindService(mConnection);
Additional mistake in the posted coding is the missing of
发布的编码中的其他错误是缺少
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
releaseMediaPlayer();
return false;
}
回答by Anonsage
As a sidenote, since none of the other answers helped, I found that my error was using a different Context
for bind and unbind. My bind was from the Application context, but my unbind was from the Activity context.
作为旁注,由于其他答案都没有帮助,我发现我的错误是使用不同Context
的绑定和解除绑定。我的绑定来自 Application 上下文,但我的 unbind 来自 Activity 上下文。
To fix the error, I made sure to use the same context for bindService()
and unbindService()
.
为了修正这个错误,我确信使用相同的上下文bindService()
和unbindService()
。
回答by Jason Hartley
You may need to ensure that mService is not null. The following line gave me the "Service not Registered" error:
您可能需要确保 mService 不为空。以下行给了我“服务未注册”错误:
if (mContext != null) mContext.unbindService(mServiceConn);
if (mContext != null) mContext.unbindService(mServiceConn);
This was very confusing because both mContext and mServiceConn were not null.
这非常令人困惑,因为 mContext 和 mServiceConn 都不为空。
This fixed it:
这修复了它:
if (mContext != null && mService != null) mContext.unbindService(mServiceConn);
if (mContext != null && mService != null) mContext.unbindService(mServiceConn);
回答by craned
My MediaPlayer
would stop when I killed the app, but 5 minutes layer or less it would start back up again all on its own.
MediaPlayer
当我杀死应用程序时,我会停止,但是 5 分钟或更短的时间层会自动重新启动。
To fix this, in addition to @dorjeduck's answer, I had to also call mediaPlayer.stop()
before calling mediaPlayer.release()
.
为了解决这个问题,除了@dorjeduck 的回答之外,我还必须mediaPlayer.stop()
在调用mediaPlayer.release()
.