您的位置:首页 > 产品设计 > UI/UE

[初试Android]Service+跨线程操作GUI的一个小例子

2012-12-27 00:25 323 查看

[初试Android]Service+跨线程操作GUI的一个小例子

1、实验内容       

        本例子练习使用Service以及控件的跨线程操作:主Activity界面用来启动、停止一个服务,该服务启动后会产生一个线程,该线程每隔一秒产生一个随机双精度数,并将该随机数显示在主Activity界面的一个TextView控件中。

2、实现过程

2.1 建立工程

       首先建立一个空白的Android工程:工程名为ServiceDemo,程序包存储为per.elton.servicedemo,主Activity为默认名MainActivity。

2.2 添加Service实现类

       在per.elton.servicedemo下新建一个Service实现类:RandomService,该类继承android.app.Service。并重载该类的三个方法:

public class RandomService extends Service {
// 服务启动时调用一次
@Override
public void onCreate(){}

// 服务每次启动都调用一次
@Override
public void onStart(Intent intent, int startID){}

// 停止服务时调用
@Override
public void onDestory(){}

@Override
public IBinder onBind(Intent arg0) {
return null;
}
}

2.3 布置MainActivity界面

      添加两个按钮分别用来启动(btnStartService)和停止服务(btnStopService),添加一个TextView(tvShowRandom)用来显示随机数。布局如下图所示:



Fig 1

2.4 添加事件监听

       使MainActivity实现android.view.OnClickListener接口,并添加该接口的实现方法: 

@Override
public void onClick(View v) {}

      对于“Start Service”按钮和“Stop Service”:添加对按钮点击事件的处理为如下代码。

@Override
public void onClick(View v) {
Intent intent = new Intent(this,RandomService.class);
switch (v.getId()) {
case R.id.btnStartService:
// 显示启动服务,知道服务的类以及路径
startService(intent);
// 隐式启动服务,不清楚类的更详细细节
/*
* Intent intentHiden = new Intent();
* intentHiden.setAction("MY_RANDOM_SERVICE");
* startService(intentHiden);
*/
break;

case R.id.btnStopService:
stopService(intent);
break;
}
}

      既可以显式启动服务,也可以通过服务在AndroidManifest.xml中的名字(本例服务的名字名为“MY_RANDOM_SERVICE”)来启动服务。服务在XML文件中的设置如下:

<service android:name="RandomService">
<intent-filter>
<action android:name="MY_RANDOM_SERVICE"/>
</intent-filter>
</service>

      本例中采用直接指定服务的实现类来启动RandomService这个服务。

      在Activity启动时,将事件响应注册到两个按钮上。在onCreate方法中添加如下事件监听器。

Button btnStartService = (Button)findViewById(R.id.btnStartService);
Button btnStopService = (Button)findViewById(R.id.btnStopService);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);

2.5 添加updateGUI方法

      为了实现RandomService服务所启动的线程对MainActivity中tvShowRandom控件的操作,在MainAcitivity中添加一个静态的方法updateGUI(double),以方便服务中线程的调用。

private static TextView tvRandom; 	// 在onCreate方法中完成赋值
private static double dbRandom;	// 服务传递过来的随机数
private static int intIndex=0;	// 记录产生的随机数的次数
private static Handler handler = new Handler();	// 接受子线程传递来的数据,并更新UI

private static Runnable refreshRunnable = new Runnable() {
@Override
public void run() {
tvRandom.setText(String.valueOf(intIndex++)+" 产生的随机数:"+String.valueOf(dbRandom));
}
};

public static void updateGUI(double dbTmp){
dbRandom = dbTmp;
handler.post(refreshRunnable);
}

      关于Handler的更多介绍,http://www.pin5i.com/showtopic-android-handler.html。由于updateGUI方法是静态的,所以该方法涉及到的相关变量也都为静态的。

      至此,只要RandomService服务通过调用静态方法updateGUI即可更新主界面的空间内容,也就是显示一个随机数。接下来实现RandomService。

2.6 实现RandomService中的关键方法

      RandomServie需要实现2.2中所列出的三个主要方法:onCreate,onStart和onDestory。分别用来在初始化服务阶段、启动服务阶段和注销服务阶段调用。在onCreate方法中需要初始化一个线程,并通过一个Runnable变量指定其要实现的功能。相关代码如下:

private Thread rsThread;

private Runnable runableWork = new Runnable() {
public void run() {
try{
while(!Thread.interrupted()){
double dbRandom = Math.random();
MainActivity.updateGUI(dbRandom);// 更新界面
Thread.sleep(1000);	     // 子线程休眠一秒钟
}
}
catch (Exception e) {
Log.i("RANDOM_SERVICE", "Exception found ... ...");
}
}
};

@Override
public void onCreate(){
super.onCreate();
Toast.makeText(this, "Random service has been created now ... ...", Toast.LENGTH_LONG).show();

// 初始化线程
rsThread = new Thread(null,runableWork,"rsThread");
}


      服务的onStart方法在每次RandomService恢复运行或者启动时调用此方法,因此可在此方法中启动子线程,代码如下:

@Override
public void onStart(Intent intent, int startID){
super.onStart(intent, startID);
Toast.makeText(this, "Random service starts ... ...", Toast.LENGTH_LONG).show();

// 启动线程产生并显示随机数
if (!rsThread.isAlive()){
rsThread.start();
}
}

       停止RandomService服务:

@Override
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Random service has been destroied now ... ...", Toast.LENGTH_LONG).show();

rsThread.interrupt();
}

      现在所有的编码就完成了,可以直接编译放到机器上运行。本例中,模拟机采用的系统是基于android2.3.3平台的。

3、代码部分以及运行

      代码在第二章节已有较详细的介绍,此处将所有的代码打包,点击下载

      运行界面如下所示:


 
Fig 2

4、总结

      本例主要是练习如何实现一个服务,以及如何在子线程中操作主线程的GUI。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ANDROID Service
相关文章推荐