博客
关于我
Android多线程与双缓冲
阅读量:626 次
发布时间:2019-03-14

本文共 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更新。具体步骤如下:

  • 创建一个继承自Handler的子类,用于处理UI更新任务。
  • 在新线程中发送具有特定标识符的消息。
  • 在Handler中接收消息并调用View的invalidate()方法。
  • 示例代码:

    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()方法即可满足需求。

    转载地址:http://deroz.baihongyu.com/

    你可能感兴趣的文章
    could not initialize proxy - no Session (SSH)
    查看>>
    cmd编译.java文件 : java:720: 错误: 编码GBK的不可映射字符 Why ? ? ? ?
    查看>>
    【Jquery】获取当前窗口的宽度值/高度值
    查看>>
    Android 架构组件 – 让天下没有难做的 App
    查看>>
    启动MongoDB出现1053错误
    查看>>
    Gym 102770 B-Bin Packing Problem 2020浙江省省赛 (线段树 + set)
    查看>>
    centOS7.6安装nginx
    查看>>
    [python复习6]正则表达式
    查看>>
    Flask操作SQLAlchemy
    查看>>
    JavaScript和Java重要的相异点
    查看>>
    网络对抗技术-Exp2-后门原理与实践 20181314
    查看>>
    能解决数据可视化大屏需求的3款可视化工具
    查看>>
    欢迎来到小迪博客
    查看>>
    【Altium Designer21】工作栏中文解析
    查看>>
    [87]用secureCRT连接虚拟机中的Ubuntu系统,出现“远程主机拒绝连接”错误
    查看>>
    [206]如何解决python升级后yum报错
    查看>>
    Shell脚本防DNS攻击检测并删除肉机IP
    查看>>
    如何在VSCode中定制JSON的IntelliSense
    查看>>
    椭圆曲线的定义
    查看>>
    多代理区块链框架客户端的操作
    查看>>