绑定式服务是安卓编程过程中不可回避的一个问题,而且再完成客户端与服务端的交互方面有得天独厚的优势,但是在刚开始学习的时候,这一部分的编程思路比较难以理解,结合自己的所学心得,笔者从新手角度分析绑定时服务的应用方法。
绑定时服务实现步骤
运用基本的程序对绑定式服务的编码步骤进行归纳:
1. 自定义服务类
GetDistanceService
private Random random=new Random();
private IBinder mybinder=new IBinder();
public GetDistanceService() {
}
public class IBinder extends Binder {
GetDistanceService getGetDistanceService(){
return GetDistanceService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mybinder;
}
public double getDistance(){
return random.nextDouble();
}
其中特别需要注意的是要自定义一个Bind的子类IBinder ,这个类对于绑定时服务的内容实现来说非常重要,IBinder 类可以理解为一个服务和前台Activity的通道,可以在自定义的IBinder 子类中结合实际添加一些功能方法,而后将onBind(Intent intent)函数的返回值改为自定义IBinder 子类的一个实例。在自定义的服务类中,可以自定义一些方法(本文中为 getDistance)便于前台调用。
2. 实例化ServiceConnection类
在前台的Activity类中新建ServiceConnection类的实例conection作为成员变量,在OnCreate()方法中将conection变量实例化。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
GetDistanceService.IBinder binder = (GetDistanceService.IBinder) service;
disService = binder.getGetDistanceService();
binded = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
binded = false;
}
};
displayDis();
}
ServiceConnection类是实现前端Activity和服务交互功能的关键,里面定义了前台需要调用那些服务端的功能,也就是交互的逻辑定义。但是在此时尚未绑定服务。
3. 在前台的Activity类的OnStart()方法中绑定服务
super.onStart();
Intent intent = new Intent(MainActivity.this, GetDistanceService.class);
这一环节必须在onCreate()方法之后,因为在上一步完成了ServiceConnection变量的实例,通过 bindService(intent, connection, BIND_AUTO_CREATE)完成了服务绑定工作
4.在界面Activity中进行完成相应的功能实现
MainActivity
private ServiceConnection connection;
private GetDistanceService disService;
private Boolean binded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
GetDistanceService.IBinder binder = (GetDistanceService.IBinder) service;
disService = binder.getGetDistanceService();
binded = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
binded = false;
}
};
displayDis();
}
private void displayDis() {
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
if (disService != null || binded) {
TextView disText = findViewById(R.id.destanceDisplay);
disText.setText(Double.toString(disService.getDistance()));
} else
Toast.makeText(MainActivity.this, "disService=null", Toast.LENGTH_LONG);
handler.postDelayed(this, 1000);
}
});
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(MainActivity.this, GetDistanceService.class);
bindService(intent, connection, BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(connection);
}
关键解读
ServiceConnection的主要功能是运用Service交互传递过来的Bind类的实例完成功能逻辑的准备工作,比如说获取服务类实例等。
Bind类主要是提供给前端Activity与服务交互的通道,类似于信使之类,是交互的介质
要注意bindService()的调用时机,一定要在ServiceConnection实例化之后,否则会出错。
希望对你有所帮助,谢谢!