gpt4 book ai didi

java - 单例模式 "Access to Constructor not Allowed"

转载 作者:行者123 更新时间:2023-12-02 05:12:40 24 4
gpt4 key购买 nike

我对 Java 比较陌生,并且是自学的,所以我希望我缺少一些基本的理解。

背景:我正在使用蓝牙,我希望将其纳入服务中,以便我可以将收到的信息广播到多个 Activity 。这对于我的 MainActivity 来说效果很好,但对于其他任何 Activity 都不起作用。任何时候从设备读取任何其他 Activity 的蓝牙特征时,它都无法读取并使程序崩溃。我发现该特征在广播之前为非空,但在接收时为空。我认为这是由于错误地创建了两个服务实例并从从未处理过的实例中读取造成的。因此,为了消除这种可能性,我想将我的服务创建为单例。 (我想让问题切中主题,所以不会问,但建议值得赞赏。)

因此,我需要一个服务(BluetoothService)的单个实例,我用它来运行和处理一些蓝牙操作。我遇到了单例设计模式,这似乎就是我所追求的。我按照网上各种来源描述的方式实现了它:

    private static BluetoothService serviceInstance;
private BluetoothService() {} // Error occurs here

public static BluetoothService getSharedBluetoothService() {
if(serviceInstance == null)
serviceInstance = new BluetoothService();
return serviceInstance;
}

当 Activity 尝试绑定(bind)到服务时,我在 Activity 中定义了绑定(bind)器类:

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

如果我正确理解错误,则私有(private)构造函数会导致我的 MainActivity 出现错误 - 它无法实例化服务,因为它的构造函数是私有(private)的。如果构造函数公开,MainActivity 将无法绑定(bind)到服务。 onBind() 永远不会被调用,这会导致其他地方出现空指针异常。

我哪里出错了?据我所知,我遵循了正确的程序。我不知道该转向哪里。

编辑: Binder :

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

主要 Activity :

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)
{
// ...
};
}

最佳答案

您无法将 Service 构造函数设为私有(private)。 Android 需要能够创建许多组件来响应设备上发生的事件。例如,Android 可以创建 Service 类的实例来响应 Intent 。

您可以做的是设置一个单独的单例对象来完成您的工作,并在您的服务中获取该对象。但是,请注意服务的生命周期。如果您的服务是为了响应 Intent 或 startService 调用而启动的,那么该服务运行的时间取决于 onStartCommand 的返回值(START_STICKY 等)。该文档给出了很好的概述: http://developer.android.com/reference/android/app/Service.html

编辑:

听起来您主要只需要一个公共(public)位置来存储服务的数据,然后当其中一个 Activity 绑定(bind)到服务并请求它时,Android 创建的任何服务实例都可以获取该数据。看来您正在使用文档中的“LocalService”模式,这听起来是正确的做法。

我不知道你的蓝牙数据有多复杂,但在Android中存储数据的最常见方法是SharedPreferences(用于更简单的键/值数据)和数据库。如果您认为可以摆脱 SharedPreferences,那么您可以使用 JSON 将相当多的复杂性存储为长字符串。

如果你的数据太复杂,或者更多的是基于表,那么Android附带了SQLiteDatabase和相关类,还有一个ContentProvider类,它提供对数据库的URI类型访问。

我的方向正确吗?我现在就停下来,但如果您需要更多解释,或者我是否偏离了轨道,请告诉我。

关于java - 单例模式 "Access to Constructor not Allowed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27210935/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com