1

here で説明されているように、Android サービスを使用しています。を呼び出しdoBindService()て、の のメソッドのonCreate()1 つを呼び出そうとしています。これは私が問題に遭遇するところです。この時点では、まだ呼び出されていないため、まだ nullです。mBoundserviceonResume()mBoundServicemConnection.onServiceConnected()

mBoundServiceinのメソッドを呼び出すことができる方法はありますonResume()か、それともその時点で null であることを回避する方法はありませんか?

4

1 に答える 1

1

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

... ...

お役に立てれば。

于 2012-04-17T03:15:30.480 に答える