在调用方法之前绑定服务

时间:2012-01-25 16:59:14

标签: android android-service android-activity

我在将服务绑定到Android中的活动时遇到问题。问题出现在活动中:

public class ServiceTestActivity extends Activity {

private static final String TAG = "ServiceTestAct";
boolean isBound = false;
TestService mService;    

public void onStopButtonClick(View v) {
    if (isBound) {
        mService.stopPlaying();
    }
}
public void onPlayButtonClick(View v) throws IllegalArgumentException, IllegalStateException, IOException, InterruptedException {
    if (isBound) {
        Log.d(TAG, "onButtonClick");
        mService.playPause();
    } else {
        Log.d(TAG, "unbound else");
        Intent intent = new Intent(this, TestService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
}


private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName name) {
        isBound = false;

    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        isBound = true;         
    }
    };
}

isBound告诉该服务(称为TestService)是否已绑定到该活动。 mService是对服务的引用。

现在如果我第一次调用“onPlayButton(..)”,服务没有绑定,调用bindService(..)并且isBound从false切换到true。然后,如果我再次调用“onPlayButton(..)”,它会在服务对象上调用“playPause()”。到这里一切正常。

但我希望在服务绑定后立即调用“playPause()”,所以我将代码更改为:

public void onPlayButtonClick(View v) throws IllegalArgumentException, IllegalStateException, IOException, InterruptedException {
    if (isBound) {
        Log.d(TAG, "onButtonClick");
        mService.playPause();
    } else {
        Log.d(TAG, "unbound else");
        Intent intent = new Intent(this, TestService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        mService.playPause();
    }
}

从这一点开始,我得到一个NullPointerException,因为mService没有绑定服务的引用,它仍然是null。我通过在代码中的不同位置记录mService的值来检查它。

我在这里做错了什么提示?我对android中的编程(特别是绑定)服务很新,但我仍然没有看到我的版本之间的主要区别在哪里。

2 个答案:

答案 0 :(得分:2)

服务的绑定是异步发生的,即如果bindService()返回但是当onServiceConnected()完成时,服务可能不会被绑定。因为mService仍然为null并且抛出异常。 一种解决方案是默认情况下禁用该按钮(在XML或onCreate()中)并启用onServiceConnected()中的按钮。

答案 1 :(得分:2)

一种解决方案是在onServiceConnected()中调用playPause()。另一种解决方案是使用自定义意图调用startService(),该意图将告诉服务进行播放。我想你可能想考虑重新设计。我会尝试设计服务,以便您可以在活动开始时启动并绑定到服务,并在活动停止时停止服务。如果您需要一个在活动生命周期内保持活动状态的服务,请扩展Application类,然后在onCreate()方法中启动该服务。