31. 2D graphics process Activity android.view.* android.graphics.* (Canvas, Paint,Path, Picture,Region...) ActivityManager WindowManager frameworks/base/core/jni/android/graphic SurfaceFlinger HAL / FrameBuffer Get Surface Obj. /external/skia
32. 3D graphics process Activity android.opengl.* javax.microedition.khronos.egl javax.microedition.khronos.opengl (GLSurfaceView...) ActivityManager WindowManager frameworks/.../gles_jni/* SurfaceFlinger HAL / FrameBuffer Get Surface Obj. /frameworks/base/opengl
/*x 该值表示方位, 0 代表北( North ); 90 代表东( East ); 180 代表南( South ); 270 代表西( West ) 如果 x 值正好是这 4 个值之一,并且手机是水平放置,手机的顶部对准的方向就是该值代表的方向。 y 值表示倾斜度,或手机翘起的程度。当手机绕着 X 轴倾斜时该值发生变化。 y 值的取值范围是 -180≤y 值 ≤ 180 。 假设将手机屏幕朝上水平放在桌子上,这时如果桌子是完全水平的, y 值应该是 0 (由于很少有桌子是绝对水平的, 因此,该值很可能不为 0 ,但一般都是 -5 和 5 之间的某个值)。这时从手机顶部开始抬起,直到将手机沿 X 轴旋转 180 度(屏幕向下水平放在桌面上)。 在这个旋转过程中, y 值会在 0 到 -180 之间变化,也就是说,从手机顶部抬起时, y 的值会逐渐变小, 直到等于 -180 。如果从手机底部开始抬起,直到将手机沿 X 轴旋转 180 度,这时 y 值会在 0 到 180 之间变化。 也就是 y 值会逐渐增大,直到等于 180 。可以利用 y 值和 z 值来测量桌子等物体的倾斜度。 z 值表示手机沿着 Y 轴的滚动角度。表示手机沿着 Y 轴的滚动角度。取值范围是 -90≤z 值≤ 90 。 假设将手机屏幕朝上水平放在桌面上,这时如果桌面是平的, z 值应为 0 。将手机左侧逐渐抬起时, z 值逐渐变小,直到手机垂直于桌面放置,这时 z 值是 -90 。将手机右侧逐渐抬起时, z 值逐渐增大, 直到手机垂直于桌面放置,这时 z 值是 90 。在垂直位置时继续向右或向左滚动, z 值会继续在 -90 至 90 之间变化。 */
<declare-styleable name=&quot;Wallpaper&quot; > <!-- Component name of an activity that allows the user to modify the current settings for this wallpaper. --> <attr name=&quot;settingsActivity&quot; /> <!-- Reference to a the wallpaper's thumbnail bitmap. --> <attr name=&quot;thumbnail&quot; format=&quot;reference&quot; /> <!-- Name of the author of this component, e.g. Google. --> <attr name=&quot;author&quot; format=&quot;reference&quot; /> <!-- Short description of the component's purpose or behavior. --> <attr name=&quot;description&quot; /> </declare-styleable>
package cn.shen.wallpaper.service; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Handler; import android.service.wallpaper.WallpaperService; import android.view.MotionEvent; import android.view.SurfaceHolder; /* * This animated wallpaper draws a rotating wireframe cube. */ public class LiveWallpaperService extends WallpaperService { private final Handler handler = new Handler(); /** * 创建引擎 */ public Engine onCreateEngine() { return new CubeEngine(); } /** * 立方体引擎 */ class CubeEngine extends Engine { private final Paint mPaint = new Paint();// 画板 private float xOffset ;// 偏移量 private float touchX = -1;// x 触点 private float touchY = -1;// y 触点 private float centerX;// x 中心 private float centerY;// y 中心 private boolean visible;// 可见 private float step = 2; private float downX = -1; private float downY = -1; private float upX = -1; private float upY = -1; /** * 分线程运行程序 */ private Runnable r = new Runnable() { public void run() { doDraw(); } }; CubeEngine() { // Create a Paint to draw the lines for our cube // 初始化 Paint paint = mPaint;// 油漆 , 涂料 paint.setColor(0xffff0000);// 颜色 paint.setAntiAlias( true );// 抗锯齿 paint.setStrokeWidth(2);// 笔画宽度 paint.setStrokeCap(Paint.Cap. ROUND );// 帽形 paint.setStyle(Paint.Style. STROKE );// 样式 } // 启用触碰事件 public void onCreate(SurfaceHolder surfaceHolder) { super .onCreate(surfaceHolder); setTouchEventsEnabled( true ); } // public void onDestroy() { super .onDestroy(); handler.removeCallbacks(r);// 删除队列中所有该回调消息 } // 可见性发生变化 public void onVisibilityChanged( boolean visible) { this .visible = visible; if (visible) { doDraw();// 画框 } else { // 删除消息中的队列 handler.removeCallbacks(r); } } // 表面变化时 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { super .onSurfaceChanged(holder, format, width, height); // store the center of the surface, so we can draw the cube in the // right spot centerX = width / 2.0f;// 计算中心位置 ( 表面包容器宽度的一半 ) centerY = height / 2.0f;// 计算中心位置 ( 表面包容器高度的一半 ) doDraw(); } // 表面销毁时 public void onSurfaceDestroyed(SurfaceHolder holder) { super .onSurfaceDestroyed(holder); this .visible = false ; handler.removeCallbacks(r); } // 响应偏移量发生改变时事件 WallpaperManager.setWallpaperOffsets(). public void onOffsetsChanged( float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) { this .xOffset = xOffset; doDraw();// 画框 } /* * Store the position of the touch event so we can use it for drawing * later */ // 响应触碰事件 public void onTouchEvent(MotionEvent event) { // if (event.getAction() == MotionEvent.ACTION_MOVE) { // this.touchX = event.getX();// 得到移动点 x 坐标 // this.touchY = event.getY();// 得到移动点 y 坐标 // } else { // this.touchX = -1; // this.touchY = -1; // } if (event.getAction() == MotionEvent. ACTION_DOWN ) { this .downX = event.getX(); this .downY = event.getY(); } else { this .upX = event.getX(); this .upY = event.getY(); } super .onTouchEvent(event); } /* * Draw one frame of the animation. This method gets called repeatedly * by posting a delayed Runnable. You can do any drawing you want in * here. This example draws a wireframe cube. */ void doDraw() { final SurfaceHolder holder = getSurfaceHolder();// 得到表面包容器 Canvas c = null ; try { c = holder.lockCanvas();// 锁定画布 if (c != null ) { drawCube(c);// 画立方体 drawTouchPoint(c);// 画触点 } } finally { if (c != null ) holder.unlockCanvasAndPost(c);// 解锁画布并发送 } // Reschedule the next redraw handler.removeCallbacks(r);// 画完图形后 , 删除对立中消息 . if (visible) { handler.postDelayed(r, 1000 / 25);// 若墙纸可见 , 发送延迟消息 } } /* * Draw a wireframe cube by drawing 12 3 dimensional lines between * adjacent corners of the cube 绘制立方体 */ void drawCube(Canvas c) { if (step >= this .centerX) { step = 2; } float left = this .centerX - step; float top = this .centerY + step; float right = this .centerX + step; float bottom = this .centerY - step; c.save(); c.translate(0, 0);// 移动到中间位置 c.drawColor(0xff000000);// 用指定颜色填充画布的位图 c.drawLine(left, top, right, top, mPaint); c.drawLine(right, top, right, bottom, mPaint); c.drawLine(left, bottom, right, bottom, mPaint); c.drawLine(left, top, left, bottom, mPaint); c.restore(); step = step + 2; } /* * Draw a circle around the current touch point, if any. */ void drawTouchPoint(Canvas c) { if (downX > 0 && upX > 0 && (!(downX == upX && downY == upY))) { float originalX = (downX + upX) / 2 ; float originalY = (downY + upY) / 2 ; double radius = Math. sqrt (Math. pow (upX - downX,2) + Math. pow (upY - downY,2)) / 2 ; c.drawCircle(originalX, originalY, new Float(radius), mPaint); } } } }