簡體   English   中英

在廣播接收器內添加自定義偵聽器可在Android中獲得NPE

[英]Adding a custom listener inside a broadcast receiver gives NPE in Android

我在這里遇到了一個問題,我正在嘗試通過實現廣播接收器來偵聽連接性更改,還初始化了廣播接收器中的自定義偵聽器,以便與活動進行有關連接性更改的通信以顯示Crouton Toast各個類的代碼如下:

廣播接收器:

public class NetworkStateReceiver extends BroadcastReceiver {

    private NetworkStateListener networkStateListener;

    public NetworkStateReceiver() {
    }

    public NetworkStateReceiver(NetworkStateListener networkStateListener) {
        this.networkStateListener = networkStateListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("test", "Network connectivity change ::: " + this.networkStateListener);
        if (intent.getExtras() != null) {

            NetworkInfo ni = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i("test", "Network " + ni.getTypeName() + " connected");
                networkStateListener.onConnected();
            }
        }
        if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("test", "There's no network connectivity");
            networkStateListener.onDisconnected();
        }
    }
}

自定義偵聽器界面:

public interface NetworkStateListener {

    public void onConnected();

    public void onDisconnected();
}

實現偵聽器和注冊接收器以進行連接性更改的活動:

    public class HomeActivity extends AppCompatActivity implements NetworkStateListener {
     private NetworkStateReceiver mReceiver;
     private LocalBroadcastManager mBroadcastManager;
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
      mBroadcastManager =    LocalBroadcastManager.getInstance(HomeActivity.this);
        mReceiver = new NetworkStateReceiver(HomeActivity.this);
    }

@Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
        mBroadcastManager.registerReceiver(mReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mBroadcastManager.unregisterReceiver(mReceiver);
    }
    }

這是清單條目:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test">

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

 <application
        android:name=".TestApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"

<receiver android:name=".shared.receivers.NetworkStateReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

我不知道為什么networkstateListener沒有被初始化。它給出了一個空指針,表示NetWorkStateListener可能沒有被初始化。有人可以幫我這個忙嗎? 過去,我是通過自定義廣播而不是通過此類系統廣播來實現的。

CONNECTIVITY_CHANGE廣播由系統發送。 這意味着您當前的設置有幾件事情。

  1. 您正在LocalBroadcastManager注冊的BroadcastReceiver實例將永遠不會收到該廣播,因為LocalBroadcastManager僅處理來自應用程序內部的廣播。

  2. 在清單中注冊Receiver類意味着系統將實例化Receiver的新實例來處理每個廣播。 由於尚未將這些實例作為偵聽器傳遞給您的Activity實例, networkStateListener onReceive() networkStateListener將為null,這很可能是您當前NullPointerException的來源。

根據所需的行為,您可以選擇幾種方式。

如果僅想在Activity運行時收到連接更改的通知,請執行以下操作:

  1. 而是使用Context#registerReceiver()方法Context#registerReceiver() Receiver的實例,然后從清單中刪除<receiver>條目。 如果將NetworkStateReceiver HomeActivity的內部類,則不需要該接口。

  2. 使用LocalBroadcastManagerNetworkStateReceiver和您的Activity之間(而不是您的偵聽器interface 您可以在Intent上使用額外的內容來指示連接狀態,或者使用其他操作來區分。

  3. 使用其他事件總線實現在Receiver和Activity之間進行通信。

如果即使在應用未運行時也希望收到有關更改的通知,請執行以下操作:

  1. 從接收器開始您的Activity ,並在Intent上附加一個附加符號以指示連接狀態。 如果將ActivitylaunchModesingleTasksingleTop ,並覆蓋其onNewIntent()方法,則這也可以處理Activity已經運行的情況。

在任何情況下,都沒有必要將Activity作為偵聽器傳遞給BroadcastReceiver

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM