Android中使用Handler&Looper更新UI范例
来源:互联网 发布:淘宝图片护盾哪里查看 编辑:程序博客网 时间:2024/05/16 23:35
5年前在学校错过一次Android,等到现在才开始补救。但愿还不晚。
本文以一个更新UI的例子来讲述Looper和Handler如何配合使用。
本文所写范例仅供研究、学习之用,不喜勿喷,敬请谅解!
UI目标:
1. 用户滑动seekBar至任意值(例如X%),然后点击UPDATE按钮,等待2s后progressBar更新到seekBar的相同值X%,底部editText_log中显示出“set progress=X”的日志。
多线程设计
据说,不可以做任何阻塞UI的工作!
本文设计一共两个线程:UI线程 + Looper线程。
两个线程的职责分别是:
UI线程:UI启动、处理UI消息、更新UI。
Looper线程:处理耗时2s的复杂任务,处理完毕后返回消息给UI线程。
本文设计了两个Handler,分别是:MainHandler + LooperHandler。
两个Handler的职责分别是:
MainHandler:
1. 由Looper线程调用,发送更新UI的消息到UI线程;
2. 由UI线程处理Message时被调用处理UI更新的Message,更新UI。
LooperHandler:
1. 由UI线程调用,发送处理任务的消息给Looper线程;
2. 在Looper线程中调用,处理从UI线程发来的耗时任务。
两个线程的时序图如下所示:
部分实现代码如下:
package com.frank.simplehandler_0611;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.EditText;import android.widget.ProgressBar;import android.widget.SeekBar;public class MainActivity extends AppCompatActivity { private static final String TAG = "SimpleHandler_0611"; public static class MyLooperHandler extends Handler { private MainHandler mMainHandler = null; private static final int MSG_SET_PROGRESS = 0; public MyLooperHandler(Looper looper, MainHandler mainHandler) { super(looper); mMainHandler = mainHandler; } /**** * handleMessage called in LooperThread. * * @param msg message object. */ @Override public void handleMessage(Message msg) { if (msg.what == MSG_SET_PROGRESS) { Log.d(TAG, "MyLooperHandler.handleMessage msg.what=" + msg.what + " arg1=" + msg.arg1); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } mMainHandler.updateProgress(msg.arg1); } } /*** * setProgress called in Main Thread. * * @param arg0 new seek bar value. */ public void setProgress(int arg0) { Log.d(TAG, "MyLooperHandler.setProgress arg0=" + arg0); Message msg = Message.obtain(); msg.what = MSG_SET_PROGRESS; msg.arg1 = arg0; sendMessage(msg); } } public class MainHandler extends Handler { public static final int MSG_SET_PROGRESS_MAIN = 1; public MainHandler(Looper looper) { super(looper); } /*** * handleMessage called in UI thread * * @param msg */ @Override public void handleMessage(Message msg) { if (msg.what == MSG_SET_PROGRESS_MAIN) { int prg = msg.arg1; String content = (String) msg.obj; Log.d(TAG, "MainHandler.handleMessage msg.what=" + msg.what + " progress=" + prg + " content=" + content); if (progressBar_01 != null) { progressBar_01.setProgress(prg); } if (editText_log != null) { editText_log.append(content); } } } /*** * updateProgress called in MyLooperThread * This message is send to Main Thread for UI update * * @param arg */ public void updateProgress(int arg) { Log.d(TAG, "MainHandler.updateProgress arg=" + arg); Message msg = Message.obtain(); msg.what = MSG_SET_PROGRESS_MAIN; msg.arg1 = arg; msg.obj = String.format("set progress=%d", arg); sendMessage(msg); } } MyLooperHandler myLooperHandler = null; MainHandler mainHandler = null; EditText editText_log = null; SeekBar seekBar_01 = null; ProgressBar progressBar_01 = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "MainActivity.onCreate UI thread running..."); // UI components initialize editText_log = (EditText) findViewById(R.id.editText_log); seekBar_01 = (SeekBar) findViewById(R.id.seekBar_01); progressBar_01 = (ProgressBar) findViewById(R.id.progressBar_01); findViewById(R.id.button_action).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (seekBar_01 != null) { int prg = seekBar_01.getProgress(); if (myLooperHandler != null) { Log.d(TAG, "MainActivity.onCreate.button_action.onClick prg=" + prg); myLooperHandler.setProgress(prg); } } } }); MyLooperThread myLooperThread = new MyLooperThread("Worker"); myLooperThread.start(); mainHandler = new MainHandler(getMainLooper()); myLooperHandler = new MyLooperHandler(myLooperThread.getLooper(), mainHandler); }}
代码工程详见:
https://github.com/wangqunfeng/AndroidDemos/tree/master/apps/SimpleHandler_0611
阅读全文
0 0
- Android中使用Handler&Looper更新UI范例
- Android使用线程更新UI----Thread、Handler、Looper、TimerTask等
- Android UI应用之 UI更新使用Thread、Handler、Looper、TimerTask
- Android--Android中更新UI的线程:Thread 、Handler、Looper、TimerTask
- Android--Android中更新UI的线程:Thread 、Handler、Looper、TimerTask
- [Android基础知识] 之十五: Android中更新UI的线程:Thread 、Handler、Looper、TimerTask等
- (转)Android中更新UI的线程:Thread 、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- 内存优化-java四种引用,让你能更好的构建你的项目
- 免费搭建个人技术博客 Github and Hexo
- Android 限制EditText只能输入数字、限制输入类型、限制输入长度的小技巧
- 舞步学院图形界面设计代码
- 自定义ViewGroup实现循环轮播ViewPager
- Android中使用Handler&Looper更新UI范例
- 软件的坐标系
- 依据TFTP协议的服务端和客户端
- Python爬虫实例--爬取百度贴吧小说
- Ubuntu-修改用户的默认目录
- 【cmd】cmd怎么到达指定的文件夹
- git常见问题
- 读取MBTiles数据库里的图片
- Ubuntu-忘记密码后进入单用户模式强制修改密码