Android 四大组件之Service的启动、绑定小述

版权声明:转载请声明: https://blog.csdn.net/MingJieZuo/article/details/83384293

一、概述

学习过Android的小伙伴就不可能不知道Service是什么,因为Service是Android四大组件之一,声名赫赫有木有,所以在这里我就不详细介绍了,本节主要还是充当笔记的作用,因为我待记性如初恋,记性虐我千百遍。

二、Service的创建

Service是一种无界面交互的android组件,并不同于一般服务的概念,它并不意味着Service将创建线程或者进程,事实上默认情况下,Service总是运行在主线程之中,所以它本身并不能做耗时操作,否则就会导致ANR。创建Service的方式很简单,只要继承Service类即可,我们来看下代码

    public class MyService extends Service {

        @Nullable 
        @Override 
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public void onCreate() {
            super.onCreate();
            Log.i("Tag", "onCreate");
        }
    }

在Manifest清单文件中注册该Service

        <service android:name=".MyService">
            <intent-filter>
                <action android:name="com.servicetest.MyService" />
            </intent-filter>
        </service>

三、Service的工作状态

Service分为两种工作状态,一种是启动状态,我们通过startService的方式启动,主要用于执行后台计算,例如下载任务、播放音乐、文件I/O等场景;另一种是绑定状态,通过bindService的方式绑定,主要用于其他组件与Service的交互,Service提供公共的功能,供自己或其它应用来调用,例如系统的传感器服务、定位服务等场景。需要注意的是,这两种状态是可以共存的,即Service既可以处于启动状态,又可以同时处于绑定状态。下面我们就来具体的看下两种状态和之间的差别:

(1)startService启动服务

如果一个组件通过startService启动一个Service,那么Service就会独立运行,不再与该组件产生任何关系。启动的代码也很简单

        Intent startServiceIntent = new Intent("com.servicetest.MyService");
        startService(startServiceIntent);

当然我们也可以通过stopService来手动结束该Service

        stopService(startServiceIntent);

好了,启动方法是不是非常简单,接下来我们就简单分析下startService()启动服务时,Service的生命周期方法,正常情况下,系统会先调用服务的onCreate()方法,接着调用onStartCommand()方法。

        onCreate()>>onStartCommand()

当然,当我们通过stopService结束服务时,系统会先调用服务的onDestroy()方法

        onDestroy()

需要注意的是,当我们多次调用startService启动同一个服务时,该服务的onCreate()方法并不会多次调用,但是onStartCommand()方法会被调用多次

(2)bindService绑定服务

通过bindService绑定(启动)一个服务后,Service会为该组件提供一个接口,我们可以通过该接口实现组件与Service的交互。代码也很简单

    public class MainActivity extends AppCompatActivity {

        ServiceConnection conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                // iBinder即服务连接后返回的接口,我们通过该接口来调用Service提供的功能
            }
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        };

        private void startService() {
            // 开启服务
            Intent startServiceIntent = new Intent("com.servicetest.MyService");
            bindService(startServiceIntent, conn, BIND_AUTO_CREATE);
        }

        private void stopService() {
            // 解除绑定,结束服务
            unbindService(conn);
        }
}

好了,绑定服务也不是难点,同样的,我们也来分析下,当我们bindService绑定一个服务时,Service的生命周期方法,正常情况下,系统会先调用服务的onCreate()方法,接着调用onBind()方法。

        onCreate()>>onBind()

这个时候组件和Service就绑定在了一起,一旦调用者退出了,那么系统就会先调用Service的onUnbind()方法,随后调用Service的onDestroy()方法。当然我们也可以直接通过unbindService()方法解除与当前服务的连接,调用该方法也会导致系统调用Service的onUnbind()方法,随后调用Service的onDestroy()方法。

        onUnbind()>>onDestroy()

需要注意的是,如果调用bindService前服务已经被绑定,那么多次调用bindService并不会导致多次创建与绑定服务,也就是说,Service的onCreate()方法和onBind()方法不会重复调用

四、Service的通信

当我们创建一个Service后,调用者该怎么与Service进行通信呢?例如传值或者调用Service提供的方法,下面我们就来简单看下几种情况:

(1)startService的Intent传值

当我们在Activity中开启一个Service时,我们可以通过Intent进行通信,代码如下,在这里我们是通过startService方式开启的

        private void startService() {
            Intent startServiceIntent = new Intent("com.servicetest.MyService");
            startServiceIntent.putExtra("intent_tag", 0);
            startService(startServiceIntent);
        }

当然相应的,在我们的Service中,我们要通过onStartCommand()方法获取数据

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // 能够接收调用者传递过来的数据
            if(intent != null){
                int tag = intent.getIntExtra("intent_tag", -1);
                Log.i("Tag", "onStartCommand"+tag);
            }
            return super.onStartCommand(intent, flags, startId);
        }

(2)bindService的Intent传值

当我们通过bindService方式绑定一个服务时,我们也可以通过Intent进行数据传递,操作方法与startService方式类似

        private void startService() {
            Intent startServiceIntent = new Intent("com.servicetest.MyService");
            startServiceIntent.putExtra("intent_tag", 0);
            bindService(startServiceIntent, conn, BIND_AUTO_CREATE);
        }

与startService方式不同的是,我们需要在已绑定的服务的onBind方法中获取数据

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            // 能够接收调用者传递过来的数据
            if(intent != null){
                int tag = intent.getIntExtra("intent_tag", -1);
                Log.i("Tag", "onBind"+tag);
            }
            return null;
        }

(3)bindService的IBinder方法调用

当我们通过bindService方式绑定一个服务后,我们还能进行更为灵活的交互,例如直接调用Service内的方法

    public class MyService extends Service {

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            // 能够接收调用者传递过来的数据
            if(intent != null){
                int tag = intent.getIntExtra("intent_tag", -1);
                Log.i("Tag", "onBind"+tag);
            }
            return new MyIbinder();
        }

        @Override
        public void onCreate() {
            super.onCreate();
            Log.i("Tag", "onCreate");
        }

        class MyIbinder extends Binder {
            // 我们通过内部类MyIbinder的方法,调用Service的方法或属性
            public String getName() {
                return getServiceDescription();
            }
        }

        private String getServiceDescription() {
            return this.getPackageName() + "MyService";
        }

        @Override
        public boolean onUnbind(Intent intent) {
            Log.i("Tag", "onUnbind");
            return super.onUnbind(intent);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i("Tag", "onDestroy");
        }
    }

我们在Activity中通过ServiceConnection匿名类来调用Service中的方法,实现与Service的交互

        ServiceConnection conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                MyService.MyIbinder binder = (MyService.MyIbinder)iBinder;
                String description = binder.getName();
                Log.i("Tag","description:" + description);
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        };

五、总结

本节主要简单介绍了Service的创建、启动、绑定和与Activity交互的方法,如果想要查看更多Service的基础知识,去我的博客目录里查看吧,因为关于每块知识点的介绍,博客单节写的比较零散,不容易查找。

猜你喜欢

转载自blog.csdn.net/MingJieZuo/article/details/83384293
今日推荐