使用 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();
}
}
实现同样的目标...
我有这个代码:
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();
}
}
实现同样的目标...