深入Android架构(从线程到AIDL)_18 SurfaceView的UI多线程02

news2025/1/9 21:28:49

目录

2、 使用SurfaceView画2D图

范例一

设计GameLoop(把小线程移出来)

范例二


2、 使用SurfaceView画2D图

范例一
  • 以SurfaceView绘出Bitmap图像
  • 设计SpriteView类别来实作SurfaceHolder.Callback接口
  • 首先来看个简单的程序,显示出一个Bitmap图像。这个图像就构成Sprite动画的基本图形。这个图像如下:

   

// SpriteView.java
// ………
public class SpriteView implements SurfaceHolder.Callback{
    private SpriteThread sThread;
    private Paint paint;
    private Bitmap bm;
    public SpriteView(Bitmap bmp) { bm = bmp; }
    @Override public void surfaceCreated(SurfaceHolder holder) {
        sThread = new SpriteThread(holder, this);
        sThread.start();
    }

    @Override public void surfaceDestroyed(SurfaceHolder holder) {}
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {}
    protected void onDraw(Canvas canvas) {
    paint= new Paint();
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(bm, 10, 10, paint);
}

public class SpriteThread extends Thread{
    private SpriteView mView;
    private SurfaceHolder mHolder;
    private Canvas c;
    SpriteThread(SurfaceHolder h, SpriteView v){
        mHolder = h mView = v;
    }

    public void run(){
        try{
            c = mHolder.lockCanvas(null);
            synchronized (mHolder){
            mView.onDraw(c);
            }
        }finally{
            if(c!=null)
            mHolder.unlockCanvasAndPost(c);
        }
    }
}
设计GameLoop(把小线程移出来)

// SpriteView.java
// ……..
public class SpriteView implements SurfaceHolder.Callback{
    private SpriteThread sThread;
    private Paint paint;
    private Bitmap bm;
    public SpriteView(Bitmap bmp) { bm = bmp; }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        sThread = new SpriteThread(holder, this);
        sThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    { }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { }
    protected void onDraw(Canvas canvas) {
        paint= new Paint();
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(bm, 10, 10, paint);
    }
}

// SpriteThread.java
//……….
public class SpriteThread extends Thread {
    private SpriteView mView;
    private SurfaceHolder mHolder;
    private Canvas c;
    SpriteThread(SurfaceHolder h, SpriteView v){
        mHolder = h; mView = v;
    }

    public void run(){
        try{
            c = mHolder.lockCanvas(null);
            synchronized (mHolder){ mView.onDraw(c); }
        }finally{
            if(c!=null){ mHolder.unlockCanvasAndPost(c); }
        }
    }
}

// myActivity.java
// ……..
public class myActivity extends Activity implements OnClickListener {
    private SurfaceView sv = null;
    private Button ibtn;
    private Bitmap bm;
    private SpriteView spView;

    @Override 
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        sv = new SurfaceView(this);
        bm = BitmapFactory.decodeResource(
        getResources(), R.drawable.walk_elaine);
        spView = new SpriteView(bm);
        sv.getHolder().addCallback(spView);

        LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(200, 200);
        param.topMargin = 10; param.leftMargin = 10;
        layout.addView(sv, param);
        //----------------------------------------------
        ibtn = new Button(this); ibtn.setOnClickListener(this);
        ibtn.setText("Exit");
        ibtn.setBackgroundResource(R.drawable.gray);
        LinearLayout.LayoutParams param1 = new LinearLayout.LayoutParams(200, 65);
        param1.topMargin = 10; param1.leftMargin = 10;
        layout.addView(ibtn, param1);
        setContentView(layout);
    }
    public void onClick(View v) { finish(); }
}
范例二
  • 让图像在SurfaceView里旋转

         

  • 在MySurfaceView里定义一个DrawThread类,它诞生一个单独的线程来执行画图的任务。
  • 当主线程侦测到绘图画面(Surface)被开启时,就会诞生DrawThread对象,启动新线程去画图。
  • 一直到主要线程侦测到绘图画面被关闭时,就停此正在绘图的线程。
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private DrawThread mThread;
    MySurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        mHolder = holder;
        mThread = new DrawThread();
        mThread.start(); 
    }


    public void surfaceDestroyed(SurfaceHolder holder) {
        mThread.finish();
        mThread = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format,int w, int h) { }

    class DrawThread extends Thread {
        int degree = 36;
        boolean mFinished = false;
        DrawThread() { super(); }

        @Override public void run() {
            Bitmap bmp = BitmapFactory.decodeResource(getResources(),
            R.drawable.x_xxx);
            Matrix matrix;
            degree = 0;

            while(!mFinished){
                Paint paint = new Paint(); paint.setColor(Color.CYAN);
                Canvas cavans = mHolder.lockCanvas();
                cavans.drawCircle(80, 80, 45, paint);
                //------ rotate -----------------------------
                matrix = new Matrix(); matrix.postScale(1.5f, 1.5f);
                matrix.postRotate(degree);
                Bitmap newBmp= Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                bmp.getHeight(), matrix, true);
                cavans.drawBitmap(newBmp, 50, 50, paint);
                mHolder.unlockCanvasAndPost(cavans);
                degree += 15;
                try { Thread.sleep(100);
                } catch (Exception e) {}
            }
        }
        void finish(){ mFinished = true; }
    }
}

 

// ac01.java-
//……..
public class ac01 extends Activity {
    @Override protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        MySurfaceView mv = new MySurfaceView(this);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(200, 150);
        param.topMargin = 5;
        layout.addView(mv, param);
        setContentView(layout);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2274018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【FlutterDart】 拖动边界线改变列宽类似 vscode 那种拖动改变编辑框窗口大小(11 /100)

【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100) 【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果(12 /100) 上效果: 这个在知乎里找到的效果&…

tk GMV MAX素材范围投放指南

Product GMy Max素材范围说明 Product GMy Max能自动获取带有相关商品锚点链接(无论是单个锚点还是多个锚点)的视频,并将其用于推广特定商品的广告素材,前提是这些视频已经获得广告授权。然而,请注意,多个…

物联网无线芯片模组方案,设备智能化交互升级,ESP32-C3控制应用

无线交互技术的核心在于实现设备之间的无缝连接和数据传输。在智能家居系统中,各种智能设备如智能灯泡、智能插座、智能门锁等,都通过无线网络相互连接,形成一个互联互通的生态。 用户可以通过语音助手、手机APP或其他智能终端,远…

ubuntu为Docker配置代理

终端代理 我们平常在ubuntu终端中使用curl或git命令时,往往会很慢。 所以,首先需要给ubuntu终端环境添加代理。 查看自身那个软件的端口号,我这里是7890。 sudo gedit ~/.bashrcexport http_proxyhttp://localhost:7890 export https_pr…

【VUE 指令学习笔记】

v-bind :单向绑定解析表达式,可简写为:xxx v-model :双向数据绑定。 v-for:遍历数组/对象/字符串 v-on:绑定事件监听,可简写为。 v-if:条件渲染(动态控制节点是否存存在) v-else:条件渲染(动态控制节点是否存存在) v-show:条件渲染…

用OpenCV实现UVC视频分屏

分屏 OpencvUVC代码验证后话 用OpenCV实现UVC摄像头的视频分屏。 Opencv opencv里有很多视频图像的处理功能。 UVC Usb 视频类,免驱动的。视频流格式有MJPG和YUY2。MJPG是RGB三色通道的。要对三通道进行分屏显示。 代码 import cv2 import numpy as np video …

123.【C语言】数据结构之快速排序挖坑法和前后指针法

目录 1.挖坑法 执行流程 代码 运行结果 可读性好的代码 2.前后指针法(双指针法) 执行流程 单趟排序代码 将单趟排序代码改造后 写法1 简洁的写法 3.思考题 1.挖坑法 执行流程 "挖坑法"顾名思义:要有坑位,一开始将关键值放入临时变量key中,在数组中形成…

JavaFx 21 项目Markdown 预览、编辑、新建、文件树、删除、重命名

项目文件结构 项目的源代码和资源文件存放在以下路径: 源代码: src/main/java/com/kong/markdown/ 包含多个 Java 文件,主要实现了应用的功能: App.java:主类,可能包含应用的启动逻辑。FileService.java:可能与文件操作相关的服务类。MainController.java:控制器类,可…

jenkins入门6 --拉取代码

Jenkins代码拉取 需要的插件,缺少的安装下 新建一个item,选择freestyle project 源码管理配置如下:需要添加git库地址,和登录git的用户密码 配置好后执行编译,成功后拉取的代码在工作空间里

数学建模入门——建模流程

摘要:本文介绍了数学建模的一般流程概述。 目录 一、前言 二、数据预处理 三、描述性统计分析 四、模型建立 五、模型评价 一、前言 本文将为想要入门数学建模的同学讲述数学建模的一般流程。但数学建模流程并非一成不变。虽有大致步骤,像分析问题、…

《机器学习》集成学习之随机森林

目录 一、集成学习 1、简介 2、集成学习的代表 3、XGBoost和随机森林的对比 相同点: 不同点: 二、Bagging之随机森林 1、简介 2、随机森林的核心思想 3、随机森林生成步骤 4、随机森林的优点 5、随机森林的缺点 三、随机森林的代码实现 1、…

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章,讲解屏幕录制的使用。官方文档参见:使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二…

CSS——22.静态伪类(伪类是选择不同元素状态)

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>静态伪类</title> </head><body><a href"#">我爱学习</a></body> </html>单击链接前的样式 左键单击&#xff08;且…

JavaWeb开发(六)XML介绍

1. XML介绍 1.1. 什么是XML &#xff08;1&#xff09;XML 指可扩展标记语言(EXtensible Markup Language)XML 是一种很像HTML的标记语言。   &#xff08;2&#xff09;XML 的设计宗旨是传输数据(目前主要是作为配置文件)&#xff0c;而不是显示数据。   &#xff08;3&a…

攻防世界 bug

发现有Register界面&#xff0c;先去注册 登录以后发现以下界面&#xff0c;点击Manage显示you are not admin&#xff0c;并且在注册界面用admin为注册名时显示用户名已存在。初步推测是设法改变admin的密码取得权限。 在主界面一通操作并没有什么发现&#xff0c;去findpw…

maven依赖的配置和排除依赖

1.依赖的配置 1.1位置&#xff1a;写在<properties></properties>标签之下&#xff0c;<project></project>里。 1.2语法固定的格式 <dependencies><dependency></dependency></dependencies> 1.3在 <dependency><…

transformer深度学习实战CCTSDB中国交通标志识别

本文采用RT-DETR作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。RT-DETR以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对CCTSDB交通标志数据集进行训练和优化&#xff0c;该数据集包含丰富的CCTSDB交…

Elastic-Job相关

文档参考视频&#xff1a;09_SpringBoot案例演示_哔哩哔哩_bilibili 一、Elastic-Job介绍 Elastic-Job 是一个轻量级、分布式的任务调度框架&#xff0c;旨在解决分布式环境下的定时任务调度问题。 1.1. Elastic-Job 的核心组件 Elastic-Job 是由多个核心组件构成的&#x…

esp32开发笔记之一:esp32开发环境搭建vscode+ubuntu

最近想用esp32做一个物联网项目&#xff0c;踩坑N个终于有点心得&#xff0c;写下来避免和我一样的小白踩无谓的坑。 写在前面&#xff1a; 第一&#xff0c;大家一定要用linux系统作为编译工具&#xff0c;速度上是windows无法比的&#xff0c;不要因为不熟悉linux而选择win…

(七)人工智能进阶之人脸识别:从刷脸支付到智能安防的奥秘,小白都可以入手的MTCNN+Arcface网络

零、开篇趣谈 还记得第一次用支付宝"刷脸"时的新奇感吗&#xff1f;或者被抖音的人脸特效逗乐的瞬间&#xff1f;这些有趣的应用背后&#xff0c;其实藏着一个精妙的AI世界。今天&#xff0c;就让我们开启一段奇妙的人脸识别技术探索之旅吧&#xff01; 一、人脸识…