bindService() が実際には非同期呼び出しであることは、公式の開発者ガイドで明確に述べられていません。
クライアントは bindService() を呼び出すことでサービスにバインドできます。その場合、サービスとの接続を監視する ServiceConnection の実装を提供する必要があります。bindService() メソッドは値なしですぐに戻りますが、Android システムがクライアントとサービス間の接続を作成するときに、ServiceConnection で onServiceConnected() を呼び出して、クライアントがサービスとの通信に使用できる IBinder を配信します。
bindService() を呼び出した後、システムが使用可能なサービス インスタンス (NULL ではない) を準備/インスタンス化し、それを ServiceConnection.onServiceConnected() コールバックで返す前に、ラグがあります (瞬間的ではありますが、それでもラグがあります)。onCreate() と onResume() の間の時間間隔が短すぎて、ラグを克服できません (アクティビティが初めて開かれた場合)。
onResume() で mBoundservice.foo() を呼び出す場合、一般的な回避策は、アクティビティが最初に作成されたときに onServiceConnected() コールバックで呼び出し、ブール状態を設定し、onResume() メソッドで、状態が設定され、コード実行を条件付きで制御します。つまり、さまざまなアクティビティ ライフサイクルに基づいて mBoundservice.foo() を呼び出します。
LocalService mBoundservice = null;
boolean mBound = false;
... ...
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mBoundservice = binder.getService();
mBound = true;
// when activity is first created:
mBoundservice.foo();
}
... ...
};
... ...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// call bindService here:
doBindService();
}
@Override
protected void onResume() {
super.onResume();
// when activity is resumed:
// mBound will not be ready if Activity is first created, in this case use onServiceConnected() callback perform service call.
if (mBound) // <- or simply check if (mBoundservice != null)
mBoundservice.foo();
}
... ...
お役に立てれば。