在Android中使用Thread发送消息

时间:2015-04-08 19:22:47

标签: java android multithreading alertdialog

我有这段代码:

 if (value) {
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        while (!isConnected()) {
                            synchronized (this) {
                                wait(3000);
                            }
                        }
                    } catch (InterruptedException ex) {
                    }

                    if(wifiManager.isWifiEnabled()){
                        sendMessageWidget();
                    } else {
                        showWifiSettingsAlert();
                    }
                }
            };

            thread.start();
        }

我希望我的应用等到谷歌api客户端连接,然后发送消息。

isConnected方法的代码是:

public boolean isConnected() {
        mGoogleApiClient.connect();
        if (mGoogleApiClient.isConnected()) {
            return true;
        }
        return false;
    }

但是我收到此错误消息: NullPointerException:无法在未调用Looper.prepare()的线程内创建处理程序,并且它表示错误是某处id showWifiSettingsAlert()

这是代码:

public void showWifiSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());

        // Setting Dialog Title
        alertDialog.setTitle("Location accuracy tips");

        // Setting Dialog Message
        alertDialog
                .setMessage("You can improve the accuracy of your location by turning on\n- Wi-Fi");

        // On pressing Settings button
        alertDialog.setPositiveButton("Turn on",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        wifiManager.setWifiEnabled(true);
//                       Posalji poruke al pre toga jos jednom azuriraj
//                       lokaciju al ako je pozvana aplikacija iz widgeta
                        if (value) {
                            sendMessageWidget();
                        }
                    }
                });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        wifiManager.setWifiEnabled(false);

                        // Posalji poruke al pre toga jos jednom azuriraj
                        // lokaciju al ako je pozvana aplikacija iz widgeta
                        if (value) {
                            sendMessageWidget();
                        }
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    }

我想,如果没有启用wifi,用户可以选择是否启用它,但无论哪种方式都应该发送消息......你能帮忙吗?

2 个答案:

答案 0 :(得分:0)

您在线程中使用mGoogleApiClient.connect();这是一种异步方法,但这是不允许的。

您可以尝试使用runOnUiThread代替:

runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    //do your stuff here
                }
            });

答案 1 :(得分:0)

由于您无法从主线程以外的线程触摸UI,因此必须将这些更改发布回UI线程及其looper和关联的处理程序。您可以通过创建与UI线程关联的处理程序(可以在任何地方工作,因为Looper.getMainLooper()是静态调用)来明确地执行此操作,例如:

if (value) {
            Handler uiCallback = new Handler(Looper.getMainLooper());
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        while (!isConnected()) {
                            synchronized (this) {
                                wait(3000);
                            }
                        }
                    } catch (InterruptedException ex) {
                    }

                    uiCallback.post(new Runnable() {
                        @Override public void run() {
                            if(wifiManager.isWifiEnabled()){
                                sendMessageWidget();
                            } else {
                                showWifiSettingsAlert();
                            }
                        }
                    });

                }
            };

            thread.start();
        }

或者根本不使用处理程序,如果您处于执行相同操作的活动中,则可以将部件包装在run()中的runOnUiThread()方法中。

但是,您应该注意,您实际上并不需要在此处使用任何线程。如果您按照https://developer.android.com/google/auth/api-client.html上的示例进行操作,您会发现通过实施ConnectionCallbacks, OnConnectionFailedListener,您可以从活动的mGoogleApis.connect()调用onStart(),当它连接或无法执行相应操作时回调将在调用线程上执行。例如,

@Override
public void onConnected(Bundle connectionHint) {
     if(wifiManager.isWifiEnabled()){
         sendMessageWidget();
     } else {
         showWifiSettingsAlert();
     }
}

实现同样的目标......