2012-02-06 13 views
3

これを解決する方法はわかりませんが、1つのアクティビティでstartServiceを呼び出し、すぐに次のアクティビティを開始するように呼び出します。前のアクティビティでstartServiceが呼び出されたときにbindServiceが失敗する

これが機能し、サービスが開始され、期待どおりにデータの処理が開始されます。

私は次のアクティビティに行き、onResumeに私はAsyncTaskを呼び出してサービスをバインドします。

したがって、基本的な流れは、AsyncTaskを呼び出すことです。bindServiceはfalseを返すので、mConnectionは呼び出されません。

なぜ、bindServiceがfalseを返すのが問題なのですか?

私がAsyncTaskにバインディングを置くのは、サービスが最初に起動する必要があるかどうかを確認するためにバインドする前にスレッドを10秒間スリープさせたためです。

また、このアクティビティの中で、onCreateメソッドでサービスを開始したので、10秒待ってからbindServiceもfalseを返します。

private class BindServiceTask extends AsyncTask<Void, Void, Boolean> { 
    protected Boolean doInBackground(Void... params) { 
     return bindService(
       new Intent(IMyCallback.class.getName()), 
       mConnection, Context.BIND_AUTO_CREATE); 
    } 
    protected void onPostExecute(Boolean b) { 
     if (b) { 
      Log.i(TAG, "onResume - binding succeeded"); 
      Toast.makeText(mContext, "Bound to service succeeded", 
        Toast.LENGTH_LONG).show(); 
     } else { 
      Log.i(TAG, "onResume - binding failed"); 
      Toast.makeText(mContext, "Bound to service failed", 
        Toast.LENGTH_LONG).show(); 
     } 
    } 
} 
private IMyCallback mCallback = new IMyCallback.Stub() { 
    @Override 
    public void dataChanged(double[] info) throws RemoteException { 
     mHandler.sendMessage(mHandler.obtainMessage(LOCATION_MSG, info)); 
    } 
}; 
IMyService mIRemoteService; 
private ServiceConnection mConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     Log.i(TAG, "onServiceConnected"); 
     mIRemoteService = IMyService.Stub.asInterface(service); 
     try { 
      Log.i(TAG, "registering callback"); 
      mIRemoteService.registerCallback(mCallback); 
     } catch (RemoteException e) { 
      Log.e(TAG, e.toString()); 
     } 
    } 

    public void onServiceDisconnected(ComponentName className) { 
     Log.e(TAG, "Service has unexpectedly disconnected"); 
     mIRemoteService = null; 
    } 
}; 
+0

は、あなたがコールバックを作成したAPIとの接続を欠落していませんか?エラー/スタックトレースを投稿できますか? – Jonathan

+0

@ジョナサン - エラーはありません。私がbindServiceを呼び出すと、値はfalseです。 mConnectionはコールバック関数です。bindServiceが失敗したので、それを含める必要はありませんでした。 –

+0

bindServiceが失敗しなかった可能性が高いのは、サービスが常に完全にインスタンス化されてその呼び出しでバインドされるわけではないか、まれにしかバインドされないためです。私は、私が取り組んでいるプロジェクトからいくつかのスニペットを投稿しました。最初にAIDL Service APIを実装したとき、私は自分の髪を引き出しました。これを理解したので、他のすべてのオプションにもかかわらず、私はすべてのサービスの実装に頑強に使用します。 – Jonathan

答えて

1

bindService()に電話すると、サービスにアクセスするためのサービス接続またはAPIが返されるとは限りません。それは非同期に起こります。あなたはこのようなコールバックが必要です。

class PictureUploadQueueServiceConnection implements ServiceConnection { 
    public void onServiceConnected(ComponentName name, IBinder service){ 
     Log.d(TAG, "PictureUpload Service Connected!");    
     pictureUploadQueueApi = PictureUploadQueueServiceApi.Stub.asInterface(service);  
    } 

    public void onServiceDisconnected(ComponentName name){ 
     Log.d(TAG, "PictureUpload Service Connection Closed!"); 
     pictureUploadQueueApi = null; 
    } 
}; 

をバインドを行うにはあなたの呼び出しは次のようになります。

getApplicationContext().bindService(new Intent("org.me.xxxx.PictureUploadQueueServiceApi"), 
         pictureUploadQueueServiceConnection, 
         Context.BIND_AUTO_CREATE 
       ); 

を使用すると、APIのスタブを実装し、それのインスタンスを返すされているあなたのサービスで確認してくださいあなたのonBind()方法:

private PictureUploadQueueServiceApi.Stub api = new PictureUploadQueueServiceApi.Stub() { 
    @Override 
    public void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback) throws RemoteException { 
     appendPictureUpload(remoteURI, localURI, target, description, callback); 
    } 
    @Override 
    public boolean isEmpty() { 
     return queue.size() == 0 ? true : false; 
    }; 
}; 

@Override 
public IBinder onBind(Intent intent) { 
    Log.d(TAG, "Bound Intent: " + intent); 
    return api; 
} 

最後に、例を完了するためには、私の例のためのAIDLファイルは次のようになります。

interface PictureUploadQueueServiceApi { 

     void queuePictureUpload(String remoteURI, String localURI, String target, String description, String callback); 

     boolean isEmpty(); 

    } 
+0

私が家に帰ると、あなたがしたことをより慎重に見ていきます。私はこれらのすべてのステップを行っているようですが、私が逃したものがあるかもしれません。 –

+0

@ JamesBlack特に、バインディングが非同期であることをコードで考慮していません。サービス接続の「ライフサイクル」を処理するために、単純な状態マシンをセットアップする必要があります。 – Jonathan

+0

もう少し詳細なコードを追加しました。 –

2

問題がマニフェストに問題があるようです。

私はサービスがにバインドすることができ、システム伝えるために意図-フィルタがありませんでした:あなたはAIDLを使用している場合

<service 
     android:name=".MyService" 
     android:process=":remote" > 
     <intent-filter> 

      <!-- 
       These are the interfaces supported by the service, which 
       you can bind to. 
      --> 
      <action android:name="my.com.services.IMyCallback" /> 
      <action android:name="my.com.services.IMySecondaryService" /> 
      <!-- 
       This is an action code you can use to select the service 
       without explicitly supplying the implementation class. 
      --> 
      <action android:name="my.com.activity.MY_SERVICE" /> 
     </intent-filter> 
    </service> 
+0

ようやく!数時間のデバッグ後に-_- – mr5

関連する問題