手持终端
Eclipse平台下Android开发环境的搭建
PhoneGap配置到Eclipse开发环境
使用PhoneGap开发Android应用程序
PhoneGap3.0以上版本配置到Eclipse开发环境
使用PhoneGap3.0版本开发Android应用程序
PhoneGap3.0的第三方Android插件
Cordova配置到Android Studio开发环境
Android系统基本架构
Android的字符串颜色图片样式
Android的常用控件及菜单
Android的消息提示及传递
Android系统的组件通信
Android系统的Service
Android的广播消息接收
Android的数据存储与访问
Android系统的网络应用
Android图形图像处理
Android的Fragment框架
Android系统的并发编程
Java源文件结构与保留字
Java语言的数据类型与变量
Java的运算符与流程控制
Java语言的数组及操作
Java面向对象编程
Java的常用类
Android开发常用工具及命令
Android应用程序权限管理
Android系统提供的R类内置资源
Android系统的控件类及其方法
Android系统的菜单类及其方法
Android系统的对话框
Android应用程序模型及组件
Android的绘图类及方法
Android系统的动画效果
Android的数据库操作
Android的多媒体功能
Android系统照相机的使用
Android的文本朗读TTS
获取Android系统信息
Android系统的电话操作
Android系统的定位
Android系统的传感器
按照工作方式,Android应用程序可以分为前台和后台两种,Activity是前台应用程序,而Service是后台服务,可使用startService()方法将指定的应用转到后台。
Service分为本地服务Local Service和远程服务Remote Service两种,本地服务主要在应用程序内部使用,应用实现应用程序本身的任务,如自动下载;远程服务主要在应用程序之间使用,如天气预报。
后台服务往往需要运行较长的时间,甚至会从系统启动开始运行到系统关闭。Service一般不与用户交互,并且Service运行时不会获取控制权。Service有自己的声明周期,可以调用Context.startService()来启动一个服务,启动后会一直运行,直到使用Context.stopService()或stopSelf()方法结束服务。
综上所述,Service的特点是:没有用户界面、不与用户交互,长时间运行,不占据程序控制权,优先级比Activity高,不会轻易被Android系统终止。
Android提供了一些特殊的Service类,如AbstractInputMethodService、AccessibilityService、IntentService、RecognitionService、WallpaperService。
1. 创建Service类:
创建一个自定义的Service类,需要继承android.app.Service类,并且重写其onCreate()、onStart()、onDestroy()等方法。其中,onCreate()方法用来初始化Service,是Service生命周期的开始;onStart()用来启动一个Service,表示Service进入运行状态;onDestroy()用来释放Service占用的资源,是Service生命周期的结束。
要使用自定义的Service类,需要在AndroidManifest.xml配置文件进行如下配置:
<service android:name=".MyService" android:enabled="true">
<intent-filter>
<action android:name="cn.example.dwenzhao.MY_SERVICE"/>
</intent-filter>
</service>
2. Service的使用:
Service类创建后,可以通过两种方式启动,Context.startService()或Context.bindService()。
1)Context.startService()启动流程:
context.startService()--onCreate()--onStart()--Service running--context.stopService()--onDestroy() --Service stop
如果Service还没有运行,则Android先调用onCreate()方法,然后调用onStart()方法;如果Service已经运行,则只调用onStart()方法。一个Service的onStart()方法可能会调用多次。
在调用stopService()方法时会直接调用onDestroy()方法,如果是调用者自己直接退出而没有调用stopService(),Service会一直在后台运行。
调用startService方法的生命周期为:onCreate()--onStart()(可多次调用)--onDestroy()
使用startService()启动的服务,要通过调用Context.stopService()或Service.stopSelf()方法来停止,其中stopService()会强制终止当前服务,而stopSelf()直到Intent处理完才停止服务。
2)Context.bindService()启动流程:
context.bindService()--onCreate()--onBind()--Service running--onUnbind()--onDestroy()--Service stop
onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,如得到Service的运行状态等,这时会把调用者(Context)和Service绑定在一起,Context退出了,Service就会调用onUnbind()--onDestroy()方法相应地退出。同一个Service可以绑定多个服务连接,因而通过绑定方式可以同时为多个不同的应用提供服务。
Context.bindService()绑定一个Service时需要3个参数,第1个参数是Intent对象,第2个参数是服务连接对象ServiceConnection;第3个参数是创建Service的方式,一般指定为自动创建Service.BIND_AUTO_CREATE。其中的服务连接对象ServiceConnection需要创建,要实现其onServiceConnected()和onServiceDisconnected()方法,用于判断连接成功或失败:
ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name,IBinder service){
Log.i("SERVICE","连接成功");
}
@Override
public void onServiceDisconnected(ComponentName name){
Log.i("SERVICE","断开连接");
}
};
而绑定Service的代码为:
Context.bindService(intent,conn,Service.BIND_AUTO_CREATE);
调用bindService方法的生命周期为:onCreate()--onBind()(只一次)--onUnbind()--onDestroy()
使用bindService()绑定的服务,要通过Context.unbindService()解除绑定。
startService()和bindService()方式可以混合使用,比如MP3播放器启动音乐功能可通过startService()来播放音乐;对暂停音乐可通过onBind()获取服务连接和Service对象,通过调用该Service对象来暂停。这时,调用stopService()并不能停止音乐Service,需要在所有服务连接关闭后才能停止。
3. Android系统服务:
Android提供了大量系统服务,用于完成不同的功能:
Service名 |
作用 |
返回对象 |
WINDOW_SERVICE |
窗口服务 |
android.view.WindowManager |
LAYOUT_INFLATER_SERVICE |
布局映射服务 |
android.view.LayoutInflater |
ACTIVITY_SERVICE |
活动服务 |
android.app.ActivityManager |
NOTIFICATION_SERVICE |
通知服务 |
android.app.NotificationManager |
KEYGUARD_SERVICE |
键盘锁服务 |
android.app.KeyguardManager |
LOCATION_SERVICE |
位置服务 |
android.location.LocationManager |
SEARCH_SERVICE |
本地查询服务 |
android.app.SearchManager |
VEBRATOR_SERVICE |
手机震动服务 |
android.os.Vibrator |
CONNECTIVITY_SERVICE |
网络连接服务 |
android.net.ConnectivityManager |
WIFI_SERVICE |
无线局域网服务 |
android.net.wifi.WifiManager |
TELEPHONY_SERVICE |
电话服务 |
android.telephony.TelephonyManager |
SENSOR_SERVICE |
传感器服务 |
android.os.storage.StorageManager |
INPUT_METHOD_SERVICE |
输入法服务 |
android.view.inputmethod.InputMethodManager |
这些系统服务可以通过Context.getSystemService()方法获取Android系统所支持的服务管理对象,示例:
ActivityManager am=(ActivityManager)getSystemService(ACTIVITY_SERVICE);
4. Notification在状态栏的使用:
NotificationManager类是系统的通知服务管理器,能够将通知信息显示在状态栏上。Notification类用于定义通知的显示(图片及标题等)以及处理通知的应用,其本身并不能实现在状态栏上显示通知的功能,必须通过NotificationManager才能将Notification所定义的通知显示在手机中。具体步骤为:
⑴通过getSystemService(NOTIFICATION_SERVICE)创建NotificationManager对象,用于管理Notification。
⑵使用Notification构造函数创建Notification对象。
Notification notification=new Notification(drawable,ticketText,System.currentTimeMillis());
也可以通过属性设置来设置状态栏上的图标、内容以及显示的时间等。示例:
notification.icon=drawable;
notification.ticketText=tickertext;
notification.when=System.currentTimeMillis();
Notification还提供了声音、震动模式等其他属性:
属性名 |
描述 |
andioStreamType |
Notification所用的音频流类型 |
contentIntent |
设置单击通知条目时所执行的Intent |
contentView |
设置在状态栏上显示通知时所显示的视图 |
defaults |
设置默认值,如DEFAULT_LIGHTS默认灯、DEFAULT_SOUND默认声音、DEFAULT_VIBRATE默认震动、DEFAULT_ALL以上默认 |
deleteIntent |
删除所有通知时被执行的Intent |
icon |
设置状态栏上显示的图标 |
iconLevel |
设置显示图标级别 |
ledARGB |
设置LED颜色 |
ledOffMS |
设置关闭LED时的闪烁时间 |
ledOnMS |
设置开启LED时的闪烁时间 |
sound |
设置一个音频文件作为Notification,其值为一个URI |
tickerText |
设置状态栏上显示的消息内容 |
vibrate |
设置Notification的震动模式,通常是一个时间数组long[] vibrate=new long[]{1000,1000,1000,1000,1000},。配置文件中需要设置权限 |
when |
通知发生的时间 |
注:ledOffMS为0而ledOnMS为1表示打开LED,两者设置为0表示关闭LED。
⑶创建Intent对象,并指定其对应的Notification。
Intent intent=new Intent(notification,class);
⑷根据创建的Intent对象创建PendingIntent对象,用于对Intent对象的进一步封装。
PendingIntent mPendingIntent=PendingIntent.getActivity(NotificationName.this,0,intent,0);
⑸调用NotificationManager的notify()方法将通知发送到状态栏中。
nm.notify(R.layout.main,notification);
⑹使用NotificationManager的cancel()方法删除Notification。
nm.cancel(R.layout.main);
5.跨进程服务:
AIDL是Android Interface Definition Language的缩写,用于生成可以在Android设备上两个进程之间进行的通信(IPC,Interprocess Communication)的代码。如果在一个进程中要调用另一个进程中对象的操作,就可以使用AIDL生成可序列化的参数。AIDL IPC机制是面向接口的,,使用代理类在客户端和实现端之间传递数据。
在Android中,每个应用程序都有自己的进程,但Java是不支持跨进行内存共享的,要传递对象需要把对象解析成操作系统能够理解的数据格式,以达到跨界访问对象的目的。由于进程之间的通信信息需要双向转换,所以Android代理类在背后实现了信息的双向转换。只有用户为了进程间的通信允许客户端从不同的应用程序访问Service,以及实现在用户的Service中处理多线程情况下,使用AIPL才是必要的。
1)服务端:
AIDL是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,无须自己去写这段代码,只要在需要时调用即可。
首先要建立一个服务端工程,AIDLService,在IPerson.aidl中定义一个hello方法:
package com.mialab.aidl;
interface IPerson{String hello(String someone);}
在Eclipse插件的帮助下,编译器会自动在gen目录中生成对应的IPerson.java文件。
IPerson接口中的抽象内部类Stub继承android.os.Binder类并实现IPerson接口,其中比较重要的方法是asInterface(IBinder)方法,该方法会将IBinder类型的对象转换成IPerson类型,必要时生成一个代理对象返回结果。
接下来就是实现AIDLService,主要代码为:
public class AIDLService extends Service{
private static final String TAG="AIDLService";
IPerson.Stub stub=new IPerson.Stub(){
@Override
public String hello(String someone) throws RemoteException{
Log.d(TAG,"hello() called");
return "Hello,"+someone;
}
};
@Override
public IBinder onBind(Intent intent){
Log.d(TAG,"onBind() called");
return stub;
}
@Override
public boolean onUnbind(Intent intent){
Log.d(TAG,"onUnbind() called");
return true;
}
@Override
public boolean onDestroy(){
super.onDestroy();
Log.d(TAG,"onDestroy() called");
}
}
以上实现了IPerson.Stub抽象类的hello方法,然后在onBind方法中返回stub实例,这样调用方获取的IPerson.Stub就是这个实例,hello方法就会按照期望的那样执行。
要让Service生效,还需要AndroidManifest.xml中对Service进行配置:
<service android:name="cn.example.dwenzhao.service.AIDLService">
<intent-filter>
<action android:name="android.intent.action.AIDLService"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
2)客户端:
创建客户端工程,如AIDLService_Client,并将IPerson.aidl文件复制到相应目录中,编译器同样生成对应的IPerson.java文件,这样服务端和客户端在通信协议上达到统一,主要工作在MainActivity中完成。
代码中,需要重写ServiceConnection中的onServiceConnected方法,将IBinder类型的对象转换成IPerson类型;再通过服务端Service定义的android.intent.action.AIDLService标识来绑定所需要的服务,这样客户端和服务端就实现了通信的连接。
要把AIDLService.apk通过adb install命令安装到手机模拟器,安装成功后就会在Apps管理界面看到AIDLService。