Android handle的难点问题及解答

 

1. 消息的使用

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        finish();
        overridePendingTransition(R.anim.abc_fade_in, R.anim.abc_fade_out);
    }
}, 500);
 

 

2. Looper 死循环为什么不会导致应用卡死?

线程默认没有Looper的,如果需要使用Handler就必须为线程创建Looper。我们经常提到的主线程,也叫UI线程,它就是ActivityThread,ActivityThread被创建时就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。

 

3. 子线程中使用Toast,更新UI会导致奔溃的原因

在这里显示Toast一定会崩溃,报错日志如下:

new Thread(new Runnable() {
@Override
public void run() {
  Toast.makeText(MainActivity.this, "run on thread" ,            Toast.LENGTH_SHORT).show();//崩溃无疑  
  }
}).start();

一般如果子线程不能更新UI控件是会报如下错误的(子线程不能更新UI)

原因分析:

子线程中Looper不同于主线程里面的Looper!

扫描二维码关注公众号,回复: 3452804 查看本文章

主线程里面的Looper是一直循环的,同时该looper不影响程序崩溃,只有在程序在OnCreate(),OnPause()会暂时结束,在activity生命周期OnPause()结束后,Looper继续。因此主线程中更新UI不会出现问题。

子线程中looper不是一直循环的,因此在子线程中更新UI可能会发生崩溃。

完成代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 
    public static final int UPDATE_TEXT = 1;
 
    private TextView textView;
    private Button changeText;
 
    // 消息异步处理机制
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(){
        public void handleMessage(Message msg){ // 在这里接收handle消息,handleMessage()方法在主线程中处理
            switch (msg.what) {
                case UPDATE_TEXT:
                    // 在这里进行UI操作
                    textView.setText("更新数据");
                    break;
                default:
                    break;
            }
        }
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.text);
        changeText = (Button) findViewById(R.id.change);
        changeText.setOnClickListener(this);  // 设置button点击监听
    }
 
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.change:
                // 创建子线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 1.0版本,这样写,在子线程中进行UI操作会导致奔溃
                        // textView.setText("更新数据");
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);  // 将Message对象发送出去
                    }
                }).start();
                break;
                default:
                    break;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37218227/article/details/82953721