6

私はAndroid開発が初めてで、サービスにバインドしようとしています。サービスが開始されるとメソッドを呼び出すことができます。以下に説明するアクティビティとサービスは同じアプリケーションに含まれているため、そこに問題はないはずですが、アプリを実行するたびに次のエラーが表示されます。サービスにバインドするときのAndroid ClassCast例外

java.lang.ClassCastException:android.os.BinderProxy

これに起こる線である:

LocalBinder binder = (LocalBinder) service; 

My活動コードである(簡略化):

public class Main extends Activity { 

    boolean gpsBound = false; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 

    /** Called whenever the activity is started. */ 
    @Override 
    protected void onStart() { 
     super.onStart(); 
     // Bind to GPSService 
     Intent i = new Intent(this, GPSService.class); 
    startService(i); 
    bindService(i, connection, Context.BIND_AUTO_CREATE); 
    } 

    /** service binding */ 
    private ServiceConnection connection = new ServiceConnection() { 

     public void onServiceConnected(ComponentName className, IBinder service) { 
      // After binding to GPSService get the instance of it returned by IBinder 
     LocalBinder binder = (LocalBinder) service; 
      gpsBound = true; 
     } 

     public void onServiceDisconnected(ComponentName className) { 
      gpsBound = false; 
     } 
    }; 

} 

サービス:

public class GPSService extends Service { 

    @Override 
    public void onCreate() { 
      super.onCreate(); 
    } 

    @Override 
    public IBinder onBind(Intent i) { 
    // TODO Auto-generated method stub 
    return new LocalBinder<GPSService>(this); 
    } 


    /** 
    * Our implementation of LocationListener that handles updates given to us 
    * by the LocationManager. 
    */ 
    public class CustomLocationListener implements LocationListener { 

     DBHelper db; 

     CustomLocationListener() { 
      super(); 
     } 

    // Overridden methods here... 

    } 

} 

そして最後に、私のLocalBinder:

/** 
* A generic implementation of Binder to be used for local services 
* @author Geoff Bruckner 12th December 2009 
* 
* @param <S> The type of the service being bound 
*/ 

public class LocalBinder<S> extends Binder { 
    private String TAG = "LocalGPSBinder"; 
    private WeakReference<S> mService; 


    public LocalBinder(S service){ 
     mService = new WeakReference<S>(service); 
    } 


    public S getService() { 
     return mService.get(); 
    } 
} 

私はClassCast例外の意味を理解が、何をすべきか理解できません!私はGoogleのドキュメントの例に従ってきましたが、まだ動作していません。誰かがこれを引き起こしている可能性のあることについて何か光を当てることができますか?

ありがとうございます!

答えて

3

onServiceConnectedで渡されるLocalBinderにはジェネリック型の引数がありますが、ローカル変数LocalBinder binderには型がありません。

解決この一つの方法または別の、LocalBinderの定義からジェネリック型を除去することにより、またはonServiceConnected

class MyBoundService extends Service{ 
    private final IBinder mBinder = new MyBinder(); 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 

    public class MyBinder extends Binder{ 

     public void doStuff(){ 
      //Stuff 
     } 
     //More Binder Methods 
    } 
} 

class MyActivity extends Activity{ 
    private MyBinder mBinder; 

    @Override 
    protected void onStart(){ 
     Intent intent = new Intent(this, MyBoundService.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
    } 

    @Override 
    protected void onStop(){ 
     unbindService(mConnection); 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      mBinder = (TaskBinder) service; 
      mBound = true; 
     } 

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

    private void doStuff(){ 
     if (mBound) 
      mBinder.doStuff(); 
    } 
} 

で、ローカル変数バインダーのあなたの宣言に1を追加することにより、いずれかの周りいじるする本当の必要性弱い参照とそれ以外のもので。 (サンプルではありませんでした)

サービスメソッドASAPを呼び出す場合は、mBinderを設定した後にonServiceConnectedにコールを入れるだけです。それ以外の場合は、他のコールバック(onClickイベントなど)から呼び出します。

+0

が好き意味するか: 「LocalBinder バインダー=(LocalBinder )サービスを;」 それでも同じエラーが発生する場合は! –

+0

私はジェネリック医薬品を完全に取り出す方向に傾いていた。私はすぐに書いているboundServiceの使い方の簡単なサンプルで編集します。 –

+0

ジェネリック医薬品を使わずに自分自身に行くことができますが、もしあなたが素晴らしい例を与えることができれば!ありがとう、ジェームズ –

3

ローカルサービスにバインドしようとしている場合は、キャストできます。ただし、リモート(別のプロセス)サービスにバインドしようとする場合は、この記事で規定されているAIDLメソッドを使用する必要があります。あなたのサービスのあなたのAndroidManifest.xmlで

http://developer.android.com/guide/components/aidl.html

+0

リンクはもう有効ではありません。 –

+0

新しい有効なリンクhttp://developer.android.com/guide/components/aidl.html – MrMaffen

32

削除属性process

+2

これは正しい答えです。 – Snicolas

+1

好奇心、詳細な理由はありますか? –

+0

@ThomasDecaux LocalBinderは、サービスがアプリケーションと同じプロセス(ローカル)で実行されている場合にのみ使用できます。プロセス属性は、サービスを実行するための別のプロセスを作成するため、IPCを使用して通信する必要があります。バインドプロセス中に、Androidはサービスへのブリッジとして機能するBinderProxyを提供し、IPCクラス(AIDLで書かれています)をインスタンス化できます。 http://stackoverflow.com/a/10610463/269876 –

4

同じエラーがありました。マニフェストにandroid:process = ":process_description"属性を追加しました。あなたはそれを追加すると、あなたのサービスは、個別のプロセスとして作成され、したがって、あなたはbinderProxyのインスタンス(したがって、クラスキャスト例外)を取得

関連する問題