Android中的服务,没有界面在后台长期运行的,四大组件之一,service 和activity 有血缘关系 service 辈分大一些 是activity的 叔叔
代码手动开启服务并关闭:
// 开启服务
public void click(View v) {
// 开启服务和 开启activity的方式 一模一样
Intent service = new Intent();
service.setClass(this, FirstService.class);
startService(service);
}
// 停止服务
public void click1(View v) {
Intent service = new Intent();
service.setClass(this, FirstService.class);
stopService(service);
}
FirstService 为继承Service类并在清单文件中注册。
通过在服务中注册广播接收者,实现监听屏幕的开启与关闭,广播注册使用动态注册
定义Service:
public class ScreenService extends Service {
private ScreenReceiver receiver;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
// 服务中注册特殊的广播接收者
// 和在activity的方式 一模一样
// 记得在服务销毁的时候 注销
// 不注销会漏气
receiver = new ScreenReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
registerReceiver(receiver, filter);//动态注册广播需要在 服务销毁的时候注销广播接收者
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// 注销
unregisterReceiver(receiver);
}
}
定义广播接收者:
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.intent.action.SCREEN_ON")) {
System.out.println("屏幕亮了");
}
if (action.equals("android.intent.action.SCREEN_OFF")) {
System.out.println("屏幕灭了");
}
}
}
在清单文件注册:
<receiver android:name="cn.test.registbroadcast.ScreenReceiver">
<intent-filter >
<action android:name="android.intent.action.SCREEN_ON"/>
<action android:name="android.intent.action.SCREEN_OFF"/>
intent-filter>
receiver>
<service android:name="cn.test.registbroadcast.ScreenService">
service>
启动服务:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动服务
startService(new Intent(this, ScreenService.class));
}
为什么前面已经有start方式开启服务还要搞一个bind服务方式?
因为是为了调用服务里的方法。
步骤:
public class BanzhengService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
//返回代理人对象
return new MyBinder();
}
public void banZheng(int money){
if (money>=500) {
System.out.println("大兄弟,明天来拿证..");
}else{
System.out.println("小伙子,今天比较忙,下次再说吧");
}
}
//代理对象
//Binder 是Ibinder 的实现类
class MyBinder extends Binder{
//创建和服务中一样 参数一样的 返回值 不一样 的方法名的 方法
public void callbanzheng(int money){
banZheng(money);
}
}
}
在activity中开启服务:
public class MainActivity extends Activity {
private MyBinder binder;
private MyServiceConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service=new Intent();
service.setClass(this, BanzhengService.class);
conn = new MyServiceConn();
bindService(service, conn, BIND_AUTO_CREATE);
}
//点击办证
public void click(View v){
binder.callbanzheng(49999999);
}
class MyServiceConn implements ServiceConnection{
//当服务连接成功的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//解绑 服务
unbindService(conn);
}
}
注意:服务需要在清单文件里注册(这里就不贴上代码了)
通过抽取接口方式,我们可以在服务中指定向外部曝露相应的方法,这样更符合面向对象编程:
定义含有指定方法的接口:
public interface Iservice {
public void callbanzheng(int money);
public void calldaqiu();
}
再定义服务:
public class BanzhengService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
//返回代理人对象
return new MyBinder();
}
public void banZheng(int money){
if (money>=500) {
System.out.println("大兄弟,明天来拿证..");
}else{
System.out.println("小伙子,今天比较忙,下次再说吧");
}
}
public void daqiu(){
System.out.println("打球");
}
//代理对象
//Binder 是Ibinder 的实现类
private class MyBinder extends Binder implements Iservice{
//创建和服务中一样 参数一样的 返回值 不一样 的方法名的 方法
public void callbanzheng(int money){
banZheng(money);
}
public void calldaqiu(){
daqiu();
}
}
}
在activity中bind服务并调用相应的服务中的方法:
public class MainActivity extends Activity {
private Iservice iservice;
private MyServiceConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1 创建一个接口
//2 让mybinder 实现 接口
//3 接口中 写入 想要暴露的方法
//4在activity 获取的 就是接口
//5 使用接口调用代理人对象暴露出来的方法
Intent service=new Intent();
service.setClass(this, BanzhengService.class);
conn = new MyServiceConn();
bindService(service, conn, BIND_AUTO_CREATE);
}
//点击办证
public void click(View v){
iservice.callbanzheng(588);
}
class MyServiceConn implements ServiceConnection{
//当服务连接成功的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iservice = (Iservice) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//解绑 服务
unbindService(conn);
}
}
顾名思义,我们可以选择start方式开启服务也可以同时选择bind方式开启服务,当时要注意以下:
先 start 还是 先bind 没有影响但是必须要先 unbind 才能stop