还有一个 "Can't create handler inside thread that has not called Looper.prepare()" 主题
Yet another "Can't create handler inside thread that has not called Looper.prepare()" topic
我有这个代码,它是一个 Activity,启动时会检查互联网连接,如果有连接,生活就会继续。否则会出现一个对话框来打开连接。但是我做了一个线程,每 10 秒检查一次连接,如果连接丢失,它将再次显示对话框。
package greensmartcampus.eu.smartcampususerfeedbackapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.net.InetAddress;
public class HomeScreen extends AbstractPortraitActivity {
private static final int WIFI_REQUEST_CODE = 1;
private boolean networkSettingsDialogOpened = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
this.runOnUiThread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
(...)
private boolean isInternetAvailable() {
try {
final InetAddress ipAddr = InetAddress.getByName("google.com");
if (ipAddr.equals("")) {
return false;
} else {
return true;
}
} catch (Exception e) {
return false;
}
}
private void createNetErrorDialog() {
networkSettingsDialogOpened = true;
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need a network connection to use this application. Please turn on mobile network or Wi-Fi in Settings.")
.setTitle("Unable to connect")
.setCancelable(false)
.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent i = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivityForResult(i, WIFI_REQUEST_CODE);
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
HomeScreen.this.finish();
}
}
);
final AlertDialog alert = builder.create();
alert.show();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == WIFI_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
networkSettingsDialogOpened = false;
Toast.makeText(HomeScreen.this, "Returned Ok",
Toast.LENGTH_LONG).show();
}
if (resultCode == RESULT_CANCELED) {
networkSettingsDialogOpened = false;
Toast.makeText(HomeScreen.this, "Returned Canceled",
Toast.LENGTH_LONG).show();
}
}
}
}
但是我收到以下错误:
02-03 18:13:14.525 2683-2699/greensmartcampus.eu.smartcampususerfeedbackapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-193
Process: greensmartcampus.eu.smartcampususerfeedbackapp, PID: 2683
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.createNetErrorDialog(HomeScreen.java:97)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.access0(HomeScreen.java:15)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.run(HomeScreen.java:29)
注意: 第 97 行包含:
final AlertDialog alert = builder.create();
我在谷歌上搜索了很多,我已经在使用 runOnUiThread 的陈词滥调答案,但它并没有解决它。
我错过了什么?
您检查互联网的方式我猜您正在导致 UI 线程休眠。你应该这样做。
创建一个处理程序和线程运行 标志:
Handler mHandler = new Handler();
boolean isRunning = true;
然后,使用 onCreate() 方法中的这个线程:
new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
@Override
public void run() {
if(!HomeScreen.this.isInternetAvailable()){
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
}
}
});
} catch (Exception e) {
}
}
}
}).start();
稍微改变一下这个方法
private boolean isInternetAvailable() {
try {
final InetAddress ipAddr = InetAddress.getByName("google.com");
if (ipAddr.equals("")) {
return false;
} else {
isRunning = true;
return true;
}
} catch (Exception e) {
return false;
}
}
您不能从 UI 线程上 运行ning 的代码调用 Thread.sleep()
。这是您的代码:
this.runOnUiThread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
您只是需要 运行 在 UI 线程上显示 Dialog
的代码位。试试这个:
new Thread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
// Show the Dialog on the UI thread
HomeScreen.this.runOnUiThread(new Runnable() {
@Override
public void run() {
HomeScreen.this.createNetErrorDialog();
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
我有这个代码,它是一个 Activity,启动时会检查互联网连接,如果有连接,生活就会继续。否则会出现一个对话框来打开连接。但是我做了一个线程,每 10 秒检查一次连接,如果连接丢失,它将再次显示对话框。
package greensmartcampus.eu.smartcampususerfeedbackapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.net.InetAddress;
public class HomeScreen extends AbstractPortraitActivity {
private static final int WIFI_REQUEST_CODE = 1;
private boolean networkSettingsDialogOpened = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
this.runOnUiThread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
(...)
private boolean isInternetAvailable() {
try {
final InetAddress ipAddr = InetAddress.getByName("google.com");
if (ipAddr.equals("")) {
return false;
} else {
return true;
}
} catch (Exception e) {
return false;
}
}
private void createNetErrorDialog() {
networkSettingsDialogOpened = true;
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need a network connection to use this application. Please turn on mobile network or Wi-Fi in Settings.")
.setTitle("Unable to connect")
.setCancelable(false)
.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent i = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivityForResult(i, WIFI_REQUEST_CODE);
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
HomeScreen.this.finish();
}
}
);
final AlertDialog alert = builder.create();
alert.show();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == WIFI_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
networkSettingsDialogOpened = false;
Toast.makeText(HomeScreen.this, "Returned Ok",
Toast.LENGTH_LONG).show();
}
if (resultCode == RESULT_CANCELED) {
networkSettingsDialogOpened = false;
Toast.makeText(HomeScreen.this, "Returned Canceled",
Toast.LENGTH_LONG).show();
}
}
}
}
但是我收到以下错误:
02-03 18:13:14.525 2683-2699/greensmartcampus.eu.smartcampususerfeedbackapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-193
Process: greensmartcampus.eu.smartcampususerfeedbackapp, PID: 2683
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.createNetErrorDialog(HomeScreen.java:97)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.access0(HomeScreen.java:15)
at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.run(HomeScreen.java:29)
注意: 第 97 行包含:
final AlertDialog alert = builder.create();
我在谷歌上搜索了很多,我已经在使用 runOnUiThread 的陈词滥调答案,但它并没有解决它。
我错过了什么?
您检查互联网的方式我猜您正在导致 UI 线程休眠。你应该这样做。
创建一个处理程序和线程运行 标志:
Handler mHandler = new Handler();
boolean isRunning = true;
然后,使用 onCreate() 方法中的这个线程:
new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
@Override
public void run() {
if(!HomeScreen.this.isInternetAvailable()){
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
}
}
});
} catch (Exception e) {
}
}
}
}).start();
稍微改变一下这个方法
private boolean isInternetAvailable() {
try {
final InetAddress ipAddr = InetAddress.getByName("google.com");
if (ipAddr.equals("")) {
return false;
} else {
isRunning = true;
return true;
}
} catch (Exception e) {
return false;
}
}
您不能从 UI 线程上 运行ning 的代码调用 Thread.sleep()
。这是您的代码:
this.runOnUiThread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
HomeScreen.this.createNetErrorDialog();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
您只是需要 运行 在 UI 线程上显示 Dialog
的代码位。试试这个:
new Thread(new Runnable() {
@Override
public void run() {
while (!HomeScreen.this.isInternetAvailable()) {
if (!networkSettingsDialogOpened)
// Show the Dialog on the UI thread
HomeScreen.this.runOnUiThread(new Runnable() {
@Override
public void run() {
HomeScreen.this.createNetErrorDialog();
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();