使用 Android 中的 Thread 发送消息

Using Thread in Android for sending message

我有这个代码:

 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();
        }

我希望我的应用程序等到 google 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 未启用,用户可以选择是否启用它,但无论哪种方式都应该发送消息...请帮忙吗?

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

您可以尝试使用 runOnUiThread 代替:

runOnUiThread(new Runnable() {

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

由于您无法从主线程以外的线程访问 UI,因此您必须 post 将这些更改返回到 UI 线程及其循环程序和关联的处理程序.您可以通过创建与 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();
        }

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

但是你应该注意,你实际上不需要在这里使用任何线程。如果您遵循以下示例:https://developer.android.com/google/auth/api-client.html,您会发现通过实施 ConnectionCallbacks, OnConnectionFailedListener,您可以从 activity 的 onStart() 调用 mGoogleApis.connect() 并且当它连接时or fails to do 相应的回调将在调用线程上执行。例如,

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

实现同样的目标...