什么是Handler
Posted lixiansheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是Handler相关的知识,希望对你有一定的参考价值。
定义
Handler是用来结合线程的消息队列来发送、处理"Message对象"和"Runnable对象"的工具。
每一个Handler实例之后会关联一个线程和该线程的消息队列。也就是说,当你创建一个Handler的时候,从此开始,他就会自动关联到所在的线程/消息队列,然后它就会陆续把Message/Runnable分发到消息队列,并在他们出队的时候处理掉。因为android只允许在主线程中更新UI,Handler的目的就是作为线程通信的桥梁,进而再通过主线程更新UI。使用Handler这种异步回调机制,使我们可以再完成一个很长的任务后再做出相应的通知。
Handler和Message、MessageQueue、Looper之间的关系
Message
Handler接收与处理的消息对象
MessageQueue
消息队列,以先进先出队列形式管理所有的Message,且在初始化Looper对象时会创建一个与之关联的MessageQueue。每个线程最多只有一个MessageQueue。MessageQueue通常都是由Looper来管理,而主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个MessageQueue。其他非主线程,不会自动创建Looper。
Looper
每个线程只能够一个Looper,管理MessageQueue,不断从中去除Message分发给对应的Handler处理。
通俗一点讲:当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送消息;而我们发送的消息会先到主线程的MessageQueue中进行等待,由Looper按先入先出顺序取出,再根据Message对象的what属性分发给对应的Handler进行处理。
Handler的主要用途
1.推送未来某个时间点将要执行的Message或者Runnable到消息队列
通过Handler+Message的方式更新UI
public class MainActivity extends AppCompatActivity private TextView text; private static final int UPDATE_TEXT = 1; //整型常量用于表示更新TextView这个动作 @Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.id.activity_main); text = (TextView) findViewById(R.id.text); Button chaneText = (Button) findViewById(R.id.change_text); change_text.setOnClickListener(this); //新增Handler对象,并重写父类的handlerMessage()方法,在这里对具体的Message进行处理 private Handler handler = new Handler() public void handleMessage(Message msg) //收到消息,在HandleMessage()方法中对消息进行处理 switch (msg.what) case UPDATE_TEXT: // 在这里进行UI操作,处于主线程中 text.setText("Nice to meet you"); break; default: break; ; @Override public void onClick(View v) switch(v.getId()) case R.id.change_text: new Thread(new Runnable() @Override public void run() Message message = new Message(); message.what = UPDATE_TEXT; //将waht字段的值指定为UPDATE_TEXT handler.sendMessage(message); //调用Handler的sendMessage()方法发送消息 ).start(); break; default: break;
2.在子线程把需要在另一个线程执行的操作加入到消息队列中去
通过Handler + Message来实现子线程加载图片,在UI线程显示图片
public class ThreadActivity extends AppCompatActivity implements View.OnClickListener private ActivityThreadBinding mBinding = null; @Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); mBinding = DataBindingUtil.setContentView(this, R.layout.activity_thread); // 设置点击事件 mBinding.clickBtn.setOnClickListener(this); mBinding.resetBtn.setOnClickListener(this); @Override public void onClick(View v) switch (v.getId()) // 响应load按钮 case R.id.clickBtn: // 开启一个线程 new Thread(new Runnable() @Override public void run() // 在Runnable中进行网络读取操作,返回bitmap final Bitmap bitmap = loadPicFromInternet(); // 在子线程中实例化Handler同样是可以的,只要在构造函数的参数中传入主线程的Looper即可 Handler handler = new Handler(Looper.getMainLooper()); // 通过Handler的post Runnable到UI线程的MessageQueue中去即可 handler.post(new Runnable() @Override public void run() // 在MessageQueue出队该Runnable时进行的操作 mBinding.photo.setImageBitmap(bitmap); ); ).start(); break; case R.id.resetBtn: mBinding.photo.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.default_pic)); break; /*** * HttpUrlConnection加载图片,不多说 * @return */ public Bitmap loadPicFromInternet() Bitmap bitmap = null; int respondCode = 0; InputStream is = null; try URL url = new URL("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1421494343,3838991329&fm=23&gp=0.jpg"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(10 * 1000); connection.setReadTimeout(5 * 1000); connection.connect(); respondCode = connection.getResponseCode(); if (respondCode == 200) is = connection.getInputStream(); bitmap = BitmapFactory.decodeStream(is); catch (MalformedURLException e) e.printStackTrace(); Toast.makeText(getApplicationContext(), "访问失败", Toast.LENGTH_SHORT).show(); catch (IOException e) e.printStackTrace(); finally if (is != null) try is.close(); catch (IOException e) e.printStackTrace(); return bitmap;
以上是关于什么是Handler的主要内容,如果未能解决你的问题,请参考以下文章