Android 深入系统完全讲解(19)

news2024/12/23 5:34:57

技术的学习关键点

是什么?思路。
而我这里分享一个学习的经典路线,先厘清总框架,找到思路,然后再逐步击破。
这里关于音视频的就是:
总体分为几部分:
1 绘制
2 编解码格式
3 Android 平台的 FFmpeg 开源移植
4 应用场景
概括成一句话就是,视频如果解析出来,视频如何显示画面,声音怎么播放。
然后这里面的
市场机会
在哪里?
1 支持格式扩展
2 特效画面 gpuimage 框架
3 倍速播放
4 格式转化,自动制作工具
5 移植到嵌入式板子
那么我们第二版就来完成这个任务,首先我们先说一个,就是绘制。

绘制流程(图)
市面上讲解绘制,直接上来一堆内容,我这里先忽略掉细节,我们来说下简单的绘制代表什
么。
我们自己画东西的时候,需要画笔,画板(画布),然后有各种涂料。

在安卓里面,这里画板就是 Canvas ,而画笔就是对应的各种 API。
那么接下来我们说下,这 Canvas 的简单逻辑,让你一目了然。
我们画的东西,叫做一个内存,叫做 FrameBuffer,这个有时候是双缓存。
然后我们每个 Activity 创建的时候,都会申请一个 Surface ,这个被叫做 平面,然后这个对
应到一个 Buffer,这一组由 Activity 或者是系统对话框,系统中使用 WMS.addView 添加进来
的 Buffer 组合。
依据层叠关系放置,而 SurfaceFlinger 这边会完成所谓的合并,绘制,推送到真正的屏幕
FrameBuffer,完成显示。
我来给大家发画一张图,大家大致看一下,形成印象。

在这里插入图片描述
我们这里记住的点就是:我们 View 绘制是在一个 canvas 里面,而这个里面是一个 surface,
这个说白了就是一个内存区域,用 surface 包裹方便操作。
于是我们来进行调试,看下流程,以及记住几个文件,方便我们学习。

在这里插入图片描述
我们调试一个 TextView 的 OnDraw 方法,然后可以看到一个信息,ViewRootImpl.java

在这里插入图片描述
这里分享的调试技巧,通过堆栈,能够非常高效的定位到代码,找到流程,参考这个很快就
能把绘制流程分析完。
这个绘制流程,是普通的 surface ,对应上层为 canvas 的绘制。一般我们不会在游戏使用,
原因很简单,这个主线程(UI)线程,在游戏引擎中,游戏频繁更新,绘制很容易耗时,所
以需要单独的线程。
而安卓这里提供了 surfaceView 以及 textureView,这里我们看下 surfaceView 的使用:
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surface);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
return;} Paint paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); Canvas canvas = surfaceHolder.lockCanvas(); // 获取 canvas //canvas.drawBitmap(bitmap, 0, 0, paint); //执行绘制操作 surfaceHolder.unlockCanvasAndPost(canvas); // 释放并显示 } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { } 我们看个常用的使用方式: //内部类 class MyView extends SurfaceView implements SurfaceHolder.Callback{ SurfaceHolder holder; public MyView(Context context) { super(context); holder = this.getHolder();//获取 holder holder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(new MyThread()).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } //内部类的内部类 class MyThread implements Runnable{
@Override
public void run() {
Canvas canvas = holder.lockCanvas(null);//获取画布
Paint mPaint = new Paint();
mPaint.setColor(Color.BLUE);
canvas.drawRect(new RectF(40,60,80,80), mPaint);
holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
}
}
}

从这里流程可以看到,关键点在于这个 holder 。这里整体的流程就是:
使用
holder = this.getHolder();//获取 holder
holder.addCallback(this);
完成获取 holder ,以及注册回调。
然后在 surfaceCreated 里面,完成创建线程,随后在线程里面,获取 canvas,绘制,然后释
放。

在游戏引擎里面,这里就是自己的一个线程,调入游戏引擎中去,完成游戏引擎的核心入口。
我们在学习的时候,一定要找这里的关键方法,也就是所谓的线索。在 surfaceView 的开发
中,这个 holder 就是引子。
下来我们说下,用 surfaceView+OpenGL 如何操作。

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

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

相关文章

Compressed Sensing——从零开始压缩感知

Problem 考虑一个线性方程组求解问题: Axb(1)A x b \tag{1}Axb(1) 其中,A∈RmnA \in\mathbb R^{m\times n}A∈Rmn,x∈Rn1x \in\mathbb R^{n\times 1}x∈Rn1,b∈Rm1b \in\mathbb R^{m\times 1}b∈Rm1且m≪nm \ll nm≪n 这是一个…

【C++11】—— lambda表达式

目录 一、lambda表达式的简介 二、lambda表达式的基本语法 三、lambda表达式的使用方法 四、lambda表达式的底层原理 一、lambda表达式的简介 lambda表达式就类似于仿函数,相比仿函数要更加的简洁,我们看一下下面的代码: //商品类 struct…

【项目实战】使用MybatisPlus乐观锁插件功能

一、背景 当要更新一条记录时,希望这条记录没有被别人更新,可以考虑使用MybatisPlus乐观锁插件功能来实现以上需求。 二、乐观锁介绍 2.1 乐观锁是什么? 乐观锁是一种乐观思想,即认为读多写少,遇到并发的可能性低&…

使用ASM框架创建ClassVisitor时遇到IllegalArgumentException的一种可能解决办法

背景 ASM是java语言中最为广泛使用的插装框架,其优点在于可以动态地在运行时改变java系统的行为,加入我们自己的逻辑。在软件测试领域应用广泛。但是其使用难度很高,一方面使用asm框架需要对java底层知识有较高的了解,另一方面网…

网页共享电脑屏幕与播放(带声音)

这次项目我们是写的一个课堂辅助软件的网页版,其中有一个功能感觉能作为我们项目的一个亮点,就是直播功能,在之前并没有写过这个东西。虽然现在这个功能还不知道怎么写,但是它的流程终归是利用视频流将本地的视频给共享出去&#…

Verilog:【8】基于FPGA实现SD NAND FLASH的SPI协议读写

碎碎念: 终于熬过了期末周,可以开始快乐的开发之旅了。 这一期作为一千粉后的首篇博客,由于之后项目会涉及到相关的部分,因此介绍的是使用FPGA实现SD NAND FLASH的读写操作,以雷龙科技提供的SD NAND FLASH样品为例&…

实证分析权重系数计算大全

在实际研究中,权重计算是一种常见的分析方法,需要结合数据的特征情况进行选择,比如数据之间的波动性是一种信息量,那么可考虑使用CRITIC权重法或信息量权重法;也或者专家打分数据,那么可使用AHP层次法或优序…

直观感受PromQL及其数据类型

由于PromQL内容较多,将内容分为三篇文章讲述: 一、直观感受PromQL及其数据类型 二、PromQL之选择器和运算符 三、PromQL之函数 想必都知道要使用Msql,必须会用SQL,同样要使用Prometheus 就要掌握PromQL(Prometheus Que…

【链表】leetcode142.环形链表II(C/C++/Java/Js)

leetcode142.环形链表II1 题目2 思路2.1 判断链表是否有环--快慢指针法2.2 如果有环,如何找到这个环的入口2.3 补充3 代码3.1 C版本3.2 C版本3.3 Java版本3.4 JavaScript版本4 总结1 题目 题源链接 给定一个链表的头节点 head ,返回链表开始入环的第一个…

软测复习05:基于质量特征的测试

作者:非妃是公主 专栏:《软件测试》 个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩 文章目录性能测试压力测试容量测试健壮性测试安全性测试可靠性测试恢复性测试协议一致性测试兼容性测试安装…

【数据结构】保姆级单链表教程(概念、分类与实现)

目录 🍊前言🍊: 🍈一、链表概述🍈: 1.链表的概念及结构: 2.链表存在的意义: 🍓二、链表的分类🍓: 🥝三、单链表的实现&#x1f…

​盘点几款国内外安全稳定的域名解析平台​

众所周知,有了域名后想建站使用,必须要先解析域名。域名使用注册商一般会提供域名解析服务,这虽然为用户提供了方便,但功能大多有限,使用第三方域名解析平台就成了非常必要的选择。今天,小编就为大家盘点几…

计算机视觉OpenCv学习系列:第四部分、键盘+鼠标响应操作

第四部分、键盘鼠标响应操作第一节、键盘响应操作1.键盘响应事件2.键盘响应3.代码练习与测试第二节、鼠标操作与响应1.鼠标事件与回调2.鼠标操作3.代码练习与测试学习参考第一节、键盘响应操作 键盘响应中有一个函数叫做waitKey,所有的获取键盘键值都是通过waitKey…

【经典笔试题】动态内存管理

test1:void GetMemory(char* p) {p (char*)malloc(100); } void Test(void) {char* str NULL;GetMemory(str);strcpy(str, "hello world");printf(str); }int main() {Test();return 0; }请问执行上面代码,会出现什么结果?解析&a…

7. R语言【独立性检验】:卡方独立性检验、Fisher精确检验 、Cochran-Mantel-Haenszel检验

文章目录1. 卡方检验2. 费希尔精确检验(Fisher Exact Test)3. Cochran-Mantel-Haenszel检验独立性检验:用来判断变量之间相关性的方法,如果两个变量彼此独立,那么两者统计上就是不相关的 1. 卡方检验 可以使用chisq.…

Java面向对象之多态、内部类、常用API

目录面向对象之三大特性之三:多态多态的概述、多态的形式多态的好处多态下引用数据类型的类型转换多态的综合案例内部类内部类概述内部类之一:静态内部类内部类之二:成员内部类内部类之三:局部内部类内部类之四:匿名内…

JavaSE与网络面试题

大佬的: https://github.com/Snailclimb/JavaGuide https://osjobs.net/topk/all/ 自增自减 要点: 赋值 ,最后计算 右边的从左到右加载值,一次压入操作数栈 实际先算哪个看运算符的优先级 自增、自减操作都是直接修改变量…

SpringCloud面试题

为什么需要学习Spring Cloud 不论是商业应用还是用户应用,在业务初期都很简单,我们通常会把它实现为单体结构的应用。但是,随着业务逐渐发展,产品思想会变得越来越复杂,单体结构的应用也会越来越复杂。这就会给应用带…

带你走入虚函数和多态的世界(c++)

1、什么是虚函数 C类中用virtual修饰的函数叫做虚函数&#xff0c;构造函数没有虚构造函数&#xff0c;存在虚析构函数&#xff0c;C所有虚函数都是一个指针去存储的&#xff0c;所以具有虚函数的类&#xff0c;内存会增加一个指针大小的内存 #include<iostream> #includ…

第一章:计算机网络概述

一、计算机网络基本概念 1、什么是计算机网路&#xff1f; 计算机网络是通信技术与计算机技术紧密结合的产物。计算机网络就是一种特殊的通信网络&#xff0c;其特别之处就是&#xff0c;其信源和信宿通常就是我们所说的计算机&#xff0c;发出的信息通常就是数字化的一些信息…