簡體   English   中英

無法在警告對話框線程中未調用Looper.prepare()的線程內創建處理程序

[英]Can't create handler inside thread that has not called Looper.prepare() on alert dialog thread

當我檢查互聯網連接並且沒有互聯網時,我的啟動活動出錯了。它可能發生在我的警報對話框中。

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.Dialog.<init>(Dialog.java:148)             
at android.support.v7.app.AppCompatDialog.<init>(AppCompatDialog.java:43)           
at android.support.v7.app.AlertDialog.<init>(AlertDialog.java:95)                
at android.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 android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.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();
        }
    }
}

在Android中, Looper是一個運行消息循環的隊列系統。 默認情況下,Thread在創建時沒有與之關聯的Looper。 因此,當您的AlertDialog嘗試使用消息隊列時,它會崩潰。

可以在新線程中創建一個Looper,但是您應該在主線程上使用AlertDialog。 為此,您可以使用Handler postDelayed方法:

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

在你的onCreate方法中

作為對早期問題的改進,我可能會做以下事情,因為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在另一個線程中完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM