有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法在未调用Looper的线程内创建处理程序。警报对话框线程上的prepare()

当我的splash活动检查了internet连接,但没有internet时,我的活动出错了。。这可能发生在我的警报对话框中

java.lang.RuntimeException: 
Can't create handler inside thread that has not called Looper.prepare()
at 安卓.os.Handler.<init>(Handler.java:200)                                
at 安卓.os.Handler.<init>(Handler.java:114)                              
at 安卓.app.Dialog.<init>(Dialog.java:108)                           
at 安卓.app.Dialog.<init>(Dialog.java:148)             
at 安卓.support.v7.app.AppCompatDialog.<init>(AppCompatDialog.java:43)           
at 安卓.support.v7.app.AlertDialog.<init>(AlertDialog.java:95)                
at 安卓.support.v7.app.AlertDialog$Builder.create(AlertDialog.java:927)        
at com.example.study.Splash.checking(Splash.java:66)
at com.example.study.Splash$2.run(Splash.java:51)

我试过了runOnUiThread(),但还是不行。。 这是我的启动代码

package com.example.study;

import 安卓.content.DialogInterface;
import 安卓.os.Bundle;
import 安卓.support.v7.app.AlertDialog;
import 安卓.support.v7.app.AppCompatActivity;

import com.example.study.helper.SessionManager;
import com.example.study.util.ConnectionDetector;

public class Splash extends AppCompatActivity {

    private ConnectionDetector cd;
    Boolean isInternetPresent = false;
    protected SessionManager session;

    private AlertDialog.Builder builder;


    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);


        builder = new AlertDialog.Builder(Splash.this);

        session = new SessionManager(getApplicationContext());
        cd = new ConnectionDetector(getApplicationContext());

        builder.setTitle("No Connection");
        builder.setMessage("Check Your Internet Connection.");
        builder.setIcon(R.drawable.fail);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int id) {

                    /* TODO Auto-generated method stub */
                dialog.dismiss();
            }
        });

        Thread timer = new Thread(){
            public void run(){
                try {
                    sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    checking();
                }
            }
        };
        timer.start();
    }

    public void checking() {

        isInternetPresent = cd.isConnectingToInternet();

        if(isInternetPresent) {
            session.checkLogin();
            finish();
        } else {
            builder.create().show();
            finish();
        }
    }
}

共 (2) 个答案

  1. # 1 楼答案

    在Android中Looper是一个运行消息循环的队列系统。默认情况下,创建线程时,线程没有与其关联的活套。因此,当您的AlertDialog尝试使用消息队列时,它会崩溃

    您可以在新线程中创建一个循环器,但是您应该在主线程上使用AlertDialog。为此,您可以使用HandlerpostDelayed方法:

    new Handler().postDelayed(
            new Runnable() {
                @Override
                public void run() {
                    checking();
                }
            },
            2000
    );
    

    onCreate方法中

  2. # 2 楼答案

    作为对前面问题的改进,我可能会做以下工作,因为UI线程上的网络活动也是一个坏主意:

    在onCreate()中创建处理程序:

    mHandler = new Handler();
    

    并且仍然在它自己的线程中运行checking(),但稍微更改一下:

    public void checking() {
    
        isInternetPresent = cd.isConnectingToInternet();
    
        if(isInternetPresent) {
            session.checkLogin();
            finish();
        } else {
            mHandler.post(new Runnable() {
            @Override
            public void run() {
                builder.create().show();
                finish();
            });
        }
    }
    

    这样,UI将在UI线程上完成,而网络将在另一个线程中完成