如何让公共蓝牙包方法在所有子包中可访问且无需设为public
解决方案:在Android中实现包结构隔离且子包可访问核心方法
我完全懂你的困扰——既要保持代码结构清晰,又不想把核心蓝牙方法暴露成public,还要让SPP、HDP、BTLE这些子包能复用公共包的通用逻辑。结合Java/Kotlin的访问权限规则和Android的代码组织方式,给你几个实用的解决方案:
1. 用Kotlin的internal权限(推荐,如果你用Kotlin开发)
Kotlin的internal修饰符可以让方法/类在同一个模块内的所有包可见,但对模块外完全隐藏。这完美匹配你的需求:
- 公共蓝牙包的核心方法设为
internal,不用暴露给外部 - SPP、HDP、BTLE子包和公共包同属一个模块,直接就能访问这些
internal方法 - 包结构保持清晰,各自负责不同的蓝牙协议实现
示例代码:
// 公共包:com.yourapp.bluetooth.core internal class CoreBluetooth(private val context: Context, private val receiver: BroadcastReceiver) { internal fun connectDevice(address: String) { // 通用蓝牙连接逻辑 } internal fun scanDevices() { // 通用扫描逻辑 } } // SPP子包:com.yourapp.bluetooth.spp class SppBluetooth(context: Context, receiver: BroadcastReceiver) { private val core = CoreBluetooth(context, receiver) fun connectSppDevice(address: String) { // 直接调用公共包的internal方法 core.connectDevice(address) // 加上SPP专属的连接逻辑 } }
2. 优化继承方案,解决Context和BroadcastReceiver问题
你之前尝试继承遇到的问题,其实可以通过构造函数传递依赖来解决,不用把核心方法设为public:
- 公共包的基类把Context和BroadcastReceiver通过构造函数接收并持有
- 基类的通用方法设为
protected,子类(子包中的类)可以直接访问 - 每个子包的类继承基类,初始化时传入所需的Context和Receiver
示例代码(Java):
// 公共包:com.yourapp.bluetooth.core public abstract class BaseBluetooth { protected final Context context; protected final BroadcastReceiver bluetoothReceiver; // 构造函数接收依赖,子类必须调用 protected BaseBluetooth(Context context, BroadcastReceiver receiver) { this.context = context; this.bluetoothReceiver = receiver; } // 通用方法,protected修饰,仅子类可见 protected void connectGeneric(String address) { // 通用连接逻辑 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice device = adapter.getRemoteDevice(address); // ... } } // SPP子包:com.yourapp.bluetooth.spp public class SppBluetooth extends BaseBluetooth { public SppBluetooth(Context context, BroadcastReceiver receiver) { super(context, receiver); // 传递依赖给父类 } public void connectSpp(String address) { // 调用父类的protected方法 connectGeneric(address); // SPP专属逻辑:比如创建RFCOMM通道 // ... } }
这种方案既保持了继承的代码复用性,又解决了Context和Receiver的初始化问题,同时核心方法不会暴露给外部包。
3. 接口+工厂模式,隐藏实现细节
如果不想用继承,也可以用接口定义通用行为,把具体实现放在公共包内,通过工厂方法提供实例给子包:
- 公共包定义
public的接口,暴露需要的通用方法 - 公共包内创建包级私有(默认权限)的实现类,实现接口逻辑
- 公共包提供
public的工厂类,负责创建实现类的实例 - 子包通过接口访问通用逻辑,完全看不到实现细节
示例代码(Java):
// 公共包:com.yourapp.bluetooth.core public interface BluetoothCore { void connectDevice(String address); void startScan(); } // 包级私有实现类,仅核心包内可见 class BluetoothCoreImpl implements BluetoothCore { private Context context; private BroadcastReceiver receiver; BluetoothCoreImpl(Context context, BroadcastReceiver receiver) { this.context = context; this.receiver = receiver; } @Override public void connectDevice(String address) { // 通用连接逻辑 } @Override public void startScan() { // 通用扫描逻辑 } } // 公共工厂类,对外提供实例 public class BluetoothCoreFactory { public static BluetoothCore create(Context context, BroadcastReceiver receiver) { return new BluetoothCoreImpl(context, receiver); } } // SPP子包:com.yourapp.bluetooth.spp public class SppBluetooth { private BluetoothCore core; public SppBluetooth(Context context, BroadcastReceiver receiver) { core = BluetoothCoreFactory.create(context, receiver); } public void connectSppDevice(String address) { core.connectDevice(address); // SPP专属逻辑 } }
这种方案的好处是完全解耦了子包和公共包的实现,核心逻辑被隐藏,同时结构清晰。
内容的提问来源于stack exchange,提问作者Brian Reinhold
相关产品推荐
相关产品推荐

