2011-07-27 24 views
1

EDIT:以下のコードは、問題の正しい解決策を示すために編集されています。インターフェイスを実装するサービスへのバインド

私はフォアグラウンドサービスを使用してネットワーク操作を実行するアプリを持っています。

現在、フォアグラウンドサービスは、Bluetooth接続を使用して操作を実行します。私は、Wi-Fiを代わりに使用する新しいバージョンのサービスを実装しようとしており、ユーザーが共有設定を使用してBluetoothを使用するかWiFiを使用するかを決定できるようにしています。

私はwifiサービスを実装しましたが、今はそれをバインドする必要があります。私は、サービスの両方のバージョンが必要とするすべてのメソッドを定義するインターフェイスMyServiceを作成しました。しかし、私の活動でサービスにバインドしようとすると、ClassCastExceptionというエラーが発生します。ここで

は私のサービス・インターフェースの関連する部分です:

MyBluetoothService.java:

MyService.java:

public interface MyService { 
// constants 

... 

// method declarations 
... 

public interface LocalBinder { 
     MyService getService(Handler handler); 
    } 
} 

そして、ここでは、サービスの両方のバージョンに存在している、関連するメソッドです

public class MyBluetoothService extends Service implements MyService { 

private final IBinder mBinder = new LocalBinder(); 

... 

public class LocalBinder extends Binder implements MyService.LocalBinder { 
    MyService getService(Handler handler) { 
     mHandler = handler; 

     // Return this instance of MyService so clients can call public methods 
     return MyBluetoothService.this; 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    Log.w(TAG, "MyBluetoothService bound"); 

    return mBinder; 
} 
} 

MyWifiService.java:MyBluetoothService.javaとまったく同じですが、必要に応じてクラス名が変更されています。

そして、ここで私は私の活動のサービスにバインド場所です:

MyService mChatService = null; 
... 

private ServiceConnection mConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName className, 
      IBinder service) { 
     // We've bound to MyService, cast the IBinder and get MyService instance 
     LocalBinder binder = (LocalBinder)service; <------- ClassCastException 
     mChatService = binder.getService(mHandler); 
     mBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName argo) { 
     mBound = false;   
    } 
}; 

ClassCastExceptionは、上記に示した行で発生します。

これですべてのことが解決されました。このようにサービスにバインドすることは可能ですか?代わりに、私はいつも私がサービスからメソッドを呼び出すたびに共通の設定をチェックすることができましたが、私はむしろそうしたくありませんでした。

答えて

0

私は、投げているコードがMyBluetoothService.LocalBinderクラスではなく、MyService.LocalBinderクラスであると仮定していますか?

MyBluetoothService.LocalBinderクラスをMyService.LocalBinderクラスから継承して定義することをお考えですか?

public class MyBluetoothService extends Service implements MyService { 

private final IBinder mBinder = new LocalBinder(); 

... 

public class LocalBinder extends MyService.LocalBinder { 
    MyService getService(Handler handler) { 
     mHandler = handler; 

     // Return this instance of MyService so clients can call public methods 
     return MyBluetoothService.this; 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    Log.w(TAG, "MyBluetoothService bound"); 

    return mBinder; 
} 
} 
+0

あなたは正しい軌道に乗っていました。私は実際の解決策を示すために私の質問を編集しました。私は、 'MyService'インターフェース内で' LocalBinder'をネストされたインターフェースとして宣言しなければなりませんでした。次に、 'MyBluetoothService.java'内の' LocalBinder'の実際の宣言のために、私は 'MyService.LocalBinder'を実装しなければなりませんでした。 – howettl

関連する問題