6

ठीक है, मैं एंड्रॉइड विकास के लिए नया हूं और एक सेवा से जुड़ने की कोशिश कर रहा हूं ताकि मैं इसे शुरू होने के बाद सेवा पर विधियों को कॉल कर सकूं। नीचे वर्णित गतिविधि और सेवा दोनों एक ही अनुप्रयोग का हिस्सा हैं इसलिए वहां कोई समस्या नहीं होनी चाहिए, लेकिन हर बार जब मैं अपना ऐप चलाता हूं तो मुझे निम्न त्रुटि मिलती है:एंड्रॉइड क्लासकास्ट अपवाद सेवा के लिए बाध्यकारी

java.lang.ClassCastException: android.os.BinderProxy

लाइन इस पर होता है:

LocalBinder binder = (LocalBinder) service; 

मेरी गतिविधि कोड (सरलीकृत है):

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

सर्विसबिनेक्टेड में पास किया गया लोकलबिंडर एक सामान्य प्रकार का तर्क है, जबकि आपके स्थानीय चर 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(); 
    } 
} 

में अपने स्थानीय चर बांधने की मशीन के अपने घोषणा करने के लिए एक जोड़कर कमजोर संदर्भ और क्या नहीं के साथ। बस अनइंड करना सुनिश्चित करें (मैंने नमूना में नहीं किया था)

यदि आप सेवा विधियों ASAP का आह्वान करना चाहते हैं, तो बस एमबींडर सेट करने के बाद, सेवा से कनेक्ट होने पर कॉल करें। अन्यथा, बस अन्य कॉलबैक (ऑनक्लिक घटनाओं और क्या नहीं) से आह्वान करें।

+0

क्या आप मतलब चाहते: 'LocalBinder बांधने की मशीन = (LocalBinder ) सेवा;' यदि ऐसा है तो भी वही त्रुटि देता है! –

+0

मैं जेनेरिक पूरी तरह से बाहर निकालने की दिशा में झुका रहा था। मैं अभी एक लिखित सेवा के उपयोग के त्वरित नमूने में संपादित करूंगा जो मैं अभी लिख रहा हूं। –

+0

जेनिक्स के बिना खुद को जाना होगा, लेकिन अगर आप एक उदाहरण दे सकते हैं जो बहुत अच्छा होगा!धन्यवाद, जेम्स –

3

यदि आप हां से स्थानीय सेवा से जुड़ने की कोशिश कर रहे हैं, तो आप इसे बस डालेंगे। हालांकि यदि आप रिमोट (अलग प्रक्रिया) सेवा से जुड़ने की कोशिश कर रहे हैं तो आपको इस आलेख में निर्धारित एआईडीएल विधि का उपयोग करना होगा।

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

+0

लिंक अब मान्य नहीं है। –

+0

यहां नया मान्य लिंक है http://developer.android.com/guide/components/aidl.html – MrMaffen

32
अपनी सेवा के अपने AndroidManifest.xml में

हटाएं विशेषता process

+2

यह सही उत्तर है। – Snicolas

+1

उत्सुक, कोई विस्तृत कारण? –

+0

@ थॉमसडेकॉक्स मेरा मानना ​​है कि ऐसा इसलिए होता है क्योंकि जब भी सेवा उसी प्रक्रिया (स्थानीय) में एप्लिकेशन के रूप में चलती है तो स्थानीय बाइंडर का उपयोग किया जा सकता है। प्रक्रिया विशेषता सेवा चलाने के लिए एक अलग प्रक्रिया बनाती है, और इस प्रकार, आपको इसके साथ संवाद करने के लिए आईपीसी का उपयोग करना होगा। बाध्य प्रक्रिया के दौरान, एंड्रॉइड आपको सेवा के पुल के रूप में कार्य करने के लिए एक बाइंडरप्रॉक्सी प्रदान करता है ताकि आप अपने आईपीसी कक्षाओं (एआईडीएल में लिखे गए) को तुरंत चालू कर सकें। http://stackoverflow.com/a/10610463/269876 –

4

एक ही त्रुटि थी। मैंने एंड्रॉइड जोड़ा था: प्रक्रिया = ": process_description" मैनिफेस्ट में विशेषता। जब आप इसे जोड़ने के लिए, आपकी सेवा अलग प्रक्रिया के रूप में बनाया जाता है और इसलिए आप binderProxy (इसलिए वर्ग डाली अपवाद) के कहने मिल

संबंधित मुद्दे