如何用Kotlin为Java编写的UsbSerialPort类实现Parcelable
Great question! Let's break down how to solve this problem and analyze the approach you're considering.
Why You Can't Directly Pass UsbSerialPort via Intent
The core issue here is that UsbSerialPort from the third-party library doesn't implement Parcelable or Serializable—the two interfaces required to pass objects through Intent.putExtra(). Reconstructing the port from a string address won't work because the port object holds live hardware connection state that can't be recreated from a simple identifier.
Recommended Solutions to Share UsbSerialPort Between Activities
Instead of trying to serialize the object, use these approaches to share the live instance safely:
1. Use a Shared ViewModel (Best Practice)
ViewModels have a lifecycle independent of individual Activities, making them perfect for sharing objects that hold hardware resources.
First, create a dedicated ViewModel to hold the serial port reference:
import androidx.lifecycle.ViewModel class SerialPortViewModel : ViewModel() { var serialPort: UsbSerialPort? = null }
In your first Activity, assign the connected port to the ViewModel before launching the second Activity:
// Get the ViewModel instance val viewModel = ViewModelProvider(this)[SerialPortViewModel::class.java] // Assign your connected serial port viewModel.serialPort = yourConnectedSerialPort // Launch the second Activity startActivity(Intent(this, SecondActivity::class.java))
In the second Activity, retrieve the same ViewModel instance to access the port:
val viewModel = ViewModelProvider(this)[SerialPortViewModel::class.java] val serialPort = viewModel.serialPort // Use the serial port as needed
This approach avoids serialization entirely, keeps the connection state intact, and prevents memory leaks when used properly.
2. Use a Singleton Holder Class
If ViewModels aren't a fit for your use case, a simple singleton can store the port instance temporarily:
object SerialPortHolder { var serialPort: UsbSerialPort? = null }
In the first Activity:
SerialPortHolder.serialPort = yourConnectedSerialPort startActivity(Intent(this, SecondActivity::class.java))
In the second Activity:
val serialPort = SerialPortHolder.serialPort
⚠️ Important: Remember to set SerialPortHolder.serialPort = null and call serialPort?.close() when you're done using the port (e.g., in onDestroy() of your Activities) to avoid resource leaks.
Analysis of Your Proposed Inheritance + @Parcelize Approach
Unfortunately, this approach is not feasible for several reasons:
- Most third-party library core classes (like
UsbSerialPort) are markedfinal(orfinalby default in Java), meaning you can't inherit from them in Kotlin. - Even if the class was
open, you can't cast an existingUsbSerialPortinstance to your subclass—this will throw aClassCastExceptionat runtime, since the original object was never instantiated as your subclass. UsbSerialPortholds internal references toUsbDeviceandUsbDeviceConnection, which also don't implementParcelable. Even if you could create a subclass, you couldn't serialize these hardware-related objects into a Parcel.
This method will not work, so it's best to avoid pursuing it.
Final Tip
Always make sure to properly release the serial port resource when you're finished with it. Call serialPort?.close() in the appropriate lifecycle methods (like onDestroy()) to free up hardware resources and prevent crashes or connection issues.
内容的提问来源于stack exchange,提问作者vyi

