《Android 应用案例开发大全(第二版)》——2.7节线程相关类

2.7 线程相关类
Android 应用案例开发大全(第二版)
上一节详细介绍了绘制相关类,使读者对本案例的开发有了进一步的理解,在这一节将对线程相关类的开发进行详细介绍。前面已经完成了对水族馆背景及水族馆中鱼、鱼群和气泡绘制的开发,但是只是将鱼、鱼群、气泡绘制出来是远远不够的,还要让它们动起来,从而产生更加真实的效果。

本案例中启动了多个线程来定时刷新它们的位置。线程相关类主要包括气泡移动线程类、群鱼游动线程类、鱼群游动线程类、鱼食游动线程类和吸引力线程类,下面就对线程相关类的开发进行详细介绍。

2.7.1 气泡移动线程类——BubbleThread
首先介绍的是气泡移动线程类BubbleThread,该类的作用是使气泡不断地从屏幕前面冒出来,在上升一段距离后会消失,然后再在随机的位置产生气泡重复上述运动,具体代码如下所示。

1 package com.bn.ld.WorksThread;
2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码
3 public class BubbleThread extends Thread {
4  boolean flag = true;        // 标志位
5  BubbleControl Bcl;        // 气泡的控制类
6  public BubbleThread(BubbleControl Bcl) {
7   this.Bcl=Bcl;
8  }
9  public void run(){
10   while (flag) {        // 标志位
11    try {
12     for(int i=0;i<Bcl.BubbleSingle.size();i++){ // 遍历气泡列表
13       Bcl.BubbleSingle.get(i).bubbleMove();                // 执行气泡移动的方法
14     }
15    } catch (Exception e) {     // 进行异常处理
16     e.printStackTrace();     // 打印异常
17    }try {
18     Thread.sleep(100);     // 线程休眠100ms
19    } catch (Exception e) {     // 异常处理
20     e.printStackTrace();     // 打印异常
21 }}}}

说明
该类是气泡移动线程类,在该类中遍历气泡列表BubbleSingle,并调用气泡的移动方法bubbleMove,然后让线程休眠100ms后刷新气泡。

2.7.2 群鱼游动线程类——FishGoThread
上一小节完成了气泡移动线程类的介绍,读者已经了解了使气泡移动的方法。本小节将着重介绍群鱼移动线程类FishGoThread,具体包括群鱼之间的受力算法,群鱼碰到鱼群时的受力变化,以及群鱼和墙壁碰撞时的群鱼受力情况,具体代码如下所示。

1 package com.bn.ld.WorksThread;
2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码
3 public class FishGoThread extends Thread {  // 定时运动所有群鱼的线程
4  public void run() {
5   while (flag) {
6   try {        // 动态地修改群鱼受到的力的大小
7    for (int i = 0; i < fishControl.fishAl.size(); i++) {              // 计算其他鱼对该鱼产生的力的大小
8     Vector3f Vwall = null;
9     inside: for (int j = 0; j < fishControl.fishAl.size(); j++) {
10      Vector3f V3 = null;
11      if (i == j) {   // 自己不能对自己产生力
12     continue inside;
13    }
14    V3 = fishControl.fishAl.get(i).position.cut(                // 向量减法得到力的改变方向
15     fishControl.fishAl.get(j).position,Constant.MinDistances);
16    V3.getforce(fishControl.fishAl.get(i).weight); // 力与质量的比
17    fishControl.fishAl.get(i).force.plus(V3);  // 两条鱼之间的力
18    }
19  if (fishControl.Tr.fishSchool != null&& fishControl.Tr.fishSchool.fishSchool.
  size() != 0) {
20    Vector3f V4 = fishControl.fishAl.get(i).position.cut(               // 向量减法得到力的方向
21     fishControl.Tr.fishSchool.fishSchoolget(0).position,
     Constant.MinDistances);
22    V4.getforce(fishControl.fishAl.get(i).weight);
23    fishControl.fishAl.get(i).force.plus(V4);  // 两条鱼之间的力
24  }
25  Vwall = new Vector3f(0, 0, 0);
26  if (fishControl.fishAl.get(i).position.x <= -12f) { // 判断鱼和左墙壁的碰撞
27   Vwall.x = 0.0013215f;      // 撞上之后产生的力的作用
28  }
29  if (fishControl.fishAl.get(i).position.x > 12f) { // 判断鱼和右墙壁的碰撞
30   Vwall.x = -0.0013212f;      // 撞上之后产生的力的作用
31  }
32  if (fishControl.fishAl.get(i).position.y >= 4f) { // 判断鱼和上墙壁的碰撞
33   Vwall.y = -0.0013213f;      // 撞上之后产生的力的作用
34  }
35  if (fishControl.fishAl.get(i).position.y <= -3) { // 判断鱼和下墙壁的碰撞
36   Vwall.y = 0.002214f;       // 撞上之后产生的力的作用
37   if(fishControl.fishAl.get(i).position.y < -4){ // 鱼和下墙壁太近
38    Vwall.y = 0.006428f;      // 鱼所受到的反向力加倍
39   }}
40  if (fishControl.fishAl.get(i).position.z < -9f) { // 判断鱼和后墙壁的碰撞
41   Vwall.z = 0.0014214f;      // 撞上之后产生的力的作用
42  }
43  if (fishControl.fishAl.get(i).position.z > 1) {  // 判断鱼和前墙壁的碰撞
44   Vwall.z = -0.002213f;      // 撞上之后产生的力的作用
45  }
46  Vwall.y -= 0.000009;
47  fishControl.fishAl.get(i).force.plus(Vwall); // 鱼所受的力与墙给的力相加
48  }
49  for (int i = 0; i < fishControl.fishAl.size(); i++) {// 定时修改鱼的速度和位移
50   fishControl.fishAl.get(i).fishMove();   // 调用鱼游动方法的作用
51  }
52  } catch (Exception e) {       // 异常处理
53   e.printStackTrace();
54  }
55  try {           // 线程休眠
56   Thread.sleep(100);
57  } catch (Exception e) {       // 异常处理
58   e.printStackTrace();
59  }}}}

第3~24行计算单条鱼所受到的其他鱼的力,和鱼群对该鱼的力。当鱼与其他单条鱼或鱼群中鱼之间的距离小于阈值后会产生力的作用。
第25~48行是鱼与上、下、左、右、前、后墙壁的碰撞检测,碰撞时会产生力的作用。然后将鱼所受到的力与墙壁给鱼的力相加求出鱼所受到的合力。
第49~59行修改所有鱼的速度和位移。遍历群鱼列表,调用fishMove方法,让线程休眠100ms后刷新群鱼。

2.7.3 鱼群游动线程类——FishSchoolThread
上一小节详细介绍了群鱼游动线程类,本小节主要介绍鱼群游动线程类FishSchoolThread,具体包括鱼群之间的受力算法,鱼群碰到群鱼之后的受力变化,以及鱼群和墙壁碰撞时的鱼群受力情况,具体代码如下所示。

1 package com.bn.ld.WorksThread;
2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码
3 public class FishschoolThread extends Thread {
4  boolean flag = true;       // 线程标志位
5  FishSchoolControl fishschools;     // 鱼群控制类对象
6  float Length;        // 两条鱼之间的距离
7  public FishschoolThread(FishSchoolControl fishschools) {
8   this.fishschools = fishschools;
9  }
10  public void run() {
11  while (flag) {        // 定时移动鱼类
12  try {          // 鱼群受力
13  outside: for (int i = 1; i < fishschools.fishSchool.size(); i++) {               // 群鱼对鱼群里面的鱼的作用力
14  for (int j = 0; j < fishschools.Tr.fishControl.fishAl.size(); j++) {
15   if (Length > Constant.SMinDistaces-0.5) { // 距离超过一定范围就不受力
16    continue outside;
17   }
18   Vector3f V3 = null;.
19   V3 = fishschools.fishSchool.get(i).position.cut(
20    fishschools.Tr.fishControl.fishAl.get(j).position,
21    Constant.SMinDistaces);   // 进行向量减法获得力的方向
22   V3.getforce(Constant.WeightScals); // 力的缩放比,等同于单个鱼的质量
23   fishschools.fishSchool.get(i).force.plus(V3); // 两条鱼之间的力
24  }}
25  Vector3f Vwall = null;
26  float Cx = fishschools.fishSchool.get(0).position.x; // 第1条鱼的当前位置
27  float Cy = fishschools.fishSchool.get(0).position.y;
28  float Cz = fishschools.fishSchool.get(0).position.z;
29  int j=1;
30  for(int i=-90;i<=90.;i=i+90){     // 鱼群里面3条受群鱼力的鱼
31   fishschools.fishSchool.get(j).ConstantPosition.x = (float) (Cx+
   Constant.Radius*Math.cos(i));
32   fishschools.fishSchool.get(j).ConstantPosition.y = Cy;
33   fishschools.fishSchool.get(j).ConstantPosition.z = (float) (Cz+
  Constant.Radius*Math.sin(i));
34   j++;
35  }
36  for (int i = 1; i < fishschools.fishSchool.size(); i++){                // 每条鱼受到的恒力(不包括第1条鱼)
37  Vector3f VL = null;
38  VL = fishschools.fishSchool.get(i).ConstantPosition
39   .cutGetforce(fishschools.fishSchool.get(i).position);                // 计算恒力的中间变量
40  Length = VL.Vectormodule();     // 计算距离
41  if ((Length) >= Constant.SMinDistaces){
42   VL.getforce(Constant. ConstantForceScals / 8f);// 距离太远,那么恒力会增加
43  }else if (Length<= 0.3){     // 距离小于某个值时不产生力
44   VL.x = VL.y = VL.z = 0;
45  } else{
46   VL.getforce(Constant. ConstantForceScals);
47  }
48  float MediaLength = fishschools.fishSchool.get(i).force.Vectormodule();
49  if (Math.abs(MediaLength) == 0) {  // 把计算得到的力赋给恒力ConstantForce
50   fishschools.fishSchool.get(i).ConstantForce.x = VL.x;
51   fishschools.fishSchool.get(i).ConstantForce.y = VL.y;
52   fishschools.fishSchool.get(i).ConstantForce.z = VL.z;
53  } else {       // 把计算得到的力赋给恒力ConstantForce
54   fishschools.fishSchool.get(i).ConstantForce.x = 0;
55   fishschools.fishSchool.get(i).ConstantForce.y = 0;
56   fishschools.fishSchool.get(i).ConstantForce.z = 0;
57  }}
58  Vwall = new Vector3f(0, 0, 0);     // 判断鱼和墙壁的碰撞
59  if (fishschools.fishSchool.get(0).position.x <= -9) {
60   Vwall.x = 0.0013215f;     // 鱼与左墙壁的碰撞
61  }
62  if (fishschools.fishSchool.get(0).position.x > 9) {
63   Vwall.x = -0.0013212f;     // 鱼与右墙壁的碰撞
64  }
65  if (fishschools.fishSchool.get(0).position.y >= 9) {
66   Vwall.y = -0.0013213f;     // 鱼与上墙壁的碰撞
67  }
68  if (fishschools.fishSchool.get(0).position.y <= -6) {
69   Vwall.y = 0.002214f;      // 鱼与下墙壁的碰撞
70  }
71  if (fishschools.fishSchool.get(0).position.z < -7) {
72   Vwall.z = 0.0014214f;     // 鱼与后墙壁的碰撞
73  }
74  if (fishschools.fishSchool.get(0).position.z > 4) {
75   Vwall.z = -0.002213f;     // 鱼与前墙壁的碰撞
76  }
77  fishschools.fishSchool.get(0).force.plus(Vwall);
78  for (int i = 0; i < fishschools.fishSchool.size(); i++) {                // 定时修改鱼的速度和位移
79   fishschools.fishSchool.get(i).fishschoolMove();
80  }
81  } catch (Exception e) {      // 异常处理
82   e.printStackTrace();      // 打印异常
83  }try {
84   Thread.sleep(100);      // 线程休眠
85  } catch (Exception e) {      // 异常处理
86   e.printStackTrace();
87 }}}}

第11~35行计算群鱼对鱼群的作用力。当鱼群中的某条鱼与群鱼的距离小于阈值后便对该鱼产生力的作用。本案例将鱼群中的第一条鱼设置为不受其他任何鱼的力,只受到墙壁力的作用。鱼群中其他的3条鱼(不包括第1条鱼)之间没有力的作用,也不受到第一条鱼的作用力,但是受到从该条鱼位置指向相对位置(以鱼群中第一条鱼所在位置为球心,以定长半径确定的球面上的一个点)的力的作用,同时也会受到群鱼的作用力。
第36~57行给离开鱼群的鱼赋予一个恒力。一旦这条鱼相对脱离了鱼群之后就会受到一个恒力使这条鱼游回鱼群,该条鱼游得越远这个力就会越大,从而使鱼群里面的鱼能够快速回到鱼群。
第58~76行是鱼群里面第一条鱼与上、下、左、右、前、后墙壁的碰撞检测,碰撞时会对鱼群里面的第一条鱼产生力的作用。
第77~87行为修改鱼群里面所有鱼的速度和位移。调用每条鱼的fishschoolMove方法定时修改鱼群里面鱼的速度和位移。进行异常处理,让线程休眠100ms后刷新鱼群。

2.7.4 鱼食移动线程类——FoodThread
上一小节完成了鱼群移动线程类的介绍,读者已经了解了使鱼群移动的方法。本小节着重介绍鱼食移动线程类FoodThread,主要包括食物的移动方法和标志位的设置,具体代码如下所示。

1 package com.bn.ld.WorksThread;
2 ……// 此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码
3 public class FoodThread extends Thread {   // 定时运动食物的线程
4  public boolean flag1 = true    // 线程的标志位
5     public boolean Fresit=true;    // 食物的_y_是否重置的标志位
6  boolean FxMove=true;      // 移动_x_方向的标志位
7  public boolean Go=false;     // 线程里面的算法,是否走的标志位
8  public  SingleFood SingleF;    // SingleFood对象的引用
9  public FoodThread(SingleFood singleF){
10   this.SingleF=singleF;
11  }
12  public void run(){
13   while (flag1) {
14    try {
15     if(Go){
16      if{(FxMove)   /食物晃动的标志位
17       SingleF.Tr.Xposition+= FoodMove_X;
18       FxMove=!FxMove;
19      }
20      else{
21       SingleF.Tr.Xposition-= FoodMove_X;
22       FxMove=!FxMove;
23      }
24      SingleF.Ypositon-= Constant.FoodSpeed;               // 定时地修该_y_坐标
25     }}
26    catch (Exception e) {
27     e.printStackTrace();   // 打印异常
28    }
29    try {
30     Thread.sleep(200);   // 线程休眠
31    } catch (Exception e) {
32     e.printStackTrace();   // 打印异常
33    }}}}

说明
该类是鱼食移动线程类,本案例中的鱼食是从上到下匀速运动,并且每次计算食物y所在的位置之前,会通过增加或减少食物的x、z坐标来使食物产生轻微的晃动效果,从而增强食物的真实感,让线程休眠200ms后刷新鱼食。

2.7.5 吸引力线程类——AttractThread
上一小节介绍了食物移动线程类。本节主要介绍鱼食对群鱼的吸引力线程类AttractThread,本案例中鱼群里面的鱼是看不到鱼食的,即不会受到食物吸引力的作用,具体代码如下所示。

1 package com.bn.ld.WorksThread;
2  ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码
3 public class AttractThread extends Thread {   // 定时运动鱼群的线程
4  public boolean Feeding = true;     // 线程的标志位
5  public boolean Fforcefish = true;    // 清空列表标志位
6  public boolean Go = false;      // 计算吸引力的标志位
7  float Length;        // 力的模长
8  SingleFood Sf;
9  ArrayList<SingleFish> fl = new ArrayList<SingleFish>(); // 受到力的鱼列表
10  public AttractThread(SingleFood sf) {
11   this.Sf = sf;
12  }
13  public void run() {
14   while (Feeding) {     // Feeding为永真
15    try {
16    if (Go) {      // 寻找能看到食物的鱼,添加到列表
17     if (Fforcefish) {    // 每次在点击喂食时要把列表清空
18      fl.clear();   // 清空列表
19      Fforcefish = false; // 只清空一次
20    }
21   if (fl != null ) {
22   for (int i = 0; i < Sf.Tr.fishAl.size(); i++) {  // 寻找满足条件的鱼
23   if (Sf.Tr.fishAl.get(i).position.x > Sf.Tr.Xposition&& Sf.Tr.fishAl.
   get(i).speed.x < 0) {
24    if (!fl.contains(Sf.Tr.fishAl.get(i))) {
25     fl.add(Sf.Tr.fishAl.get(i));
26    }}
27   else if (Sf.Tr.fishAl.get(i).position.x < Sf.Tr.Xposition&& Sf.Tr.
   fishAl.get(i).speed.x > 0) {
28    if (!fl.contains(Sf.Tr.fishAl.get(i))) {
29     fl.add(Sf.Tr.fishAl.get(i));
30     }}}}
31    if (fl.size() != 0) {    // 给鱼加食物时吸引力的作用
32     for (int i = 0; i < fl.size(); i++) {
33     Vector3f VL = null;     // 计算吸引力的中间变量
34     Vector3f Vl2 = null;     // 食物的位置信息
35     Vl2 = new Vector3f(Sf.Tr.Xposition,Sf.Tr.singleFood.       Ypositon,Sf.Tr.Zposition);
36     VL = Vl2.cutPc(fl.get(i).position); // 获取需要的向量
37     Length = VL.Vectormodule();   // 吸引力的模长
38       if (Length != 0) {
39       VL.ChangeStep(Length); // 将力的大小规格化
40      }
41   if (Length <= Constant.FoodFeedDistance || Sf.Ypositon < Constant.
   FoodPositionMin_Y) {
42       StopAllThread();
43      }
44     VL.getforce(Constant.AttractForceScals); // 吸引力的缩放比例
45     fl.get(i).attractforce.x = VL.x;                  // 把计算得到的吸引力赋给食物吸引力
46     fl.get(i).attractforce.y = VL.y;
47     fl.get(i).attractforce.z = VL.z;
48     }}}
49     if (Sf.Ypositon < Constant.FoodPositionMin_Y)) {              // 判断Ypositon是否超出范围
50      StopAllThread();
51     }
52    } catch (Exception e) {     // 异常处理
53     e.printStackTrace();     // 打印异常
54    }
55    try {         // 线程休眠
56     Thread.sleep(100);
57    } catch (Exception e) {     // 异常处理
58     e.printStackTrace();     // 打印异常
59    }}}
60  public void StopAllThread() {
61   Sf.Ypositon = Constant.FoodPositionMin_Y);  // 重置Ypositon
62   this.Fforcefish = true;         // 清空受到吸引力的鱼列表
63   this.Go = false;       // 吸引力算法的标志位
64   Sf.Ft.Go = false;       // 食物移动的标志位
65   Constant.isFeed = true;       // 喂食的标志位为ture
66   }}

第4~12行为设置线程标志位、是否清空受到食物吸引力的鱼列表的标志位(每次喂食之前会清空列表fl)、是否计算食物吸引力的标志位。并创建受到食物吸引力的鱼列表。
第14~30行寻找能看到鱼食的鱼,每喂食一次清空受到吸引力的鱼列表fl,然后再次喂食的时候会重新寻找满足条件的鱼,如果满足条件把该条鱼添加到受到吸引力的鱼列表fl里。
第31~51行为计算列表fl里面鱼受到食物吸引力的算法,能看到鱼食的鱼受到一个由该鱼当前位置指向食物的吸引力作用。
第60~66行为StopAllThread方法,若鱼食位置超过地面,或者鱼食被鱼吃掉之后,就会调用此方法,把鱼食移动线程里面的计算标志位和计算群鱼是否受到的食物吸引力标志位变为false,同时把点击喂食的标志位设置为true,从而能点击屏幕再次喂食。

时间: 2025-01-10 09:26:23

《Android 应用案例开发大全(第二版)》——2.7节线程相关类的相关文章

《Android 3D 游戏案例开发大全》——6.5节辅助界面相关类

6.5 辅助界面相关类 Android 3D 游戏案例开发大全 前一小节介绍了主控制类TXZActivity,本小节将对该游戏的辅助界面相关类进行介绍,该游戏的辅助界面主要是欢迎界面TXZWelcomeView类.菜单界面TXZMenuView类.设置界面TXZSetView类.帮助界面TXZHelpView类.选关界面TXZSelectView类,以及关于界面TXTAboutView类,下面就对这些类的开发进行详细介绍. 6.5.1 欢迎界面类TXZWelcomeView 欢迎界面是进入游戏的

《Android 应用案例开发大全(第二版)》——1.6节本书案例项目的导入

1.6 本书案例项目的导入 Android 应用案例开发大全(第二版) 1.6.1 导入并运行Android程序 前面已经对手机如何与Eclipse连接进行了详细讲解,本小节将介绍如何在Eclipse中导入项目,并在手机上运行已经写好的Android程序.本节将以导入本书第9章百纳理财专家为例进行详细讲解,具体步骤如下. 1.在Eclipse中导入项目 (1)启动Eclipse,依次选择"File/Import"将弹出导入项目的窗口Import,选择Existing Projects

《Android 应用案例开发大全(第二版)》——2.6节绘制相关类

2.6 绘制相关类 Android 应用案例开发大全(第二版) 上一节完成了水族馆辅助绘制类开发过程的介绍,这一节将对本案例中的绘制相关类进行详细介绍.主要包括气泡绘制相关类.群鱼绘制相关类.鱼群绘制相关类和鱼食绘制相关类,从而使读者对本案例的开发有一个更加深刻的理解.下面就对这些绘制相关类进行详细介绍. 2.6.1 绘制气泡相关类 真实的水族馆中时常会冒出一些气泡,所以,在该壁纸中加入了透明气泡元素,从而达到仿真.酷炫的效果.最后本案例的运行效果是鱼在水族馆里面游,透明的气泡从屏幕下方不断冒出

《Android 应用案例开发大全(第二版)》——1.3节Android开发环境的搭建

1.3 Android开发环境的搭建 Android 应用案例开发大全(第二版) 本节主要讲解基于Eclipse的Android开发环境的搭建,模拟器的创建和运行,以及如何应用DDMS进行程序的调试. 1.3.1 Android SDK的安装及环境变量的配置 Android使用的编程语言是时下最流行的Java高级语言,Java的跨平台性和开源性,极大地促进了Android平台的发展. 首先要安装Java的JDK,并且正确地配置系统的环境变量(基于Windows操作系统).具体步骤如下. (1)

《Android 应用案例开发大全(第二版)》——2.1节案例背景及功能概述

2.1 案例背景及功能概述 Android 应用案例开发大全(第二版) 这一节将会对本案例背景及其基本功能进行简单介绍,通过本节学习,读者将会对本案例的具体功能及相应开发过程有一个整体了解,为读者进行以后的学习打下基础. 2.1.1 水族馆动态壁纸背景概述 壁纸是用户在手机屏幕上用来替代原先单一颜色背景的一张图片,有了这样一张图片可以使手机屏幕变得好看.漂亮.而随着移动手持设备功能的不断强大,静态壁纸已经不能再满足用户对酷炫壁纸的需求了,所以产生了动态壁纸. 动态壁纸是将手机屏幕所使用的壁纸以动

《Android 应用案例开发大全(第二版)》——2.9节壁纸的优化与改进

2.9 壁纸的优化与改进 Android 应用案例开发大全(第二版) 本章对3D水族馆动态壁纸的开发进行了详细介绍,在学习过程中,重点掌握鱼游动过程中鱼旋转角度的算法,并掌握鱼和鱼之间作用力变化规律,鱼受到的墙壁作用力变化规律等. 动态壁纸界面的优化 没有哪一个案例的运行界面是不可以更加完美和绚丽的,所以,对本案例的界面.风格,读者可以自行根据自己的想法进行改进,使其更加完美,如水族馆地面.背景壁纸.水草类等的纹理图都可以进一步完善,从而达到一个更加理想的效果. 动态壁纸物理碰撞的优化 本案例物

《Android 应用案例开发大全(第二版)》——2.2节壁纸策划及准备工作

2.2 壁纸策划及准备工作 Android 应用案例开发大全(第二版) 上一节介绍了本案例的背景及功能,本节将要介绍动态水族馆的策划以及开发前的准备工作.读者要认真阅读这一节,这对理解壁纸的开发有着很大的作用. 2.2.1 3D水族馆动态壁纸的策划 接下来将要对本案例的策划进行介绍,在以后的实际项目开发中,对项目的策划还需要更加地细致.具体.全面,该壁纸的策划如下所示. 动态水族馆. 本案例为3D水族馆动态壁纸,在该壁纸中有许多可以自由游动的鱼,点击该壁纸的地面可以给鱼喂食,壁纸前面还有透明的气

《Android 应用案例开发大全(第二版)》——2.4节壁纸的实现

2.4 壁纸的实现 Android 应用案例开发大全(第二版) 上一节介绍了壁纸的框架,让读者对壁纸的整体框架有了初步认识,本节将要对壁纸实现服务类GLWallpaperService.动态壁纸类LiveWallpaper.自定义渲染器类TDRender的开发进行详细介绍. 2.4.1 壁纸服务类--GLWallpaperService 该类是本项目中最基础的一个类,没有这个类就不可能使用壁纸这个功能.这个类为开发人员提供了壁纸服务,开发人员可以通过继承该类,重写此类中的方法来实现壁纸的后续开发

《Android 应用案例开发大全(第二版)》——1.4节 DDMS的灵活应用

1.4 DDMS的灵活应用 Android 应用案例开发大全(第二版) 作为一名合格的软件开发人员,必须要学会怎样去调试程序.因为调试是一个程序员最基本的技能,其重要性甚至超过学好一门语言.可以这样说,不会调试的程序员肯定不会有很好的发展. 那么什么是调试呢?所谓程序调试,是在软件投入实际使用前,用手工或编译程序等方法进行测试,修正语法错误和逻辑错误的过程.这是保证软件系统正确性的必不可少的步骤. Android为开发人员提供了一个强大的调试工具--DDMS,通过DDMS可以调试并监控程序的运行