android服务 - 错误:服务未注册

时间:2012-09-05 08:48:12

标签: android service

我想了解有界服务。在我尝试关注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$1@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)

由于编码似乎紧跟文档示例,我不知道哪里出错了。我使用minSdk级别8运行此应用程序。错误发生在MainActivity.onStop的

 mService.unbindService(mConnection);

任何解决此问题的建议都会很棒。

由于

马丁

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;
    }
};

}

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

}

}

5 个答案:

答案 0 :(得分:59)

有类似的问题,但接受的答案对我来说不是解决方案。幸运的是,其中一条评论给了我答案:

  取消绑定服务时,不应该引发

onServiceDisconnected ,所以不要依赖它。如果您的服务和ServiceConnection之间的连接被删除,它应该通知您。

感谢@Waqas我发现错误:我只在boolean bindedonServiceConnected()内更新了onServiceDisconnected()标记。现在我每次拨打unbindService()时都添加了“binded = false”,问题就消失了。就是这样,不要依赖 onServiceDisconnected

答案 1 :(得分:19)

啊,其中一天

mService.unbindService(mConnection);

显然是无稽之谈,在错误的上下文中调用unbind。它应该是

unbindService(mConnection); 

发布的编码中的其他错误是缺少

@Override
public boolean onUnbind(Intent intent) {
    // All clients have unbound with unbindService()

    releaseMediaPlayer();

    return false;
}

答案 2 :(得分:7)

作为旁注,由于其他答案都没有帮助,我发现我的错误是使用不同的Context进行绑定和取消绑定。我的绑定来自Application上下文,但我的unbind来自Activity上下文。

要解决此错误,我确保对bindService()unbindService()使用相同的上下文。

答案 3 :(得分:2)

您可能需要确保mService不为null。以下行给了我“服务未注册”错误:

if (mContext != null) mContext.unbindService(mServiceConn);

这非常令人困惑,因为mContext和mServiceConn都不是null。

这解决了它:

if (mContext != null && mService != null) mContext.unbindService(mServiceConn);

答案 4 :(得分:0)

当我杀死该应用时,我的MediaPlayer会停止,但只需5分钟或更短的时间,它就会自动重新启动。

要解决此问题,除了@ dorjeduck的答案之外,我还必须在致电mediaPlayer.stop()之前致电mediaPlayer.release()