安卓学习之四大组件之服务

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

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值