Service的基本知识点:
一、 Service简介
Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。
Service的启动有两种方式:context.startService() 和 context.bindService()
二、 Service启动流程
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会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。
所以调用startService的生命周期为: onCreate --> onStart (可多次调用) --> onDestroy
context.bindService()启动流程:
context.bindService() -> onCreate() -> onBind() -> Service running -> onUnbind() -> onDestroy() -> Service stoponBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。
所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。
三、 Service生命周期
Service的生命周期并不像Activity那么复杂,它只继承了onCreate()、onStart()、onDestroy()三个方法
当我们第一次启动Service时,先后调用了onCreate()、onStart()这两个方法;当停止Service时,则执行onDestroy()方法。
这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。
它可以通过Service.stopSelf()方法或者Service.stopSelfResult()方法来停止自己,只要调用一次stopService()方法便可以停止服务,无论调用了多少次的启动服务方法。
使用过程
1。分析客户端需要的功能。将功能抽象成接口。
2。按照AIDL文件编写规则(SDK的AIDL专题)编写AIDL文件。假设命名为IA.aidl。
3。在GEN中自动生成对应的JAVA文件。
4。使用公共类或者在service中的内部类来实现IA.Stub接口的抽象方法。实现AIDL的服务端功能。
假设你写的实现类的名称是IAimpl
5。在service的onbind中以IA.Stub的类型,返回IAimpl的一个实例。
6。在客户端的conn接口实现中的onServiceConnected方法中,
使用IA.Stub.asInterface(service)的方式返回一个IA实现类。
通过这个实现类我们就可以使用AIDL远程调用的方法了。
注意:
1.AIDL的编写规则。具体在SDK的“docs\guide\developing\tools\aidl.html”目录下。
2.注意IA接口功能的实现是在IA.Stub实现类中实现的。
3.可以不去了解自动生成的那个JAVA文件的工作细节。个
定义一个简单的个人信息接口,有三个属性,姓名、年龄、显示姓名和年龄,注意后缀名为.aidl,后缀名写错了就不灵了。
package com.demo.www;
interface IPerson{
void setAge(int age);
void setName(String name);
String display();
}
写一个类继承自Service,包什么的就不导入了,这个可以自动导
public class MyService extends Service {
// 申明我们代理类的实例。
// 声明IPerson.Stub类型。这是一种方法,下一节介绍另一种方法
IPerson.Stub person = new Newperson();
@Override
public IBinder onBind(Intent intent) {
return person;
}
}
//下面这个就是我们IPerson.aidl的实现类。
//功能要在这个类中实现。
//实现后要在service中返回这个类的实例。
class Newperson extends IPerson.Stub
{
private int age = 27;
private String name = "lala";
public void setAge(int age) throws RemoteException {
// TODO Auto-generated method stub
this.age = age;
}
public void setName(String name) throws RemoteException {
// TODO Auto-generated method stub
this.name = name;
}
public String display() throws RemoteException {
// TODO Auto-generated method stub
return new StringBuffer().append("名字:").append(name).append(" 年龄:").append(age).toString();
}
}
下面这个是Activity调用Service的那个主界面,包名自己导入,
public class Service5Activity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
LinearLayout lv;
EditText et1,et2;
TextView tv;
Button bt;
ServiceConnection conn;
IPerson p;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
lv = new LinearLayout(this);//动态new 一个布局文件
et1 = new EditText(this);
et2 = new EditText(this);
tv = new TextView(this);
bt = new Button(this);
bt.setText("display");
bt.setOnClickListener(this);
lv.setOrientation(LinearLayout.VERTICAL);
lv.addView(et1);
lv.addView(et2);
lv.addView(bt);
lv.addView(tv);
setContentView(lv);
//用AIDL的好处,1隐藏Serivice,2让其它程序调用实现特定功能
conn = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
// 使用这句话获取IPerson的实现类句柄,通过这个句柄实现功能。这是方法其一,下节是另外一种方法
p = IPerson.Stub.asInterface(service);
}
};
bindService(new Intent(this,MyService.class), conn, Service.BIND_AUTO_CREATE);
}
public void onClick(View v) {
// TODO Auto-generated method stub
try {
// setAge,setName,setDisplay都在Newperson中实现的。
// 我们客户端可以不用考虑细节,直接使用即可。
p.setAge(Integer.parseInt(et2.getText().toString()));
p.setName(et1.getText().toString());
tv.setText(p.display());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
例子很简单,不多说了,说多了污染大家的智商,如果各位大虾们觉得太简单了,希望不要拍砖过来,哥身材瘦小,经不起拍。这主要是给哥我温习用的