multithreading - 另一个 "Can' t 在未调用 Looper.prepare() 的线程内创建处理程序”主题

标签 multithreading android-intent android-activity android

我有这段代码,它是一个 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.access$200(HomeScreen.java:15)
            at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen$1.run(HomeScreen.java:29)

注意:第 97 行包含:

final AlertDialog alert = builder.create();

我用谷歌搜索了很多,我已经在使用runOnUiThread的陈词滥调答案,但它并没有解决它。

我错过了什么?

最佳答案

您检查互联网的方式我猜您正在导致您的 UI 线程休眠。你应该这样做。

创建一个Handler和Thread运行标志:

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

关于multithreading - 另一个 "Can' t 在未调用 Looper.prepare() 的线程内创建处理程序”主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28306332/

相关文章:

c# - 多个线程向一个列表添加元素。为什么列表中的项目总是比预期的少?

multithreading - WSGI的线程和进程怎么统计?

c++ - 循环缓冲区的线程安全实现

使用 Intent 不打开应用程序的 Android 深层链接

android - 控制 android fragment 创建顺序

Java 定时器与静态方法

android - 试图在另一个 Activity 中将两个 EditTexts 的产品显示为 TextView

android - Intent 未发送 ACTION_POWER_CONNECTED

android - BroadCast Receiver 正在计算电源按钮的点击次数,但无法恢复最小化的 Activity

java - 一项全程运行的 Activity