尝试调用LocalBroadcastManager.getInstance()时的NPE.sendBroadcast()

时间:2016-09-21 18:34:26

标签: android multithreading service

Android新手,开发可将蓝牙数据传送到多个不同活动的应用。我有一个ConnectActivity执行发现并向用户呈现设备,当用户选择设备时,如this讨论中的某人所建议,启动BluetoothService。

BluetoothService扩展服务并启动后台线程,该线程最终将用于阻止InputStream,并在活动可用时(即在这些活动通过startService()进行轮询之后)向活动广播数据。

这是活动。定义接收器:

public class ConnectActivity extends AppCompatActivity {
...
    // My test receiver just to see if things are working.
    private BroadcastReceiver mDataReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(D)
            Log.d(TAG, "Broadcast received.");
    }
};

启动服务onCreate():

protected void onCreate(Bundle savedInstanceState) {
...
    IntentFilter dataFilter = new IntentFilter(BluetoothService.INCOMING_DATA);
    registerReceiver(mDataReceiver, dataFilter);

    // Start the service with an intent identifying the context ("this" is an Activity,
    // which inherits from Context) and the recipient.
    Intent i = new Intent(this, BluetoothService.class);
    i.putExtra(BluetoothService.COMMAND, "MY_COMMAND"); // Add the command as payload to the intent.
    if(D)
        Log.d(TAG, "Starting service.");
    startService(i);
}

最后,按下按钮连接:

private void connect(){
   if(D)
        Log.d(TAG, "Connecting to device " + (mBluetoothDevices.get(mSelectedPos).toString()) + " at position " + mSelectedPos);

    final ProgressDialog dialog = new ProgressDialog(this);
    dialog.setTitle("Connecting");
    dialog.setMessage("Please wait...");
    dialog.show();

    if(D)
        Log.d(TAG, "Attempting to connect.");
    mBluetoothService.connect(mBluetoothDevices.get(mSelectedPos), dialog);

这是我的服务:

public class BluetoothService extends Service {
...
    public void connect (BluetoothDevice device, ProgressDialog dialog){
    ....
    // Start the thread to connect to the device
    mConnectThread = new ConnectThread(device, dialog, this);
    mConnectThread.start();
}

ConnectThread成功连接并启动一个ConnectedThread,用于将数据发送回活动状态。我包含所有内容,因为这是我的问题所在:

public class ConnectedThread extends Thread {
    private BluetoothSocket mmSocket;
    private final String mmMYNAME = "ConnectedThread";
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private final Context mmContext;


    public ConnectedThread(BluetoothSocket socket, Context context) {
        mmSocket = socket;
        mmContext = context;

        InputStream tryIn = null;
        OutputStream tryOut = null;

        // Get the BluetoothSocket input and output streams
        try {
            tryIn = mmSocket.getInputStream();
            tryOut = mmSocket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, mmMYNAME + " could not create streams.", e);
        }

        mmInStream = tryIn;
        mmOutStream = tryOut;
        mConnectedThreadEnabled = true;
    }

    @Override
    public void run()
    {
        Thread.currentThread().setName(mmMYNAME);
        Intent i = new Intent(INCOMING_DATA);

        while(mConnectedThreadEnabled) {
            SystemClock.sleep(1000);
            if(D)
                Log.d(TAG, "ConnectedThread is running.");

            LocalBroadcastManager.getInstance(mmContext).sendBroadcast(i); //KABOOM
        }
        if(D)
            Log.d(TAG, "Stopping ConnectedThread.");

    }

    public void cancel() {
        if(D)
            Log.d(TAG,"Canceling ConnectedThread.");

        try {
            if(D)
                Log.d(TAG,"Shutting down existing socket.");
            mConnectedThreadEnabled = false;
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }

}

我的问题在于:

LocalBroadcastManager.getInstance(mmContext).sendBroadcast(i); //KABOOM

我收到了:

java.lang.NullPointerException:尝试调用虚方法' android.content.Context android.content.Context.getApplicationContext()'在null对象引用上                                                                                 在android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:107)                                                                                 在android.support.v4.content.LocalBroadcastManager.getInstance(LocalBroadcastManager.java:102)                                                                                 在com.company.me.app.BluetoothService $ ConnectedThread.run(BluetoothService.java:255)

我不清楚问题是什么,因为调试表明mmContext和我似乎都是正确创建的。

1 个答案:

答案 0 :(得分:0)

  

执行mBluetoothService = new BluetoothService();

从不自己创建组件实例。摆脱这条线。任何使用mBluetoothService的内容都需要重写为:

  • 在服务中,或

  • 使用服务绑定(例如bindService(),活动然后调用提供的Binder上的方法)或

  • 使用其他模式,以避免尝试直接引用服务的活动,更不用说创建服务本身的实例