《一:startService方式开启服务》
1.在AndroidManifest.xml中的Application中配置服务组件:
<service android:name="com.example.helloservice.MyService" />
2.创建一个类继承Service,并覆写 onCreate,onStartCommand,onDestory方法:
public class MyService extends Service{
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
Log.v("aaa", "创建服务");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("aaa", "开启服务");
}
@Override
public void onDestroy() {
Log.v("aaa", "结束服务");
}
}
3.在MainActivity中启动和停止服务:
Intent intent = new Intent(this, MyService.class);
//开启服务
startService(intent);
//停止服务
stopService(intent);
4.小结:
4.1: 启动服务只能通过代码的形式,关闭服务还可以通过手机设置中手动关闭
4.2: 应用界面退出后,如果不调用代码关闭并且内存足够,服务还是存在的
4.3: 执行顺序:
starService:onCreate->onStartCommand
stopService:onDestroy
《二:bindService方式开启服务》
1.在AndroidManifest.xml中的Application中配置服务组件:
<service android:name="com.example.helloservice.MyService" />
2.定义类MyService继承Service:
2.1:复写四大生命周期方法:onCreate(),onBind(),onUnbind(),onDestroy();
2.2:onBinder返回的是IBinder接口,而实现IBinder的有Binder类,故自定义一个类
MyBinder继承Binder,在MyBinder中添加要实现的方法。
2.3:在onBinder方法中返回MyBinder对象 ,一旦返回此对象,MainActivity中的bindService中的ServiceConnection类中的onServiceConnected方法将被调用,否则它不会被调用。
2.4:要规定MyService中的方法只能是固定的,可采用
2.4.1:MyBinder类实现自定义接口IService方法。
2.4.2:MyBinder类私有化,外界只能通过onBinder返回MyBinder对象,然后用IService接口接收
来仅仅调用IService接口中规范好的方法,具体代码如下:
public class MyService extends Service{
private class MyBinder extends Binder implements IService{
@Override
public void show() {
showToast();
}
}
public void showToast(){
Toast.makeText(this, "服务显示", Toast.LENGTH_SHORT).show();
}
@Override
public void onCreate() {
Log.v("aaa", "开始服务");
}
@Override
public IBinder onBind(Intent arg0) {
Log.v("aaa", "onBind");
return new MyBinder();
}
@Override
public boolean onUnbind(Intent intent) {
Log.v("aaa", "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.v("aaa", "结束服务");
}
}
3.MainActivity中
//开启服务:
Intent intent = new Intent(this, MyService.class);
//ServiceConnection对象定义成全局变量,停止服务时要用到
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("aaa", "onServiceDisconnected");
}
//onBinder中返回不空执行此方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("aaa", "onServiceConnected");
mBinder = (IService)service;
}
};
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
//关闭服务:
unbindService(mServiceConnection);
//调用IService中的某个服务:
mBinder.show();
4.服务执行顺序:(就是不调用:onStartCommand)
4.1:开启服务:onCreate->onBinder->onServiceConnected(MainActivity中的)
4.2: 启用服务:mBinder.show();
4.2:关闭服务:onUnbind->onDestory
5.关闭界面后服务自动关闭。
6.startService后台中能一直运行,但是不能与服务交互;
bindService后台中不能一直运行,但是能和服务交互数据。
7.startService和bindService联合使用:
开启服务:onCreate->onStartCommand
绑定服务:onBind->onServiceConnected(若开启服务启动了onCreate,绑定服务不调用onCreate)
解绑服务:onUnbind(此时开启服务后,服务驻留内存,解绑服务就不会调用onDestory,若只先前只绑定服务就会调用onDestory函数)
关闭服务:onDestory
8.服务和子线程的区别:
8.1:服务是安卓四大组件之一(类),而子线程只是一个对象而已。
8.2:当关闭进程时,子线程被杀死,服务也被杀死,然后服务又会复活:
系统认为服务之所以被杀死,是当前的应用进程被杀死,进程被杀死可能
是因为内存不足而造成的,后来发现内存充足又启动服务,内存不足才可
能让服务挂。
《三:在Activity中实时获取来自Service中百度定位监听器中的BDLocation对象》
1.在MainActivity中,定义一个Handler对象,并且之后的处理也是在handleMessage中处理:
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
BDLocation location = (BDLocation) msg.obj;
initMyLocationConfig(location);
}
};
2.在开启服务时,将mHandler对象与Messenger对象绑定:
private void startMyService(){
mIntent = new Intent(this, LocationService.class);
mIntent.putExtra("messenger", new Messenger(mHandler));
startService(mIntent);
startMyBinder(mIntent);
}
3.在Service中,通过Messenger对象send消息就会实时传到mHandler中,而mHandler也会实时处理:
//先在LocationService中初始化mMessenger,得到MainActivity中传来的Messenger对象
mMessenger = (Messenger) intent.getExtras().get("messenger");
@Override
public void onReceiveLocation(BDLocation location) {
try {
Message msg = new Message();
msg.obj = location;
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}