service的作用
service用于在后台完成用户指定的操作
比如说,我们播放音乐,在后台播放音乐。比如说,我们下载任务,在后台下载文件。这些都是没有界面的后台运行程序,这些都是用服务做的
1)service分为两种
a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。
b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。
2)startService()与bindService()区别
(a)started service(启动服务)是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。
(b)使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点
3)开发人员需要在应用程序配置文件中声明全部的service,使用<service></service>标签。
4)Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态
bindService绑定开启的服务,在系统里是看不到服务在运行的:
如果是通过startService的方式启动的服务,则会在应用里看到
第三方调用服务,需要现在服务配置申明,允许被外部调用 |
服务的生命周期:onCreate()方法,onDestroy()方法,onStartCommand()方法
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"创建服务Service");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"启动服务");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"销毁Service");
}
服务的两种启动方式
采用StartService()方式启动服务
1.注册,四大组件均需要注册
2.intent进行通信,startService()进行开启服务,stopService()结束服务。
@Override
public void onClick(View v) {
if(v == create){
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
startService(intent);
}else if(v == destroy){
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
stopService(intent);
}
}
采用绑定的方式启动服务,调用服务内部方法:(内部应用调用内部方法)
1.Service里面必须实现onBind()方法,回传结果为IBinder的对象,创建内部类继承自Binder类,该类实现IBinder接口
2.进行服务绑定,也是另外一种开启服务的方式,只有进行绑定服务后才能进行调用服务内部方法,第一种开启服务方式不能进行调用。绑定服务通过Intent进行通信,通过bindService进行绑定。传递的参数需要实现ServiceConnection()接口,并实现两个方法,onServiceConnected()和onServiceDisconnected(),onServiceConnected()方法中的service参数接受的就是服务方onBind()传递过来的对象,也就是对应的实现了IBinder接口的内部类。
ServiceConnection是一个接口,也可创建内部类实现该接口的方法
private class serviceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG,"name===>"+name);
Log.d(TAG,"service==>"+service);
//service就是Service必须实现的onBind()传递过来的IBind类实现的对象
//FirstService.innerBinder iBinder = (FirstService.innerBinder) service;可访问的内部类
iBinder =(services) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG,"name:"+name);
iBinder = null;
}
};
Log.d(TAG,"服务已经绑定");
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
mServiceConnection = new serviceConnection(); //实例化实现了ServiceConnection接口的方法
bindService = bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
服务绑定后需要解绑,否则会造成内存泄漏
//判断服务是否已经绑定
if (mServiceConnection != null && bindService == true) {
unbindService(mServiceConnection);
bindService = false;
mServiceConnection = null;
iBinder = null; //服务层onBind()方法传递过来的IBinder对象
}
详细过程
FirstService.java:
public class FirstService extends Service {
private static final String TAG = FirstService.class.getName();
public class innerBinder extends Binder{
public void callService(){
sayHello();
}
}
private void sayHello() {
Log.d(TAG,"say hello !!!");
Toast.makeText(this,"你好鸭",Toast.LENGTH_SHORT).show();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new innerBinder();
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"创建服务Service");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"启动服务");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"销毁Service");
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getName();
private Button create;
private Button destroy;
private Button bind;
private Button unBind;
private boolean bindService;
private FirstService.innerBinder iBinder;
private Button apply;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitVeiw();
InitListener();
}
private void InitListener() {
create.setOnClickListener(this);
destroy.setOnClickListener(this);
bind.setOnClickListener(this);
unBind.setOnClickListener(this);
apply.setOnClickListener(this);
}
private void InitVeiw() {
create = this.findViewById(R.id.create);
destroy = this.findViewById(R.id.destroy);
bind = this.findViewById(R.id.Bind);
unBind = this.findViewById(R.id.unBind);
apply = this.findViewById(R.id.apply_inner_method);
}
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG,"name===>"+name);
Log.d(TAG,"service==>"+service);
//service就是Service必须实现的onBind()传递过来的IBind类实现的对象
//FirstService.innerBinder iBinder = (FirstService.innerBinder) service;
iBinder = (FirstService.innerBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG,"name:"+name);
iBinder = null;
}
};
@Override
public void onClick(View v) {
//开启服务
if(v == create){
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
startService(intent);
//销毁服务
}else if(v == destroy){
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
stopService(intent);
//绑定服务
}else if(v == bind){
Log.d(TAG,"服务已经绑定");
Intent intent = new Intent();
intent.setClass(this,FirstService.class);
bindService = bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
//解绑服务
}else if(v == unBind){
Log.d(TAG,"服务解绑");
//判断服务是否已经绑定
if (mServiceConnection != null && bindService == true) {
unbindService(mServiceConnection);
iBinder = null;
}
}else if(v == apply){
Log.d(TAG,"调用服务内部方法!");
iBinder.callService();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动服务"
android:id="@+id/create"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="销毁服务"
android:id="@+id/destroy"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定服务"
android:id="@+id/Bind"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解绑服务"
android:paddingLeft="3dp"
android:id="@+id/unBind"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用服务内部方法"
android:id="@+id/apply_inner_method"
/>
</LinearLayout>
2.接口方法实现内部类被调用过程
接口方法实现内部类不被外面访问:将内部类修改为private,内部方法不被外界访问,申明接口实现的方法才可以被该方法,直接在想要访问服务方的service强转为该接口,调用该接口即可实现访问。
通过定义接口直接通过接口调用另一个类中的私有方法
程序猿拉大锯p7第15讲
安卓接口定义语言AIDL