1.服务入门
进程的等级:
Foreground process(前台进程)
应用程序,用户正在操作,activity的onresume方法被执行了,可以相应点击事件。
Visible process (可视进程)
应用程序的ui界面,用户还可以看到,但是不能操作了。
Service process (服务进程)
应用程序没有界面,但是有一个后台的服务还处于运行状态
Background process(后台进程)
应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法
Empty process (空进程)
没有任何组件运行,所有的activity都关闭了,任务栈清空了
进程与应用程序之间的关系: linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的。
进程的生命周期:
1、应用程序一启动的时候就创建了进程; 2、当应用程序退出的时候进程并没有退出; 缓存,加快下次启动的速度 3、只有手工停止这个进程,进程才会结束; 操作系统尽量长时间的运行应用程序的进程,为了保证内从空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多。
服务的特点
服务的特点:
服务被创建时调用onCreate、onStartCommand; 服务只能被创建一次,可以开启多次onStartCommand; 服务只能被停止一次; 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
生命周期的方法:
onCreate:服务被创建的时候调用这个方法; onStartCommand :开启服务 onDestroy:销毁服务
一个简单的示例
1.启动一个service
//使用意图启动Service
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
2.创建一个类继承Service
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
//创建服务的时候调用
@Override
public void onCreate() {
System.out.println("*****onCreate******");
super.onCreate();
}
//启动server 每次start都会调用一次
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("*****onStartCommand******");
return super.onStartCommand(intent, flags, startId);
}
//手动停止程序后会终止服务,会调用onDestroy()方法
@Override
public void onDestroy() {
System.out.println("*****onDestroy******");
super.onDestroy();
}
}
3.添清单文件中添加一个service
<service android:name="com.example.servicedemo.MyService"></service>
2.服务的两种开启方式
API
方式1
直接启停
startService(intent);
stopService(intent);
方式2
绑定服务的方式
bindService(intent, conn, BIND_AUTO_CREATE);
unbindService(conn);
例程
在一个程序里如果配置了某个服务,那么不管如何new,始终只有那一个服务。
public void click1(View v)
{
//click1和click2 每次创建service都是一个东西 说明一个服务开启了就只存在一份
Intent intent = new Intent(MainActivity.this, ServerDemo.class);
startService(intent);
}
public void click2(View v)
{
//click1和click2 每次创建service都是一个东西 说明一个服务开启了就只存在一份
Intent intent = new Intent(MainActivity.this, ServerDemo.class);
stopService(intent);
}
public void click3(View v)
{
Intent intent = new Intent(MainActivity.this, ServerDemo.class);
conn = new MyServiceConnection();
bindService(intent, conn, BIND_AUTO_CREATE);
}
public void click4(View v)
{
unbindService(conn);
}
//这里注意,使用bind的方法必须实现这个类,用于监控绑定状态
private class MyServiceConnection implements ServiceConnection
{
//绑定成功回调
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
//解除绑定回调
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
3.使用绑定获取服务中的方法
绑定服务的应用场景
应用场景:
1、需要在后台运行一定的业务逻辑,而且需要与服务器端交互数据,都是写在服务里面的。
2、天气预报、股票行情软件;
API
bindService绑定服务、unBindService解除绑定的服务;
服务是在被绑定的时候被创建,调用oncreate、onbind方法;
服务只能被绑定一次;
服务只能被解除一次,接触绑定的时候调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常;
推荐的方式(启用顺序):
1.startService:开启并创建一个服务,服务长期运行在后台;
2.bindService:绑定服务,可以调用服务里面的方法;
3.unBindService:解除服务,停止服务里面的方法;
4.stopService:停止服务,销毁服务对象;
例程
注意,我们需要在后台开启一个服务,这个服务一直在运行。可以通过前台调用后台服务中的函数,从而进行应用程序和服务交互。
startService(intent);方法可以创建一个服务,如果不手动关闭(假定操作系统没有回收这个服务),适用于创建一个后台服务。
bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);方法用于绑定一个服务。在startService方法后调用。
1.MainActivity
public class MainActivity extends Activity {
private MyBind serverRet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(MainActivity.this, BackgroundService.class);
startService(intent);
bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);
}
public void click1(View v)
{
//调用服务的方法
serverRet.callPaly();
}
public void click2(View v)
{
serverRet.callPause();
}
public void click3(View v)
{
serverRet.callReplay();
}
class MyServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//返回服务中包含要调用方法的类
serverRet = (MyBind) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
Service
public class BackgroundService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new MyBind(); //返回到前台的对象,包含要执行的service中的方法
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void paly() {
System.out.println("********paly********");
}
public void pause() {
System.out.println("********pause********");
}
public void replay() {
System.out.println("********replay********");
}
//继承Binder类,这是因为要返回一个实现IBinder类型接口的 实现Iservice方法,这个接口里面的函数都是我们自己定义的要传给前台的函数
public class MyBind extends Binder implements Iservice
{
@Override
public void callPaly() {
paly();
}
@Override
public void callPause() {
pause();
}
@Override
public void callReplay() {
replay();
}
}
}
Iservice 接口中定义我们要传递的方法
public interface Iservice {
public void callPaly();
public void callPause();
public void callReplay();
}
4.获取其他进程的服务的方法
1.接口需要修改,将后缀名改为aidl(android interface defination language),并将包含这个接口的包名拷贝,在客户端也创建一个这个名字的包,也把这个aidl文件拷贝过去。
package com.example.ipc_server;
interface Iservice {
void callServerFun();
}
2.服务端清单文件中配置service,由于是调用不同程序的服务,所以使用隐式意图。action的name是由我们自己指定,客户端在创建隐式intent时需要写入名字,就是这个字符串。
<service android:name="com.example.ipc_server.MyServer">
<intent-filter>
<action android:name="com.example.ipc_server"/>
</intent-filter>
</service>
3.客户端
public class MainActivity extends Activity {
private Intent intent;
private ServiceConnection conn;
private Iservice serviceRet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//开启意图
intent = new Intent();
intent.setAction("com.example.ipc_server");
//绑定服务
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
public void click(View v)
{
try {
serviceRet.callServerFun();
} catch (RemoteException e) {
e.printStackTrace();
}
}
class MyConn implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("*********启动服务**********");
serviceRet = Iservice.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
5.使用服务注册监听器
两种注册类型的区别:
静态注册是当程序关闭后,如果有广播发过来,还能启动程序
动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能在接收到广播的
动态注册的优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。
静态注册的有点:动态注册广播接收器还有一个优点就是当用来注册广播的Activity关闭后,广播也就失效了,同时反映了静态注册广播的一个优势,就是无需担心广播接收器是否关闭,只要设备处于开启状态,广播接收器就能接收。
操作频繁的广播事件,如果只是在清单配置文件配置,是不生效的。需要使用代码注册才能生效;
步骤:
// 注册广播接收者
// 1、得到广播接收者的对象
ScreenBroadCastReceiver screenReceiver = new ScreenBroadCastReceiver();
// 2、创建一个intentFilter对象
IntentFilter filter = new IntentFilter();
// 3、注册接收的事件类型
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
// 4、注册广播接收者
this.registerReceiver(screenReceiver, filter);