1

我正在尝试创建一个AlertDialog,我已经这样做了数百次,但这次它不起作用。我onResume()在我的活动中的方法上有这个代码:

@Override
protected void onResume() {
    super.onResume();
    if (DEBUG)
        Log.i("BrazoRobot", "onResume()");
    isSystemRdy = false;

    mBluetoothHelper = new BluetoothHelper(this, bluetoothName);
    mBluetoothHelper.connect();
    mBluetoothHelper.setOnBluetoothConnected(this);
}

BluetoothHelper正确创建了不是 Activity 类的对象,我将 Activity 上下文传递给它:

public BluetoothHelper (final Context ctx, final String bluetoothName) {
    mActivity = ((Activity)ctx);
    this.ctx = ctx;
    this.bluetoothName = bluetoothName;
}

问题出connect()在我创建对话框的方法上:

if (!mBluetoothAdapter.isEnabled()) {
    AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
    mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
    mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));
    mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (DEBUG)
                Log.i("BrazoRobotBT", "Turning on Bluetooth...");
            mBluetoothAdapter.enable();     // Enciendo el Bluetooth
        }
    });
    mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (DEBUG)
                Log.i("BrazoRobotBT", "Exit");
            mActivity.finish();
        }
    });
    mDialog.show();
}

我在mDialog.show(). ctx是我在构造函数中传递的活动上下文,我也尝试传递mActivityis ((Activity) ctx)toAlertDialog.Builder但我得到了同样的异常。

该对话框是要求用户启用蓝牙。我知道正确的方法是使用调用 startActivityForResult() 的内置方法,但我希望将所有内容都放在我的自定义类中,如果它不是 Activity,我就不能在我的类上使用 onActivityResult(),那就是为什么我要这样做。

为什么会这样?AFAIK 我正在 UI 线程上创建对话框。我也尝试在方法中创建对话框,onCreate()但它仍然是一样的。

03-06 21:06:20.320: E/WindowManager(31411): Activity com.roboticarm.andres.BrazoRobot has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4130de20 V.E..... R.....ID 0,0-495,244} that was originally added here
03-06 21:06:20.320: E/WindowManager(31411): android.view.WindowLeaked: Activity com.roboticarm.andres.BrazoRobot has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{4130de20 V.E..... R.....ID 0,0-495,244} that was originally added here
03-06 21:06:20.320: E/WindowManager(31411):     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
03-06 21:06:20.320: E/WindowManager(31411):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
03-06 21:06:20.320: E/WindowManager(31411):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.Dialog.show(Dialog.java:281)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
03-06 21:06:20.320: E/WindowManager(31411):     at com.bluetoothutils.andres.BluetoothHelper.connect(BluetoothHelper.java:119)
03-06 21:06:20.320: E/WindowManager(31411):     at com.roboticarm.andres.BrazoRobot.onResume(BrazoRobot.java:247)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1185)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.Activity.performResume(Activity.java:5217)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2862)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2901)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2364)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread.access$600(ActivityThread.java:153)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
03-06 21:06:20.320: E/WindowManager(31411):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 21:06:20.320: E/WindowManager(31411):     at android.os.Looper.loop(Looper.java:137)
03-06 21:06:20.320: E/WindowManager(31411):     at android.app.ActivityThread.main(ActivityThread.java:5204)
03-06 21:06:20.320: E/WindowManager(31411):     at java.lang.reflect.Method.invokeNative(Native Method)
03-06 21:06:20.320: E/WindowManager(31411):     at java.lang.reflect.Method.invoke(Method.java:511)
03-06 21:06:20.320: E/WindowManager(31411):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
03-06 21:06:20.320: E/WindowManager(31411):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
03-06 21:06:20.320: E/WindowManager(31411):     at dalvik.system.NativeStart.main(Native Method)

编辑 1 (onWindowFocusChanged)

按照建议尝试了此代码:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if(hasFocus){
        // Conecto al dispositivo bluetooth
        mBluetoothHelper = new BluetoothHelper(this, "linvor");
        mBluetoothHelper.connect();
        if(DEBUG) Log.i("BrazoRobotBT", "Interface");
        mBluetoothHelper.setOnNewBluetoothDataReceived(this);
        setPreferences();

        // Indico que entro en el Analizador lógico
        mBluetoothHelper.write(logicAnalyzerMode);
    }
}

但我不断收到完全相同的错误。


编辑 2(活动测试)

我尝试在 Activity 中的 onCreate() 和 onResume() 中创建一个对话框,它是用这个简单的代码完美创建的:

    public class CustomDialog extends Activity{

        private static final boolean DEBUG = true;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            AlertDialog.Builder mDialog = new AlertDialog.Builder(this);
            mDialog.setTitle(getString(R.string.BTRequestTitle));
            mDialog.setMessage(getString(R.string.BTRequestSummary));

            mDialog.setPositiveButton(getString(R.string.Yes), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
                }
            });
            mDialog.setNegativeButton(getString(R.string.No), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Exit");
                }
            });
            mDialog.show();
        }
    }

But, if I put this code inside my class method called from my Activity I get the exception.

编辑 3(奇怪的事实)

这是我的 connect() 方法,当我从我的 Activity 调用它并显示对话框时,我得到了异常:

public void connect (){
        // Compruebo que el dispositivo tenga Bluetooth
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Si no hay Bluetooth en el dispositivo muestro un dialogo alertando al usuario y salgo de la Activity
            AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
            dialog.setTitle(ctx.getString(R.string.NoBTAlertTitle));
            dialog.setMessage(ctx.getString(R.string.NoBTAlertText));
            dialog.setPositiveButton(ctx.getString(R.string.Ok), new OnClickListener(){
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mActivity.finish(); // Cierro porque no existe un módulo Bluetooth
                }
            });
        }
        // Si el dispositivo tiene Bluetooth me conecto
        else{
            // Compruebo que el Bluetooth esté activado, sino pido al usuario que lo active
            if (!mBluetoothAdapter.isEnabled()) {

                //mActivity.startActivity(new Intent(mActivity, CustomDialog.class));

                AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
                mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
                mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));

                mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
                        mBluetoothAdapter.enable();     // Enciendo el Bluetooth
                    }
                });
                mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if(DEBUG) Log.i("BrazoRobotBT", "Exit");
                        mActivity.finish();
                    }
                });
                mDialog.show();
            }
            // Compruebo si el dispositivo no esta en los dispositivos emparejados (paired)
            Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
            if (pairedDevices.size() > 0) {
                // Loop a travez de los dispositivos emparejados (paired)
                for (BluetoothDevice device : pairedDevices) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Name: " + device.getName() + " -- Address:  " + device.getAddress());
                    // Si el dispositivo coincide con el que busco lo asigno
                    if(device.getName().equals(bluetoothName)){
                        mBluetoothDevice = device;
                        // Establezco una conexión Bluetooth para enviar datos
                        establishConnection();
                        break;
                    }
                }
            }
            // Sino salgo, debe estar en los dispositivos emparejados
            else{
                mActivity.finish();
            }
        }
    }

但是,如果我创建一个单独的方法并从 Activity 调用,当显示对话框时我不会得到异常:

public void dialog(){
    AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
    mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
    mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));

    mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
        }
    });
    mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if(DEBUG) Log.i("BrazoRobotBT", "Exit");
            mActivity.finish();
        }
    });
    mDialog.show();
}

并使用它:

mCustomClass.dialog();      // Dialog is shown, no exception
4

2 回答 2

1

好的,稍作休息后我解决了。又是我的错。问题基本上是我正在显示对话框,在它显示之前我完成了活动:

public void connect (){
        // Compruebo que el dispositivo tenga Bluetooth
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Si no hay Bluetooth en el dispositivo muestro un dialogo alertando al usuario y salgo de la Activity
            AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
            dialog.setTitle(ctx.getString(R.string.NoBTAlertTitle));
            dialog.setMessage(ctx.getString(R.string.NoBTAlertText));
            dialog.setPositiveButton(ctx.getString(R.string.Ok), new OnClickListener(){
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mActivity.finish(); // Cierro porque no existe un módulo Bluetooth
                }
            });
        }
        // Si el dispositivo tiene Bluetooth me conecto
        else{
            // Compruebo que el Bluetooth esté activado, sino pido al usuario que lo active
            if (!mBluetoothAdapter.isEnabled()) {

                //mActivity.startActivity(new Intent(mActivity, CustomDialog.class));

                AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
                mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
                mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));

                mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
                        mBluetoothAdapter.enable();     // Enciendo el Bluetooth
                    }
                });
                mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if(DEBUG) Log.i("BrazoRobotBT", "Exit");
                        mActivity.finish();
                    }
                });
                mDialog.show();
            }
            // Compruebo si el dispositivo no esta en los dispositivos emparejados (paired)
            Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
            if (pairedDevices.size() > 0) {
                // Loop a travez de los dispositivos emparejados (paired)
                for (BluetoothDevice device : pairedDevices) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Name: " + device.getName() + " -- Address:  " + device.getAddress());
                    // Si el dispositivo coincide con el que busco lo asigno
                    if(device.getName().equals(bluetoothName)){
                        mBluetoothDevice = device;
                        // Establezco una conexión Bluetooth para enviar datos
                        establishConnection();
                        break;
                    }
                }
            }
            // Sino salgo, debe estar en los dispositivos emparejados
            else{
                mActivity.finish();
            }
        }
    }

我在“mDialog.show()”上显示对话框,但在我按下确定按钮之前,蓝牙仍未启用,因此没有配对设备,所以我完成了活动,但仍在绘制对话框,所以我得到了异常。我知道愚蠢的错误,我有时应该休息一下。

所以'connect()'方法现在是:

public void connect (){
    if(DEBUG) Log.i("BrazoRobotBT", "connect()...");
    // Compruebo que el dispositivo tenga Bluetooth
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter == null) {
        // Si no hay Bluetooth en el dispositivo muestro un dialogo alertando al usuario y salgo de la Activity
        AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
        dialog.setTitle(ctx.getString(R.string.NoBTAlertTitle));
        dialog.setMessage(ctx.getString(R.string.NoBTAlertText));
        dialog.setPositiveButton(ctx.getString(R.string.Ok), new OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(DEBUG) Log.i("BrazoRobotBT", "No bluetooth on device");
                mActivity.finish(); // Cierro porque no existe un módulo Bluetooth
            }
        });
    }
    // Si el dispositivo tiene Bluetooth me conecto
    else{
        // Compruebo que el Bluetooth esté activado, sino pido al usuario que lo active
        if (!mBluetoothAdapter.isEnabled()) {
            final AlertDialog.Builder mDialog = new AlertDialog.Builder(ctx);
            mDialog.setTitle(ctx.getString(R.string.BTRequestTitle));
            mDialog.setMessage(ctx.getString(R.string.BTRequestSummary));

            mDialog.setPositiveButton(ctx.getString(R.string.Yes), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Turning on Bluetooth...");
                    mBluetoothAdapter.enable();     // Enciendo el Bluetooth

                    // Espero a que encienda el Bluetooth
                    while(!mBluetoothAdapter.isEnabled());

                    // Compruebo si el dispositivo no esta en los dispositivos emparejados (paired)
                    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
                    if (pairedDevices.size() > 0) {
                        // Loop a travez de los dispositivos emparejados (paired)
                        for (BluetoothDevice device : pairedDevices) {
                            if(DEBUG) Log.i("BrazoRobotBT", "Name: " + device.getName() + " -- Address:  " + device.getAddress());
                            // Si el dispositivo coincide con el que busco lo asigno
                            if(device.getName().equals(bluetoothName)){
                                mBluetoothDevice = device;
                                // Establezco una conexión Bluetooth para enviar datos
                                establishConnection();
                                break;
                            }
                        }
                    }
                    // Sino salgo, debe estar en los dispositivos emparejados
                    else{
                        if(DEBUG) Log.i("BrazoRobotBT", "Finish Activity not in paired devices");
                        mBluetoothAdapter.disable();
                        mActivity.finish();
                    }
                }
            });

            mDialog.setNegativeButton(ctx.getString(R.string.No), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if(DEBUG) Log.i("BrazoRobotBT", "Exit");
                    mActivity.finish();
                }
            });

            mDialog.show();
        }
    }
}

它工作正常且符合预期。非常感谢 Waqas 的帮助,但我在 AlertDialog.Builder 上没有“mDialog.dismiss()”方法,因为它是自动完成的。

于 2013-03-07T16:58:51.963 回答
0

为了避免此错误,您应该调用mDialog.dismiss()活动的onStop方法。

原因:因为您不能简单地完成对话框所有者活动或跳转到新的活动而不正确处理对话框窗口。

于 2013-03-07T00:21:32.770 回答