热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用AndroidNDK以及OpenGLES开发动态壁纸

nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd

本文是一个Android动态壁纸的例子,利用android_ndk调用底层的C++代码,使用OpenGLES来绘制动态壁纸。仅作参考。

首先是定义我们自己的Renderer类,FireWallpaperRenderer实现了GLWallpaperService.Renderer接口(GLWallpaperService的代码在《Android利用OpenGLES开发动态壁纸用到的GLWallpaperService类》的那篇文章里):

 
  1. import java.io.IOException;  
  2. import java.io.InputStream;  
  3.   
  4. import javax.microedition.khronos.egl.EGLConfig;  
  5. import javax.microedition.khronos.opengles.GL10;  
  6. import android.content.Context;  
  7. import android.graphics.Bitmap;  
  8. import android.graphics.BitmapFactory;  
  9. import android.opengl.GLUtils;  
  10. import android.util.Log;  
  11.   
  12. public class FireWallpaperRenderer implements GLWallpaperService.Renderer {  
  13.     //用于纹理映射的绑定,并把绑定后的地址传递给C++代码,供其调用   
  14.     private int[] texture = new int[2];  
  15.     //用于加载Bitmap的context   
  16.     private Context mContext;  
  17.       
  18.     //FireWallpaperRenderer构造函数,用来初始化mContext   
  19.     public FireWallpaperRenderer(Context context){  
  20.         mContext = context;  
  21.     }  
  22.       
  23.     /** 
  24.      * 渲染场景的代码,这里我们是通过调用底层C++的代码来实现的, 
  25.      * 这样能得到更好地运行速度 
  26.      * */  
  27.     @Override  
  28.     public void onDrawFrame(GL10 gl) {  
  29.         //调用本地onDrawFrame方法   
  30.         FireNativeMethod.onDrawFrame(gl);  
  31.     }  
  32.       
  33.       
  34.     /** 
  35.      * 处理屏幕尺寸发生变化时的代码, 
  36.      * 用来重新设置场景的大小和其他一些属性, 
  37.      * 也是通过调用底层C++代码来实现 
  38.      * */  
  39.     @Override  
  40.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  41.         //调用本地onSurfaceChanged方法   
  42.         FireNativeMethod.onSurfaceChanged(gl, width, height);  
  43.     }  
  44.   
  45.     /** 
  46.      * 初始化OpenGL场景, 
  47.      * 用来设置场景的一些属性, 
  48.      * 也是通过调用底层C++代码来实现 
  49.      * */  
  50.     @Override  
  51.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  52.         //用来绑定Bitmap纹理   
  53.         bindTexture(gl, mContext);  
  54.         //调用本地setTexture方法,把纹理绑定的地址传递给C++代码,以供其调用   
  55.         FireNativeMethod.setTexture(texture);  
  56.         //调用本地onSurfaceCreated方法   
  57.         FireNativeMethod.onSurfaceCreated(gl, config);  
  58.   
  59.     }  
  60.       
  61.     /** 
  62.      * 用来绑定Bitmap纹理的代码, 
  63.      * 因为暂时没有找到在C++代码中绑定Bitmap纹理的方法, 
  64.      * 所以暂且在java层绑定Bitmap纹理 
  65.      * */  
  66.   
  67.     private void bindTexture(GL10 gl, Context context) {  
  68.         //生成纹理   
  69.         gl.glGenTextures(2, texture, 0);  
  70.         //加载Bitmap   
  71.         Bitmap bitmap = loadBitmap(context, R.drawable.floor);  
  72.         if (bitmap != null) {  
  73.             Log.i("firewallpaperrenderer""bind the floor texture");  
  74.             //如果bitmap加载成功,则生成此bitmap的纹理映射   
  75.             gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);  
  76.             //设置纹理映射的属性   
  77.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,  
  78.                     GL10.GL_NEAREST);  
  79.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,  
  80.                     GL10.GL_NEAREST);  
  81.             //生成纹理映射   
  82.             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  
  83.             //释放bitmap资源   
  84.             bitmap.recycle();  
  85.         }  
  86.         bitmap = loadBitmap(context, R.drawable.fire);  
  87.         if (bitmap != null) {  
  88.             //同上   
  89.             Log.i("firewallpaperrenderer""bind the fire texture");  
  90.             gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);  
  91.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,  
  92.                     GL10.GL_NEAREST);  
  93.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,  
  94.                     GL10.GL_NEAREST);  
  95.             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  
  96.             bitmap.recycle();  
  97.         }  
  98.   
  99.     }  
  100.   
  101.     /** 
  102.      * 加载Bitmap的方法, 
  103.      * 用来从res中加载Bitmap资源 
  104.      * */  
  105.     private Bitmap loadBitmap(Context context, int resourceId) {  
  106.         InputStream is = context.getResources().openRawResource(resourceId);  
  107.         Bitmap bitmap = null;  
  108.         try {  
  109.   
  110.             // 利用BitmapFactory生成Bitmap   
  111.             bitmap = BitmapFactory.decodeStream(is);  
  112.         } finally {  
  113.             try {  
  114.   
  115.                 // 关闭流   
  116.                 is.close();  
  117.                 is = null;  
  118.             } catch (IOException e) {  
  119.                 e.printStackTrace();  
  120.             }  
  121.   
  122.         }  
  123.         return bitmap;  
  124.   
  125.     }  
  126.   
  127. }  

然后定义我们的WallpaperService,FireWallpaperService继承自GLWallpaperService:

 
  1. public class FireWallpaperService extends GLWallpaperService {  
  2.     //定义FireWallpaperRenderer实例   
  3.     private FireWallpaperRenderer mRenderer;  
  4.       
  5.       
  6.     public Engine onCreateEngine() {  
  7.         if (mRenderer == null) {  
  8.             mRenderer = new FireWallpaperRenderer(this);  
  9.         }  
  10.         return new FireWallpaperEngine();  
  11.     }  
  12.   
  13.     class FireWallpaperEngine extends GLWallpaperService.GLEngine {  
  14.   
  15.         public FireWallpaperEngine() {  
  16.             //设置Renderer和RendererMode   
  17.             setRenderer(mRenderer);  
  18.             setRenderMode(RENDERMODE_CONTINUOUSLY);  
  19.         }  
  20.   
  21.     }  
  22.   
  23. }  

完成后编辑Manifest.xml文件,如下:

 
  1. application android:icon="@drawable/icon" android:label="@string/app_name">  
  2.         <service android:name=".FireWallpaperService" android:label="@string/firewallpaper"  
  3.             android:permission="android.permission.BIND_WALLPAPER">  
  4.             <intent-filter>  
  5.                 <action android:name="android.service.wallpaper.WallpaperService" />  
  6.             intent-filter>  
  7.             <meta-data android:name="android.service.wallpaper"  
  8.                 android:resource="@xml/wallpaper" />  
  9.         service>  
  10.   
  11.     application>  

Manifest.xml文件中,FireWallpaperService使用到的wallpaper文件

(wallpaper" />)在res/xml目录下定义,内容如下:

 
  1. <span style="color:#000000;">xml version="1.0" encoding="utf-8"?>  
  2. <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:description="@string/description" android:thumbnail="@drawable/firelivewallpaper" />span>  

然后是我们的本地方法类——FireNativeMethod:

 
  1. import javax.microedition.khronos.egl.EGLConfig;  
  2. import javax.microedition.khronos.opengles.GL10;  
  3.   
  4. public class FireNativeMethod {  
  5.     //加载本地库文件   
  6.     static{  
  7.         System.loadLibrary("fire_native_method");  
  8.     }  
  9.       
  10.     //渲染场景本地方法   
  11.     public static native void onDrawFrame(GL10 gl);  
  12.     //处理屏幕尺寸变化本地方法   
  13.     public static native void onSurfaceChanged(GL10 gl, int width, int height);  
  14.     //初始化OpenGL场景本地方法   
  15.     public static native void onSurfaceCreated(GL10 gl, EGLConfig config);  
  16.     //传递纹理映射地址本地方法   
  17.     public static native void setTexture(int [] textureString);  
  18.   
  19. }  

之后就是我们的本地C++代码部分了。


推荐阅读
  • 本文探讨了如何通过编程手段在Linux系统中禁用硬件预取功能。基于Intel® Core™微架构的应用性能优化需求,文章详细介绍了相关配置方法和代码实现,旨在帮助开发人员有效控制硬件预取行为,提升应用程序的运行效率。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 基于Linux系统的Kickstart自动化服务器部署方案
    本文针对企业需求,提出了一种基于Linux系统的Kickstart自动化服务器部署方案。该方案旨在通过无盘批量安装操作系统,提高企业IT基础设施的部署效率。Kickstart是一种利用Anaconda工具实现服务器自动化安装的技术,能够显著简化和加速操作系统的安装过程。通过详细的实施规划,本文介绍了Kickstart的工作原理及其在实际部署中的应用,为企业提供了高效的自动化部署解决方案。 ... [详细]
  • 本文详细解析了客户端与服务器之间的交互过程,重点介绍了Socket通信机制。IP地址由32位的4个8位二进制数组成,分为网络地址和主机地址两部分。通过使用 `ipconfig /all` 命令,用户可以查看详细的IP配置信息。此外,文章还介绍了如何使用 `ping` 命令测试网络连通性,例如 `ping 127.0.0.1` 可以检测本机网络是否正常。这些技术细节对于理解网络通信的基本原理具有重要意义。 ... [详细]
  • 本文深入探讨了MDK链接脚本的应用与优化技巧。首先,文章介绍了链接脚本的基本概念及其在嵌入式系统开发中的重要性。接着,通过具体实例详细分析了链接脚本的结构和功能,特别是在程序在FLASH中运行时,如何优化链接脚本以提高系统性能。此外,文章还讨论了无需将程序加载到SRAM中的技术细节,为开发者提供了实用的参考和指导。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在本地环境中部署了两个不同版本的 Flink 集群,分别为 1.9.1 和 1.9.2。近期在尝试启动 1.9.1 版本的 Flink 任务时,遇到了 TaskExecutor 启动失败的问题。尽管 TaskManager 日志显示正常,但任务仍无法成功启动。经过详细分析,发现该问题是由 Kafka 版本不兼容引起的。通过调整 Kafka 客户端配置并升级相关依赖,最终成功解决了这一故障。 ... [详细]
author-avatar
mm2525888
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有