Android初级开发----用Handle机制更新UI界面
来源:互联网 发布:mac 不能打开u盘 编辑:程序博客网 时间:2024/05/18 02:32
- 引入:
之前对Android讲义的一个小项目——–随指尖移动的小球进行修改,利用View中的invalidate()方法实现每次触碰屏幕更新(UI线程)小球的位置并且附加判断大小,实现触碰更新小球大小随之更改颜色.
API引入:
每次执行invalidate()方法都会调用ondraw()
ondraw()用于刷新界面此处为canvas(画布)
2. 简单源码:
变色小球1.0
新建一个DrawView类继承View
package com.example.drawview_without_thread;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.Button;public class DrawView extends View{ public float currentX = 200; //球起始位置 public float currentY = 500;// String touchsign = "Never touch"; boolean range = true; //大小判断标记 Paint p = new Paint(); //画笔 public DrawView(Context context) { //构造函数1 直接定义视图 //final DrawView draw = new DrawView(this); super(context); } public DrawView(Context context,AttributeSet set) { //构造函数2 传入AttributeSet set在布局文件xml中加载属性 super(context,set); } int [] colors = new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.YELLOW, }; int size = 10; //初始半径10 static int colornum = 0; //大小,颜色下标序号 @Override public void onDraw(Canvas canvas){ //canvas 画布 super.onDraw(canvas); if (size >= 350) { range = false; //大小判断 }if(size <= 20) { range = true; } //半径视情况 改变 if (range) { size += 15; Log.d("DrawTest", "半径递增:"+ size ); } else { size -= 15; Log.d("DrawTest", "半径递减:"+ size ); } colornum = ++colornum % colors.length; //每次触碰滚动换色 p.setColor(colors[colornum]); Log.d("Color", "新画笔颜色"+colornum); //设置位置,大小,颜色 canvas.drawCircle(currentX, currentY, size, p); //设置点的半径和位置 } @Override //touch reaction public boolean onTouchEvent(MotionEvent event){ currentX = event.getX(); currentY = event.getY(); //touchsign = "touched"; //改变表示已经触碰 invalidate(); //用来刷新View,系统会自动回调 View的onDraw()方法// 只要是view的子类,都会从view中继承invalidate和postInvalidate这两个方法。//// 当invalidate方法被调用的时候,就是在告诉系统,当前的view发生改变,应该尽可能快的来进行重绘。//// 这个方法仅能在UI(主)线程中被调用。如果想要在工作线程中进行刷新界面,那么其他的方法将会被调用,这个方法就是postInvalidate方法。 return true; }}
为了让每次点击都改变小球位置,通过一个颜色数组colors来获取当前周期性改变的颜色,于是我想为什么不额外创建一个线程实现改变颜色呢?
问题引入:
Android制订了一条规则:它只允许(主)User Interface线程修改Activity里的UI组件,当程序第一次启动,Main Thread主要负责处理与UI相关的事件,如按钮和用户屏幕点击事件.
- 引用Handler类
官方文档解释
Handler
A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it – from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Handler : 解决,处理.这里可以理解为消息处理器.
大概的意思是,一个Handler可以让你发送消息,这个消息会推入MessageQueue(消息队列)里等待处理. - MessageQueue管家——–Looper
Looper类中的loop()方法会不断的取出消息队列的Message发送给Handler,并且将Message传递给Handler的handleMessage()方法中. - handleMessage() 常用结构:
大概流程可以参考此图:
final Handler handler = new Handler() { @Override public void handleMessage(Message msg) //接受通过Looper从MessageQueue队列提取对应发送过来的消息. { if (msg.what == 0x123) { //新线程要做的事... } super.handleMessage(msg); } }; // 激发事件 @Override public void run() { Log.d("Sent", "向处理器发送消息"); handler.sendEmptyMessage(0x123); } }).start();
通过对msg的判断新消息是否符合该处理操作,如果符合则对应处理.
所以利用额外的一个线程实现周期性改变,如今不用每次点击屏幕只要启动线程就会在原地周期改变颜色.注意的是,我们不是新建一个线程来改变UI界面,而是新建一个线程来发送消息给Handler,让位于主线程的Handler更新界面
变色小球2.0
修改DrawView的部分代码,并且在MainActivity新建Handler处理器,相关代码如下:
修改DrawView:
@Override public void onDraw(Canvas canvas){ //canvas 画布 super.onDraw(canvas); if (size >= 350) { range = false; //大小判断 }if(size <= 20) { range = true; } //半径视情况 改变 if (range) { size += 15; Log.d("DrawTest", "半径递增:"+ size ); } else { size -= 15; Log.d("DrawTest", "半径递减:"+ size ); } Log.d("Color", "新画笔颜色"+colornum); //设置位置,大小,颜色 canvas.drawCircle(currentX, currentY, size, p); //设置点的半径和位置 } public void thread_change() {//通过UI线程的handler来调用 colornum = ++colornum % colors.length; //周期性滚动换色 p.setColor(colors[colornum]); Log.d("DrawTest", "新线程重设画笔颜色"); invalidate(); //加入了原地更新界面的方法 }
修改MainActivity:
加入Handler
//处理器 final Handler handler = new Handler() { @Override public void handleMessage(Message msg) //接受通过Looper从MessageQueue队列提取对应发送过来的消息. { if (msg.what == 0x123) { draw.thread_change(); } super.handleMessage(msg); } }; //按钮 Button shine = (Button)findViewById(R.id.shine); shine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Log.d("DrawTest", "点击按钮"); new Timer().schedule(new TimerTask() { @Override public void run() { Log.d("DrawTest", "向处理器发送消息"); handler.sendEmptyMessage(0x123); } }, 0, 500); //新线程用timer周期性的向handler发送消息,此处也可以通过start()来启动新线程 } });
此时handleMessage()就是在主线程运行的,所以可以进行UI操作.
参考来源:<疯狂android讲义>p208,<第一行代码>p348
0 0
- Android初级开发----用Handle机制更新UI界面
- 用handle更新ui
- android 运用Message机制更新UI线程界面
- android异步更新UI界面
- android线程更新UI界面
- Android Adapter,UI界面更新
- Android异步机制一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步机制一:使用Thread+Handler实现非UI线程更新UI界面
- Android——使用Handle和Message更新UI控件
- android 在线程中调用handle更新UI
- Android 子线程更新UI:handle和runOnUiThread()
- 发送 handle 消息 更新UI
- Android handle机制
- 浅析Android Handle机制
- Android中handle机制
- Android消息机制---handle
- Android Handle机制浅析
- Android Handle机制
- Android 事件分发
- ubuntu权限操作授予
- 在Linux下安装Docker
- Java中的Process,执行一个命令
- Java单链表接本操作(三)--删除当前节点
- Android初级开发----用Handle机制更新UI界面
- 第1周 《C语言及程序设计》实践项目1——指针及其运算
- 欲望与产品
- ssh框架整合配置
- 欢迎使用CSDN-markdown编辑器
- 深入理解C++的动态绑定和静态绑定
- Ubuntu下安装arm-linux-gnueabi-xxx编译器
- uva11090Going in Cycle!!(最短路spfa)
- iOS———如何申请苹果公司开发者账号流程详细图文介绍(含邓白氏编码的申请方法详细介绍)