6

Ok, tôi mới phát triển Android và đang cố gắng liên kết với dịch vụ để tôi có thể gọi các phương thức trên dịch vụ khi dịch vụ được bắt đầu. Hoạt động và Dịch vụ được mô tả bên dưới đều là một phần của cùng một ứng dụng nên không có bất kỳ sự cố nào ở đó, nhưng mỗi khi tôi chạy ứng dụng của mình, tôi nhận được lỗi sau:Trường hợp ngoại lệ ClassCast Android khi liên kết với dịch vụ

java.lang.ClassCastException: android.os.BinderProxy

dòng này xảy ra trên là:

LocalBinder binder = (LocalBinder) service; 

đang Hoạt động của tôi (đơn giản là):

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

} 

dịch vụ:

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... 

    } 

} 

Và cuối cùng LocalBinder tôi:

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

Tôi hiểu ý nghĩa của các ngoại lệ ClassCast nhưng không thể hiểu phải làm gì! Tôi đã làm theo các ví dụ trong tài liệu google nhưng nó vẫn không hoạt động. Bất cứ ai có thể làm sáng tỏ những gì có thể gây ra điều này?

Cảm ơn trước!

Trả lời

3

LocalBinder được truyền trong onServiceConnected có đối số kiểu chung, trong khi biến cục bộ LocalBinder binder của bạn không có.

Giải quyết này một cách này hay cách khác, bằng cách loại bỏ các loại generic từ định nghĩa của LocalBinder, hoặc bằng cách thêm một đến tuyên bố của bạn chất kết dính biến cục bộ của bạn trong 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(); 
    } 
} 

Không cần thực fiddle xung quanh với tham chiếu yếu và không có gì. chỉ cần chắc chắn để unbind (tôi không có trong mẫu)

Nếu bạn muốn gọi phương thức dịch vụ càng sớm càng tốt, chỉ cần thực hiện cuộc gọi trong onServiceConnected, sau khi bạn đặt mBinder. nếu không, chỉ cần gọi từ các cuộc gọi lại khác (các sự kiện onClick và whatnot).

+0

Bạn có nghĩa là: 'LocalBinder binder = (LocalBinder ) service;' Nếu vậy vẫn còn lỗi tương tự! –

+0

Tôi đã nghiêng về việc đưa ra các generics hoàn toàn. Tôi sẽ chỉnh sửa trong một mẫu nhanh chóng sử dụng một boundService tôi đang viết ngay bây giờ. –

+0

Sẽ có một bản thân mình mà không có generics nhưng nếu bạn có thể đưa ra một ví dụ đó sẽ là tuyệt vời!Cảm ơn, James –

3

Nếu bạn đang cố gắng liên kết với một dịch vụ địa phương hơn là có, bạn chỉ có thể truyền. Tuy nhiên nếu bạn đang cố gắng liên kết với dịch vụ từ xa (quy trình riêng), bạn phải sử dụng phương pháp AIDL như được quy định trong bài viết này.

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

+0

không còn hợp lệ. –

+0

Đây là liên kết hợp lệ mới http://developer.android.com/guide/components/aidl.html – MrMaffen

32

thuộc tính Xóa process trong AndroidManifest.xml của bạn dịch vụ của bạn.

+2

Đó là câu trả lời đúng. – Snicolas

+1

Tò mò, bất kỳ lý do chi tiết nào? –

+0

@ThomasDecaux Tôi tin rằng đó là vì LocalBinder chỉ có thể được sử dụng bất cứ khi nào dịch vụ chạy trong cùng một quá trình (cục bộ) như ứng dụng. Thuộc tính quy trình tạo ra một quy trình riêng biệt cho dịch vụ để chạy, và do đó, bạn phải sử dụng IPC để giao tiếp với nó. Trong quá trình liên kết, Android cung cấp cho bạn một BinderProxy để làm cầu nối cho dịch vụ để bạn có thể khởi tạo các lớp IPC của mình (được viết bằng AIDL). http://stackoverflow.com/a/10610463/269876 –

4

Đã xảy ra lỗi tương tự. Tôi đã thêm thuộc tính android: process = ": process_description" vào tệp kê khai. Khi bạn thêm nó, dịch vụ của bạn được tạo ra như là quá trình riêng biệt và do đó bạn có được dụ của binderProxy (Do đó lớp đúc ngoại lệ)

Các vấn đề liên quan