使用Pyjnius绑定IBinder与LocalBinder时遇AttributeError问题求助
Fixing AttributeError for NokeDeviceManagerService.LocalBinder in Pyjnius
It looks like you're hitting a common pitfall when accessing Java inner classes with Pyjnius, plus a small issue with your method signature. Let's break down the problem and fix it step by step.
Why You're Seeing the Error
- Incorrect Inner Class Access: In Java, static inner classes are accessed using the
OuterClass.InnerClasssyntax, but Pyjnius requires using a$instead of a dot to reference static inner classes. Your attempt to accessnokeDeviceManagerService.LocalBinderwon't work because Pyjnius doesn't resolve inner classes that way from an instance. - Unnecessary Service Instance: You don't need to create a new
NokeDeviceManagerServiceinstance — the service instance is already managed by the Android system and retrieved via the binder'sgetService()method. - Missing
selfParameter: As a Python class method,onServiceConnectedmust haveselfas its first parameter to reference the instance and avoid signature mismatches.
Corrected Code
First, properly reference the static LocalBinder inner class using Pyjnius's syntax:
from jnius import autoclass, cast, PythonJavaClass, java_method # Reference the main service class and its static inner LocalBinder class NokeDeviceManagerService = autoclass('com.noke.nokemobilelibrary.NokeDeviceManagerService') NokeDeviceManagerService_LocalBinder = autoclass('com.noke.nokemobilelibrary.NokeDeviceManagerService$LocalBinder') NokeDevice = autoclass('com.noke.nokemobilelibrary.NokeDevice') NokeMobileError = autoclass('com.noke.nokemobilelibrary.NokeMobileError') NokeServiceListener = autoclass('com.noke.nokemobilelibrary.NokeServiceListener') class ServiceConnection(PythonJavaClass): __javainterfaces__ = ('android.content.ServiceConnection') __javacontext__ = 'app' @java_method('(Landroid/content/ComponentName;Landroid/os/IBinder;)V') def onServiceConnected(self, component_name, raw_binder): # Cast the raw IBinder to the correct LocalBinder type local_binder = cast(NokeDeviceManagerService_LocalBinder, raw_binder) # Retrieve the bound service instance self.mNokeService = local_binder.getService() # Initialize and register your listener, then start scanning self.mNokeServiceListener = NokeServiceListener() self.mNokeService.registerNokeListener(self.mNokeServiceListener) self.mNokeService.startScanningForNokeDevices()
Key Fixes Explained
- Static Inner Class Reference: Using
NokeDeviceManagerService$LocalBindertells Pyjnius to directly access the static inner class, which matches how Java resolvesNokeDeviceManagerService.LocalBinder. - Removed Unnecessary Instance: The
NokeDeviceManagerService()instantiation was redundant — the service you need is already bound and provided via the binder. - Added
selfParameter: This ensures your method adheres to Python's instance method conventions and matches the expected method signature for theServiceConnectioninterface.
Additional Notes
If you need to handle the onServiceDisconnected method (required for the ServiceConnection interface), add it to your ServiceConnection class with the correct signature:
@java_method('(Landroid/content/ComponentName;)V') def onServiceDisconnected(self, component_name): # Clean up references here self.mNokeService = None self.mNokeServiceListener = None
内容的提问来源于stack exchange,提问作者GoBig06
相关产品推荐
相关产品推荐

