Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 631|回复: 0

[实例教程]Android技巧之-SurfaceFlinger绘图与输入法开关

[复制链接]

该用户从未签到

发表于 2011-10-22 12:41:20 | 显示全部楼层 |阅读模式
SurfaceFligner是Android画形化的核心,网上有几篇关于这个C/S系统的分析,着实不错,我在文章最后的参考文章中都列出来 了,大家可以先看一下那些文章从原理上对SurfaceFlinger系统的分析再看我这篇文章。我这篇文章偏重于具体代码上的实现,最后汇总成一个小的 应用程序来演示如何与SurfaceFlinger交互,例子中使用的2D图形引擎。

源码在这里:http://code.google.com/p/flying-on-android/

使用的SurfaceFlinger系统可以分为这么几步:建立连接、创建Surface、取得Canvas、绘制、提交Canvas。下面来具体分析一下

1、建立连接

这个比较简单,先把示例代码贴上来 session = new SurfaceComposerClient;
代码很简单,具体SurfaceComposerClient如何通过IBinder与SurfaceFlinger通信比较复杂,可以本文后面列出的“参考文章“当中其它作者的分析。

2、创建Surface

java层,View树最后是绘制在Surface上面的,一个Surface对应了SurfaceFlinger中的一个Layer。我们要绘 画,必须先取得一个Surface并在上面画东西,画完了通过session向SurfaceFlinger一提交,就显示在屏幕上了。

呵。。。似乎只要涉及到代码,都很简单了。 surfaceControl = session->createSurface(getpid(), 0, display.w, display.h,



PIXEL_FORMAT_RGBA_8888);
surfaceControl用来控制Surface属性。 surface = surfaceControl->getSurface();
surface才代表真正的Surface。

3、取得Canvas

用程序绘制UI,其实就是借助图形引擎提供的点、线、面函数最后形成一个包含像素信息的数组并提交给图形驱动(Linux上是 FrameBuffer)的过程。现在我们拥有一个Surface,那么就可以取得Surface属性信息并把这些信息提供给图形引擎(这里是 skia),图形引擎根据这些信息就可以构造出一张Bitmap的形式提供给我们。我们拿到Bitmap是不可以直接在上面绘画的,还需要把它包装成 Canvas。这样,我们调用Canvas的绘画API时,最终改变了Bitmap的内容。Bitmap的数据都存储在一个二维数组中,每个数组的元素代 表了一个像素值。看一下关键代码 surface->lock(&info, &dirtyRegion);//获取Surface属性信息到info当中



bitmap.setPixels(info.bits);//构造Bitmap



canvas.setBitmapDevice(bitmap);//把Bitmap封装成Canvas
4、绘制

Canvas构造好了,就可以调用drawLine,drawColor等进行绘制了。这里我们做的很简单,只是把整个Canvas渲染成黑色。 canvas->drawColor(0xff000000);
5、提交Canvas

提交过程,实际上就是把Bitmap中的像素数组通过Surface传递给服务端SurfaceFlinger中与我们拥有的这个Surface对应的Layer,并告诉SurfaceFlinger把它渲染到屏幕。一句代码就可以搞定了。 surface->unlockCanvasAndPost();
我自己学习工作时,深刻体会到十篇讲原理的不如一段演示代码来的实在,就把这个过程写成了一个可以编译运行的小程序放到了这里:

如何你对这个话题比较感兴趣,可以把例子下载下来一边看代码一边看这篇文章。只要把它放到/frameworks/base/cmds目录下,然后 切换到这个模块下运行mm命令,会自动编译成一个名字为flying的程序安装到/system/bin,只要把它复制出来放到机器的/system /bin目录下,然后在通过Shell运行就可以了。我是在Android2.3下面完成的,其它的系统版本没有试过。

如果只要看效果的话,资源中也包含可执行文件,直接把它复制到/system/bin下面运行即可。

如何打开和关闭输入法

一、打开输入法窗口: InputMethodManager inputMethodManager = (InputMethodManager)            

getSystemService(Context.INPUT_METHOD_SERVICE);



// 接受软键盘输入的编辑文本或其它视图



imm.showSoftInput(submitBt,InputMethodManager.SHOW_FORCED);
二、关闭出入法窗口 InputMethodManager inputMethodManager = (InputMethodManager)            

getSystemService(Context.INPUT_METHOD_SERVICE);

inputMethodManager.hideSoftInputFromWindow(OpeListActivity.this.getCurrentFocus().getWindowTok

InputMethodManager.HIDE_NOT_ALWAYS);

//接受软键盘输入的编辑文本或其它视图

inputMethodManager

.showSoftInput(submitBt,InputMethodManager.SHOW_FORCED);
三、如果输入法打开则关闭,如果没打开则打开 InputMethodManager m=(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);



m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
四、获取输入法打开的状态 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

boolean isOpen=imm.isActive();
isOpen若返回true,则表示输入法打开

好了先介绍这两个技巧。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-22 16:57 , Processed in 0.386904 second(s), 46 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表