Android(安卓)Handler 作用以及使用
16lz
2021-01-25
Handler是用来做什么的,我引用一个人的博客的话: 很多人认为Handler的作用是更新UI,这说的的确没错,但是更新UI仅仅是Handler的一个特殊的使用场景,具体来说是这样的:有时候需要在子线程中进行耗时的IO操作,这可能是读取文件或者访问网络等,当耗时操作完成以后可能需要在UI上做一些改变,由于Android开发规范的限制,我们并不能在子线程中访问UI控件,否则就会触发程序异常,这个时候通过Handler就可以将更新UI的操作切换到主线程中执行。因此,本质上来说,Handler并不是专门用于更新UI的,它只是常被大家用来更新UI。
来源:<http://blog.csdn.net/singwhatiwanna/article/details/48350919>
卧槽,居然能更新UI,嗯 ,没错,是能更新 ,还记得刚开始的那段话吗,有个条件,在子线程中,进行一些的耗时的操作的时候,这个时候如果想更新UI,那么就必须用到Handler。 现在我们修改下子线程
OK,我们用Handler来更新UI,再修改下
在前面的文章中,我们展示了如何使用handler.sendMessage(sendEmptyMessage, sendMessageAtTime都是类似的)方法 不过现在呢我,我们对之前的代码优化下
我们现在来看看点有意思的事情,我们先回忆下之前在Handler()这个构造方法中,我们有个mCallback,也就是一个runnable,现在我们看下使用removeCallback()
当我们点击这个button后,textView中的内容就不会更新,这也就是removeCallback作用,当然我们想到,既然有removeCallback,那么就应该有的removeMessage,这是当然了,这个就不演示了
来源:<http://blog.csdn.net/singwhatiwanna/article/details/48350919>
package com.example.admin.handler_01;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private static final int MSG_ONE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv);
new MyThread0().start();
}
class MyThread0 extends Thread {
@Override
public void run() {
mTextView.setText("update UI in Thread by Handler");
}
}
}
卧槽,居然能更新UI,嗯 ,没错,是能更新 ,还记得刚开始的那段话吗,有个条件,在子线程中,进行一些的耗时的操作的时候,这个时候如果想更新UI,那么就必须用到Handler。 现在我们修改下子线程
这个时候就正常报错了 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. at com.example.admin.handler_01.MainActivity$MyThread0.run(MainActivity.java:114)class MyThread0 extends Thread {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mTextView.setText("update UI in Thread by Handler");
}
}
OK,我们用Handler来更新UI,再修改下
这个时候发现没有问题,这样就验证开头说的那句话了 以上演示了handler.post(new Runnable())方法/**
* mHandler.post(Runnable runnable)方法
*/
class MyThread0 extends Thread {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
mTextView.setText("update UI in Thread by Handler");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
在前面的文章中,我们展示了如何使用handler.sendMessage(sendEmptyMessage, sendMessageAtTime都是类似的)方法 不过现在呢我,我们对之前的代码优化下
之前我们是new了一个Message,现在用mHandler.obtainMessage()复用系统的,msg.sendToTarget()最终也是调用mHandler.sendMessage(),这里就不过多分析了. 我们可以关注下Message几个参数怎么用的,what用来识别message的,arg0,arg1传递的int类型,object就是传递任意对象了。package com.example.admin.handler_01;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int MSG_ONE = 0;
private TextView mTextView;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
/**
* int : msg.what
* int :msg.arg1 ,msg.arg2
* Object : msg.object
*/
int what = msg.what;
switch (what) {
case MSG_ONE:
int i = msg.arg1;
Student st = (Student) msg.obj;
mTextView.setText("i = " + i + "," + st.toString());
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
new MyThread2().start();
}
private void init() {
mTextView = (TextView) findViewById(R.id.tv);
}
class MyThread2 extends Thread {
@Override
public void run() {
//Message msg = new Message();
//获取与 mHandler绑定的线程的Message ,有就返回自己的Message对象 ,没有就创建Message对象
Message msg = mHandler.obtainMessage();
/**
* int msg.what
* int msg.arg1 ,int msg.arg2
* Object msg.object
*/
msg.what = MSG_ONE;
msg.arg1 = 10;
msg.obj = new Student(24, "David");
//mHandler.sendMessage(msg);
//把Message对象发给mHandler,mHandler再sendMessage(msg)
msg.sendToTarget();
}
}
class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "name=" + name + ",age=" + age;
}
}
}
我们现在来看看点有意思的事情,我们先回忆下之前在Handler()这个构造方法中,我们有个mCallback,也就是一个runnable,现在我们看下使用removeCallback()
package com.example.admin.handler_01;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextView;
private Handler mHandler = new Handler();
private int i = 0;
private Button mButton;
private MyRunnable myRunnable = new MyRunnable();
@Override
public void onClick(View v) {
int id = v.getId();
switch(id){
case R.id.bt:
mHandler.removeCallbacks(myRunnable);
break;
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
i++;
i = i % 3;
mTextView.setText("Handler" + String.valueOf(i));
mHandler.postDelayed(myRunnable, 1000);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
new MyThread1().start();
}
private void init() {
mTextView = (TextView) findViewById(R.id.tv);
mButton = (Button) findViewById(R.id.bt);
mButton.setOnClickListener(this);
}
/**
* mHandler.postDelayed(Runnable runnable,long delayedMill) 方法
*/
class MyThread1 extends Thread {
@Override
public void run() {
mHandler.postDelayed(myRunnable, 1000);
}
}
}
当我们点击这个button后,textView中的内容就不会更新,这也就是removeCallback作用,当然我们想到,既然有removeCallback,那么就应该有的removeMessage,这是当然了,这个就不演示了
更多相关文章
- 线程方法Android:异步调用详解
- Android查看数据库方法及工具
- [转]android解决apk编译方法数超过64k的问题
- Android(安卓)四大组件 ————Service(生命周期)
- Android(安卓)OOM-Heap,MAT工具检测内存泄露
- Android(安卓)神兵利器Dagger2使用详解(一)基础使用
- Android每周一轮子:OkHttp(1)
- Android生成二维码--拍照或从相册选取图片
- J2ME VS Android