
Android多线程与双缓冲
创建一个继承自Handler的子类,用于处理UI更新任务。 在新线程中发送具有特定标识符的消息。 在Handler中接收消息并调用View的invalidate()方法。
发布日期:2021-05-17 16:28:20
浏览次数:9
分类:精选文章
本文共 3440 字,大约阅读时间需要 11 分钟。
Android视图更新有多种方法,具体使用时要根据需求选择合适的方式。以下是几种常见的情况,帮助开发者更好地理解和使用。
1. 不使用多线程和双缓冲
这种情况最简单,也是最常用的。只需要在Activity中显式调用View对象的invalidate()方法,系统会自动触发View的onDraw()方法进行重绘。
优点:代码简单,容易实现。
缺点:当View内容频繁更新时,可能会由于线程 invalide() 在不同线程中导致UI更新异常。
示例代码:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView TextView = (TextView) findViewById(R.id.TextView); new Thread(new Runnable() { @Override public void run() { while (true) { TextView.invalidate(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}
2. 使用多线程但不使用双缓冲
这种情况需要在新线程中执行UI更新操作,但直接访问View对象会导致异常(CalledFromWrongThread)。
解决方法是使用Handler类进行消息传递和UI更新。具体步骤如下:
示例代码:
public class TimeViewHandler extends Handler { private TextView timeView; public TimeViewHandler(TextView timeView) { super(); this.timeView = timeView; } @Override public void handleMessage(Message msg) { if (msg.what == MSG_UPDATE) { timeView.setText(DateHelper.getNow("kk:mm:ss")); timeView.invalidate(); } super.handleMessage(msg); }}public class MainActivity extends Activity { private static final int MSG_UPDATE = 123; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView TextView = (TextView) findViewById(R.id.TextView); final TimeViewHandler handler = new TimeViewHandler(TextView); new Thread(new Runnable() { @Override public void run() { while (true) { handler.sendEmptyMessage(MSG_UPDATE); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}
3. 使用多线程和双缓冲
如果需要更高频率的UI更新而避免因多线程操作导致的性能问题,可以使用SurfaceView和双缓冲的组合。
SurfaceView是View的子类,同时实现了双缓冲功能。通过继承SurfaceHolder.Callback接口,可以在新线程中直接进行绘制操作,而无需通过Handler。
优点:支持高频率的渲染和动画效果,适合需要复杂图形操作的场景。
示例代码:
public class TouchDrawView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private TouchDrawListener listener; public TouchDrawView(Context context) { super(context); holder = getHolder(); holder.addCallback(this); listener = new TouchDrawListener(holder); listener.setShape(TouchDrawListener.SHAPE_LINE); listener.setShape_style(TouchDrawListener.SHAPE_STYLE_FILL); setOnClickListener(listener); setLongClickable(true); setFocusable(true); setFocusableInTouchMode(true); } @Override public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = holder.lockCanvas(null); canvas.drawColor(Color.WHITE); holder.unlockCanvasAndPost(canvas); }}
通过以上方法,开发者可以根据具体需求选择合适的View更新方式。在需要高频率更新或复杂图形处理时,可以选择多线程加双缓冲的方案;在简单场景中直接使用主线程的invalidate()方法即可满足需求。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年05月08日 15时51分21秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
centOS7.6安装nginx
2019-03-13
[python复习6]正则表达式
2019-03-13
Flask操作SQLAlchemy
2019-03-13
JavaScript和Java重要的相异点
2019-03-13
网络对抗技术-Exp2-后门原理与实践 20181314
2019-03-13
能解决数据可视化大屏需求的3款可视化工具
2019-03-13
欢迎来到小迪博客
2019-03-13
【Altium Designer21】工作栏中文解析
2019-03-13
[87]用secureCRT连接虚拟机中的Ubuntu系统,出现“远程主机拒绝连接”错误
2019-03-13
Shell脚本防DNS攻击检测并删除肉机IP
2019-03-13
如何在VSCode中定制JSON的IntelliSense
2019-03-13
椭圆曲线的定义
2019-03-13
多代理区块链框架客户端的操作
2019-03-13
RSA操作中的公钥和私钥的生成
2019-03-13
C#从1打印到100再打印到1-递归的应用
2019-03-13
go语言中类的继承和方法的使用
2019-03-13
Ubuntu 修改权限的操作
2019-03-13
caffe训练的时候遇到的text-format 错误解决方案。
2019-03-13
Java 8新特性(一):Lambda表达式
2019-03-13