本节前言
前面简单的介绍了本地服务和远程服务,以及Service的生命周期,今天就讲解一下Service通信服务以及前台service(即前台服务和后台服务)
1.1可通信服务
- 本地Service是最基础的,但只能单机使用,即无法与Activity通信
- 接下来将在本地服务的基础用法上,增设“与Activity通信”的功能,即使用绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())
1.2实例Demo
- 步骤1:在新建子类继承Service类,并新建一个子类继承自Binder类、写入与Activity关联需要的方法、创建实例
public class MyService extends Service {
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("执行了onBind()");
//返回实例
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("执行了onUnbind()");
return super.onUnbind(intent);
}
//新建一个子类继承自Binder类
class MyBinder extends Binder {
public void service_connect_Activity() {
System.out.println("Service关联了Activity,并在Activity执行了Service的方法");
}
}
}
步骤2:在主布局文件再设置四个Button分别用于启动,停止,绑定和解绑Service,因为比较简单这里就不写了
步骤3:在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系
即实现了Activity指挥Service干什么Service就去干什么的功能
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button startService;
private Button stopService;
private Button bindService;
private Button unbindService;
private MyService.MyBinder myBinder;
//创建ServiceConnection的匿名类
private ServiceConnection connection = new ServiceConnection() {
//重写onServiceConnected()方法和onServiceDisconnected()方法
//在Activity与Service建立关联和解除关联的时候调用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//在Activity与Service解除关联的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//实例化Service的内部类myBinder
//通过向下转型得到了MyBinder的实例
myBinder = (MyService.MyBinder) service;
//在Activity调用Service类的方法
myBinder.service_connect_Activity();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.startService);
stopService = (Button) findViewById(R.id.stopService);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
bindService = (Button) findViewById(R.id.bindService);
unbindService = (Button) findViewById(R.id.unbindService);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//点击启动Service
case R.id.startService:
//构建启动服务的Intent对象
Intent startIntent = new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
break;
//点击停止Service
case R.id.stopService:
//构建停止服务的Intent对象
Intent stopIntent = new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
break;
//点击绑定Service
case R.id.bindService:
//构建绑定服务的Intent对象
Intent bindIntent = new Intent(this, MyService.class);
//调用bindService()方法,以此停止服务
bindService(bindIntent,connection,BIND_AUTO_CREATE);
//参数说明
//第一个参数:Intent对象
//第二个参数:上面创建的Serviceconnection实例
//第三个参数:标志位
//这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service
//这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行
break;
//点击解绑Service
case R.id.unbindService:
//调用unbindService()解绑服务
//参数是上面创建的Serviceconnection实例
unbindService(connection);
break;
default:
break;
}
}
}
1.3测试结果
2.1前台Service
前台Service和后台Service(普通)最大的区别就在于:
前台Service在下拉通知栏有显示通知(如下图),但后台Service没有;
前台Service优先级较高,不会由于系统内存不足而被回收;后台Service优先级较低,当系统出现内存不足情况时,很有可能会被回收
进程优先级(递增顺序)
空进程 后台进程 服务进程 可见进程 前台进程
2.2具体使用
其实在前面我们也已经讲解过,就是notification 消息通知控件
用法很简单,只需要在原有的Service类对onCreate()方法进行稍微修改即可,如下图:
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
//添加下列代码将后台Service变成前台Service
//构建"点击通知后打开MainActivity"的Intent对象
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
//新建Builer对象
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服务通知的标题");//设置通知的标题
builer.setContentText("前台服务通知的内容");//设置通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
builer.setContentIntent(pendingIntent);//设置点击通知后的操作
Notification notification = builer.getNotification();//将Builder对象转变成普通的notification
startForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来
}