Android'无法添加窗口 - 令牌null不适用于应用程序'异常

时间:2015-07-09 20:11:00

标签: android broadcastreceiver observer-pattern

我正在尝试为网络中的变化实现观察者模式。我对这是如何工作的一般概念,并需要一些微调的帮助,因为在尝试通知用户他们已经失去连接时,我收到以下错误:

Android'无法添加窗口 - 令牌null不适用于应用程序'异常

这是我的设置。首先,我有一个扩展BroadcastReceiver的ConnectionReceiver类。

public class ConnectionReceiver extends BroadcastReceiver {
    private static final String TAG = ConnectionReceiver.class.getSimpleName();

    private final List<NetworkStatusObserver> mObserverList = new ArrayList<NetworkStatusObserver>();
    private static boolean isNetworkConnected = true;

    @Override
    public void onReceive(Context context, Intent intent) {
        Logger.i(TAG, "onReceive() broadcast");
        boolean disconnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        boolean isNetworkConnectedCurrent;

        if (disconnected) {
            isNetworkConnectedCurrent = false;
        } else {
            NetworkInfo networkInfo;

            if (Build.VERSION.SDK_INT < 17) {
                networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            } else {
                ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                int networkType = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 0);
                networkInfo = cm.getNetworkInfo(networkType);
            }

            if (networkInfo != null && networkInfo.isConnected()) {
                isNetworkConnectedCurrent = true;
            } else {
                isNetworkConnectedCurrent = false;
            }
        }

        if (isNetworkConnectedCurrent != isNetworkConnected) {
            isNetworkConnected = isNetworkConnectedCurrent;
            Logger.d(TAG, "NetworkStatus.onReceive - isNetworkConnected: " + isNetworkConnected);
            notifyObservers(isNetworkConnected);
        }

 if (isNetworkConnected) {
            // already connected
        } else {
            Utils.showDialog(context, "", context.getString(R.string.default_network_error_message), false,
                    context.getString(R.string.retry), new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // handle click action
                }
            });
        }
    }

    /**
     * Lets all {@link NetworkStatusObserver}s know if the device is connected to a network.
     *
     * @param isNetworkConnectedCurrent
     */
    private void notifyObservers(Boolean isNetworkConnectedCurrent) {
        for (NetworkStatusObserver networkStatusObserver : mObserverList) {
            networkStatusObserver.notifyConnectionChange(isNetworkConnectedCurrent);
        }
    }

    public void addObserver(NetworkStatusObserver observer) {
        mObserverList.add(observer);
    }

    public void removeObserver(NetworkStatusObserver observer) {
        mObserverList.remove(observer);
    }

    /**
     * Interface for monitoring network status change
     */
    public interface NetworkStatusObserver {
        void notifyConnectionChange(boolean isConnected);
    }

我在Utils.java中调用的对话框方法是

public static void showDialog(Context context, String title, String message, boolean cancelable, String buttonLabel, DialogInterface.OnClickListener buttonListener) {
    if (isDialogShowing()) {
        return;
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle(title)
            .setMessage(message)
            .setCancelable(cancelable)
            .setNeutralButton(buttonLabel, buttonListener);
    mDialog = builder.create();
    mDialog.show(); // <--- the error comes on this line
}

我在清单中注册了这个接收器

<receiver android:name=".network.ConnectionReceiver">
    <intent-filter >
        <action android:name="android.net.wifi.STATE_CHANGE"/>
    </intent-filter>
</receiver>

问题是我将应用程序上下文传递给对话框而不是“活动”对话框。然后,我删除了在广播接收器中调用对话框的代码部分,并尝试将其添加到我的MainActivity.java类中。我实现了NetworkStatusObserver,但在这样做时我收到错误

无法解析notifyConnectionChange

我不确定观察者是如何发生的。顺便说一下,MainActivity扩展了FragmentActivity,这让我很难在onPause()和onResume()中添加/删除我的观察者,因为我不知道该替换“this”。 “这个”应该是什么?

// Note: connectionStatusReceiver is an object of ConnectionReceiver
unregisterReceiver(connectionStatusReceiver );
connectionStatusReceiver.removeObserver(this);

在我的onResume()中我试图添加

connectionStatusReceiver.addObserver(this);
registerReceiver(connectionStatusReceiver , new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

2 个答案:

答案 0 :(得分:2)

在{strong> YourActivity.this

中传递Context个对象showDialog()

public static void showDialog(Acitivity activity, String title, String message, boolean cancelable, String buttonLabel, DialogInterface.OnClickListener buttonListener) {
    if (isDialogShowing()) {
        return;
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    builder.setTitle(title)
            .setMessage(message)
            .setCancelable(cancelable)
            .setNeutralButton(buttonLabel, buttonListener);
    mDialog = builder.create();
    mDialog.show(); // <--- the error comes on this line
}

您可以看到此Link for Reference

答案 1 :(得分:0)

我找到了问题的答案。我无法从我的广播接收器启动一个对话框,因为我传递给我的对话框应用程序上下文而不是活动上下文。解决方案是在片段和活动上实现NetworkStatusObserver接口,我希望监视网络更改。一直这样做,我必须记住注册和取消注册我的接收器。对于Activites,我在onResume()/ onPause()中注册和取消注册我的接收者,对于片段,我在onStart()/ onPause()中注册和取消注册了我的接收者。

以下是我显示对话框的方式。

@Override
public void notifyConnectionChange(boolean isConnected) {
    Logger.i(TAG, "notifyConnectionChange: " + isConnected);
    if (isConnected && DeviceUtils.isNetworkAvailable(getActivity().getApplicationContext()) &&
            DialogUtils.isDialogShowing()) {
        DialogUtils.dismissDialog();
    } else {
        DialogUtils.showDialog(getActivity().getApplicationContext(), "",
                getString(R.string.default_network_error_message), false,
                getString(R.string.retry), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (DeviceUtils.isNetworkAvailable(getActivity().getApplicationContext())) {
                            DialogUtils.dismissDialog();
                        }

                    }
                });
    }
}

希望这有助于对如何使用观察者模式有类似误解的人。干杯!