【发布时间】:2014-11-30 07:11:54
【问题描述】:
我对 Java 比较陌生,并且是自学成才的,所以我希望会有一些我缺少的基本理解。
背景:我正在使用我想在服务中使用的蓝牙,以便我可以将接收到的信息广播到多个活动。这适用于我的 MainActivity,但不适用于其他任何人。每当从设备中为任何其他 Activity 读取蓝牙特征时,它都无法读取并使程序崩溃。我发现该特征在广播之前是非空的,但无论何时收到它都是空的。我相信这是由于错误地创建了两个服务实例并从一个从未处理过的实例中读取。因此,为了消除这种可能性,我想将我的服务创建为单例。 (我想保持问题的主题,所以不会问,但建议是赞赏。)
所以,我需要一个服务 (BluetoothService) 实例,我用它来运行和处理一些蓝牙操作。我遇到了单例设计模式,这似乎是我所追求的。我按照网上各种来源描述的方式实现了它:
private static BluetoothService serviceInstance;
private BluetoothService() {} // Error occurs here
public static BluetoothService getSharedBluetoothService() {
if(serviceInstance == null)
serviceInstance = new BluetoothService();
return serviceInstance;
}
当 Activity 尝试绑定到服务时,我在 Activity 中定义了绑定器类:
public class BtBinder extends Binder {
BluetoothService getService() {
return getSharedBluetoothService(); // returns reference to current service
//return BluetoothService.this; // Line used prior to introducing a Singleton pattern.
}
}
如果我正确理解错误,则私有构造函数会导致我的 MainActivity 出错 - 它无法实例化服务,因为它的构造函数是私有的。如果构造函数公开,则 MainActivity 无法绑定到服务。 onBind() 永远不会在其他地方导致空指针异常。
我哪里错了?据我所知,我遵循了正确的程序。我不知道该转向哪里。
编辑: 活页夹:
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "Currently binding");
BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();
return myBinder; // When bound, return the whole MyLocalBinder Binder.
}
主活动:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
// ...
BluetoothService BtService;
boolean isBound = false;
BluetoothBroadcast btSetupReceiver = null;
BluetoothBroadcast resultsReceiver = null;
boolean receiversAreRegistered = false;
private static final String TAG = "BluetoothGattActivity";
private static final String DEVICE_NAME = "Suspensionometer 3333";
private BluetoothAdapter mBluetoothAdapter;
private SparseArray<BluetoothDevice> mDevices;
private BluetoothGatt mConnectedGatt;
private ProgressDialog mProgress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Bind the service
Intent intent = new Intent(this, BluetoothService.class);
Log.d(TAG, "Attempting to bind to service.");
bindService(intent, btServiceConnection, Context.BIND_AUTO_CREATE);
// Set up BroadcastReceiver
btSetupReceiver = new BluetoothBroadcast(){
@Override
public void onReceive(Context context, Intent intent)
{
// ...
};
resultsReceiver = new BluetoothBroadcast() {
@Override
public void onReceive(Context context, Intent intent)
{
// ...
};
}
【问题讨论】:
-
你能显示Binder类的代码吗?
-
1.您可以发布 MainActivity 代码以便我们查看错误发生的位置吗? 2.虽然我知道的不够多,但我认为你不应该让一个Android服务成为单例。在您深入研究之前,我会进行更多研究...
-
我已经添加了 Binder 和 MainActivity。如果它不是你所追求的,请告诉我。除了 hatcyl 所说的之外,我确信可能还有其他方法可以做到这一点,并且单例是不必要的。然而,这个想法当时似乎很简单,可以实施,我想我被冲昏了头脑......
标签: java android service constructor singleton