使用新线程时的安卓异常



嗨,伙计们,我正在尝试制作一个应用程序,通过 Toast 消息实时获取我的电池状态。所以,如果我插入电池充电器,它应该显示"电池正在充电",如果我拔下充电器,它应该显示"电池正在放电",等等......为此,我正在使用一个新线程,但在运行时我的应用程序崩溃并且我在logcat中出现错误

这里有我的代码和日志:

public class MainActivity extends Activity {
Context cxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bn = (Button) findViewById(R.id.button);
    cxt = this;

    Runnable myRunnable = new Runnable() {
        @Override
        public void run() {
            IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
            Intent BatteryStatus = cxt.registerReceiver(null, IF);
            int status = BatteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
            boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
            boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
            boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
            if (isCharging) {
                Toast.makeText(getBaseContext(), "La batteria è in carica", Toast.LENGTH_SHORT).show();
            }
            if (disCharging) {
                Toast.makeText(getBaseContext(), "La batteria è in scarica", Toast.LENGTH_SHORT).show();
            }
            if (usbCharge) {
                Toast.makeText(getBaseContext(), "La batteria è in carica tramite USB", Toast.LENGTH_SHORT).show();
            }
            if (acCharging) {
                Toast.makeText(getBaseContext(), "La batteria è in carica tramite AC", Toast.LENGTH_SHORT).show();
            }
        }
    };
    Thread myThread = new Thread(myRunnable);
    myThread.start();
}

这是我在日志中遇到的错误:

01-04 11:10:10.696    7706-7723/com.example.matteo.battery E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-4343
Process: com.example.matteo.battery, PID: 7706
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.widget.Toast$TN.<init>(Toast.java:336)
        at android.widget.Toast.<init>(Toast.java:100)
        at android.widget.Toast.makeText(Toast.java:250)
        at com.example.matteo.battery.MainActivity$1.run(MainActivity.java:43)
        at java.lang.Thread.run(Thread.java:818)

我想我在尝试启动新线程时错了什么。

谢谢大家!

您无法

在非 UI 线程中更新 UI,

您在Toast消息中收到错误,

如果您想在新线程中执行一些代码,然后在更新 UI 之后使用AsyncTask,有关在新线程中更新 UI 的详细信息,请参阅从线程更新 UI 或查看文档

试试这个

if (isCharging) {
    MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "La batteria è in carica", Toast.LENGTH_SHORT).show();
                }
            });
}

适用于所有吐司

不使用线程。 创建BroadcastReceiver

BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
                boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
                boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
                boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
                boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
                //your code
            }
        };
        IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(receiver, IF);

BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Thread myThread = new Thread(myRunnable);
myThread.start();
            }
        };
        IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(receiver, IF);

使用广播接收器可以更轻松地完成您尝试实现的结果。看看以下安卓开发者网站的官方文档。

使用 runOnUiThread 在 UI 线程上运行指定的操作。

public class MainActivity extends Activity {
Context cxt;
Button bn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bn = (Button) findViewById(R.id.button);
        cxt = this;

        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
                Intent BatteryStatus = cxt.registerReceiver(null, IF);
                int status = BatteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
                boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
                boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
                boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
                boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
                if (isCharging) {
                    showMessage("La batteria è in carica");
                }
                if (disCharging) {
                    showMessage("La batteria è in scarica");
                }
                if (usbCharge) {
                    showMessage("La batteria è in carica tramite USB");
                }
                if (acCharging) {
                    showMessage("La batteria è in carica tramite AC");
                }
            }
        };
        Thread myThread = new Thread(myRunnable);
        myThread.start();
    }
    private void showMessage(final String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

最新更新