【问题标题】:Binding a service before calling a method on it在调用服务之前绑定服务
【发布时间】:2012-01-25 16:59:13
【问题描述】:

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

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 中编程(尤其是绑定)服务非常陌生,但我仍然看不出我的 to 版本之间的主要区别在哪里。

【问题讨论】:

    标签: android android-service android-activity


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 看起来不错。我现在遇到的问题是我希望有相同的按钮来启动服务和播放音乐。我看到我必须等到 onServiceConnected 完成,我可以通过等待 (while(!isBound){}) 来做到这一点吗?我已经尝试过了,通过日志记录我注意到,只有在 onPlayButton 完成时才会到达 onServiceConnected() 的底部..
      • 我建议不要这样做。你为什么不直接从 onServiceConnected 开始播放音乐(可能之前做一些检查,比如检查音乐没有播放什么的)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多