万书网 > 文学作品 > Android从入门到精通 > 第139页

第139页



mouse  =  (ImageView)  findViewById(R.id.imageView1);  //获取ImageView对象



mouse.setOnTouchListener(new  OnTouchListener()  {



@Override



public  boolean  onTouch(View  v,  MotionEvent  event)  {



v.setVisibility(View.INVISIBLE);  //设置地鼠不显示



i++;



Toast.makeText(MainActivity.this,  "打到[  "  +  i  +  "  ]只地鼠!",



Toast.LENGTH_SHORT).show();  //显示消息提示框



return  false;



}



});

运行本实例,在屏幕上将随机显示地鼠,触摸地鼠后,该地鼠将不显示,同时在屏幕上通过消息提示框显示打到了几只地鼠,如图12.10所示。



图12.10 简易打地鼠游戏





12.4 小 结

本章主要介绍了在Android中如何实现多线程。由于在Android中,不能在子线程(也称为工作线程)中更新主线程(也称为UI线程)中的UI组件,因此Android引入了消息传递机制,通过使用Looper、Handler和Message就可以轻松实现多线程中更新UI界面的功能,这与Java中的多线程不同,希望读者能很好的理解,并能灵活应用。另外,多线程是游戏开发中非常重要的一项技术。





12.5 实践与练习

1.  编写Android项目,实现在屏幕上来回移动的气球。(答案位置:光盘\TM\sl\12\12.8)

2.  编写Android项目,实现颜色不断变化的文字。(答案位置:光盘\TM\sl\12\12.9)





第13章 Service应用

(  教学录像:48分钟)

Service用于在后台完成用户指定的操作,它可以用于音乐播放器、文件下载工具等应用程序。用户可以使用其他控件来与Service进行通信。本章将介绍Service的实现和使用方式。

通过阅读本章,您可以:

★  掌握Service的概念和用途



★  掌握创建Started  Service的两种方式



★  掌握创建Bound  Service的两种方式



★  掌握Service生命周期的管理





13.1 Service概述

教学录像:光盘\TM\lx\13\Service概述.exe

Service(服务)是能够在后台执行长时间运行操作并且不提供用户界面的应用程序组件。其他应用程序组件能启动服务,并且即便用户切换到另一个应用程序,服务还可以在后台运行。此外,组件能够绑定到服务并与之交互,甚至执行进程间通信(IPC)。例如,服务能在后台处理网络事务、播放音乐、执行文件I/O或者与ContentProvider通信。

13.1.1 Service的分类

服务从本质上可以分为以下两种类型。

[√]Started(启动):当应用程序组件(如Activity)通过调用startService()方法启动服务时,服务处于started状态。一旦启动,服务能在后台无限期运行,即使启动它的组件已经被销毁。通常,启动服务执行单个操作并且不会向调用者返回结果。例如,它可能通过网络下载或者上传文件。如果操作完成,服务需要停止自身。



[√]Bound(绑定):当应用程序组件通过调用bindService()方法绑定到服务时,服务处于bound状态。绑定服务提供客户端-服务器接口,以允许组件与服务交互、发送请求、获得结果,甚至使用进程间通信(IPC)跨进程完成这些操作。仅当其他应用程序组件与之绑定时,绑定服务才运行。多个组件可以一次绑定到一个服务上,当它们都解绑定时,服务被销毁。

尽管本章将两种类型的服务分开讨论,服务也可以同时属于这两种类型,既可以启动(无限期运行)也能绑定。其重点在于是否实现一些回调方法:onStartCommand()方法允许组件启动服务;onBind()方法允许组件绑定服务。

不管应用程序是否为启动状态、绑定状态或者两者兼有,都能通过Intent使用服务,就像使用Activity那样。然而,开发人员可以在配置文件中将服务声明为私有的,从而阻止其他应用程序访问。

服务运行于管理它的进程的主线程,服务不会创建自己的线程,也不会运行于独立的进程(除非开发人员定义)。这意味着,如果服务要完成CPU密集工作或者阻塞操作(如MP3回放或者联网),开发人员需要在服务中创建新线程来完成这些工作。通过使用独立的线程,能减少应用程序不响应(ANR)错误的风险,并且应用程序主线程仍然能用于用户与Activity的交互。

13.1.2 Service类中的重要方法

为了创建服务,开发人员需要创建Service类(或其子类)的子类。在实现类中,需要重写一些处理服务生命周期重要方面的回调方法,并根据需要提供组件绑定到服务的机制。需要重写的重要回调方法如下:

[√]onStartCommand()

当其他组件(如Activity)调用startService()方法请求服务启动时,系统调用该方法。一旦该方法执行,服务就启动(处于started状态)并在后台无限期运行。如果开发人员实现该方法,则需要在任务完成时调用stopSelf()或stopService()方法停止服务(如果仅想提供绑定,则不必实现该方法)。

[√]onBind()

当其他组件调用bindService()方法想与服务绑定时(如执行RPC),系统调用该方法。在该方法的实现中,开发人员必须通过返回IBinder提供客户端用来与服务通信的接口。该方法必须实现,但是如果不想允许绑定,则返回null。

[√]onCreate()

当服务第一次创建时,系统调用该方法执行一次性建立过程(在系统调用onStartCommand()或onBind()方法前)。如果服务已经运行,该方法不被调用。

[√]onDestroy()

当服务不再使用并即将销毁时,系统调用该方法。服务应该实现该方法来清理诸如线程、注册监听器、接收者等资源。这是服务收到的最后调用。

如果组件调用startService()方法启动服务(onStartCommand()方法被调用),服务需要使用stopSelf()方法停止自身,或者其他组件使用stopService()方法停止该服务。

如果组件调用bindService()方法创建服务(onStartCommand()方法不被调用),服务运行时间与组件绑定到服务的时间一样长。一旦服务从所有客户端解绑定,系统会将其销毁。

Android系统仅当内存不足并且必须回收系统资源来显示用户关注的Activity时,才会强制停止服务。如果服务绑定到用户关注的Activity,则会减小停止概率。如果服务被声明为前台运行,则基本不会停止。否则,如果服务是started状态并且长时间运行,则系统会随时间推移降低其在后台任务列表中的位置并且有很大概率将其停止。如果服务是started状态,则必须设计系统重启服务。系统停止服务后,资源可用时会将其重启(但这也依赖于onStartCommand()方法的返回值)。