我有这段代码:
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,用户可以选择是否启用它,但无论哪种方式都应该发送消息......你能帮忙吗?
答案 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();
}
}
实现同样的目标......