本文是一个Android动态壁纸的例子,利用android_ndk调用底层的C++代码,使用OpenGLES来绘制动态壁纸。仅作参考。首先是定义我们自己的Renderer类,FireWallpaperRenderer实现了GLWallpaperService.Renderer接口(GLWallpaperService的代码在《Android利用OpenGLES开发动态壁纸用到的GLWallpaperService类》的那篇文章里):
- import java.io.IOException;
- import java.io.InputStream;
-
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.opengl.GLUtils;
- import android.util.Log;
-
- public class FireWallpaperRenderer implements GLWallpaperService.Renderer {
- //用于纹理映射的绑定,并把绑定后的地址传递给C++代码,供其调用
- private int[] texture = new int[2];
- //用于加载Bitmap的context
- private Context mContext;
-
- //FireWallpaperRenderer构造函数,用来初始化mContext
- public FireWallpaperRenderer(Context context){
- mContext = context;
- }
-
- /**
- * 渲染场景的代码,这里我们是通过调用底层C++的代码来实现的,
- * 这样能得到更好地运行速度
- * */
- @Override
- public void onDrawFrame(GL10 gl) {
- //调用本地onDrawFrame方法
- FireNativeMethod.onDrawFrame(gl);
- }
-
-
- /**
- * 处理屏幕尺寸发生变化时的代码,
- * 用来重新设置场景的大小和其他一些属性,
- * 也是通过调用底层C++代码来实现
- * */
- @Override
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- //调用本地onSurfaceChanged方法
- FireNativeMethod.onSurfaceChanged(gl, width, height);
- }
-
- /**
- * 初始化OpenGL场景,
- * 用来设置场景的一些属性,
- * 也是通过调用底层C++代码来实现
- * */
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- //用来绑定Bitmap纹理
- bindTexture(gl, mContext);
- //调用本地setTexture方法,把纹理绑定的地址传递给C++代码,以供其调用
- FireNativeMethod.setTexture(texture);
- //调用本地onSurfaceCreated方法
- FireNativeMethod.onSurfaceCreated(gl, config);
-
- }
-
- /**
- * 用来绑定Bitmap纹理的代码,
- * 因为暂时没有找到在C++代码中绑定Bitmap纹理的方法,
- * 所以暂且在java层绑定Bitmap纹理
- * */
-
- private void bindTexture(GL10 gl, Context context) {
- //生成纹理
- gl.glGenTextures(2, texture, 0);
- //加载Bitmap
- Bitmap bitmap = loadBitmap(context, R.drawable.floor);
- if (bitmap != null) {
- Log.i("firewallpaperrenderer", "bind the floor texture");
- //如果bitmap加载成功,则生成此bitmap的纹理映射
- gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
- //设置纹理映射的属性
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
- GL10.GL_NEAREST);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
- GL10.GL_NEAREST);
- //生成纹理映射
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
- //释放bitmap资源
- bitmap.recycle();
- }
- bitmap = loadBitmap(context, R.drawable.fire);
- if (bitmap != null) {
- //同上
- Log.i("firewallpaperrenderer", "bind the fire texture");
- gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
- GL10.GL_NEAREST);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
- GL10.GL_NEAREST);
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
- bitmap.recycle();
- }
-
- }
-
- /**
- * 加载Bitmap的方法,
- * 用来从res中加载Bitmap资源
- * */
- private Bitmap loadBitmap(Context context, int resourceId) {
- InputStream is = context.getResources().openRawResource(resourceId);
- Bitmap bitmap = null;
- try {
-
- // 利用BitmapFactory生成Bitmap
- bitmap = BitmapFactory.decodeStream(is);
- } finally {
- try {
-
- // 关闭流
- is.close();
- is = null;
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
- return bitmap;
-
- }
-
- }
|
然后定义我们的WallpaperService,FireWallpaperService继承自GLWallpaperService:
- public class FireWallpaperService extends GLWallpaperService {
- //定义FireWallpaperRenderer实例
- private FireWallpaperRenderer mRenderer;
-
-
- public Engine onCreateEngine() {
- if (mRenderer == null) {
- mRenderer = new FireWallpaperRenderer(this);
- }
- return new FireWallpaperEngine();
- }
-
- class FireWallpaperEngine extends GLWallpaperService.GLEngine {
-
- public FireWallpaperEngine() {
- //设置Renderer和RendererMode
- setRenderer(mRenderer);
- setRenderMode(RENDERMODE_CONTINUOUSLY);
- }
-
- }
-
- }
|
完成后编辑Manifest.xml文件,如下:
- application android:icon="@drawable/icon" android:label="@string/app_name">
- <service android:name=".FireWallpaperService" android:label="@string/firewallpaper"
- android:permission="android.permission.BIND_WALLPAPER">
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService" />
- </intent-filter>
- <meta-data android:name="android.service.wallpaper"
- android:resource="@xml/wallpaper" />
- </service>
-
- </application>
|
Manifest.xml文件中,FireWallpaperService使用到的wallpaper文件(<meta-dataandroid:name="android.service.wallpaper"android:resource="@xml/wallpaper" />)在res/xml目录下定义,内容如下:
- <span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
- <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:description="@string/description" android:thumbnail="@drawable/firelivewallpaper" /></span>
|
然后是我们的本地方法类——FireNativeMethod:
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
-
- public class FireNativeMethod {
- //加载本地库文件
- static{
- System.loadLibrary("fire_native_method");
- }
-
- //渲染场景本地方法
- public static native void onDrawFrame(GL10 gl);
- //处理屏幕尺寸变化本地方法
- public static native void onSurfaceChanged(GL10 gl, int width, int height);
- //初始化OpenGL场景本地方法
- public static native void onSurfaceCreated(GL10 gl, EGLConfig config);
- //传递纹理映射地址本地方法
- public static native void setTexture(int [] textureString);
-
- }
|
之后就是我们的本地C++代码部分了。