Android 组件Service(一)之startService()、bindService()

Android 组件Service(一)之startService()、bindService()


1.服务Service简介

服务(service)是Android中实现程序后台运行的程序,非常适合去执行那些不需要和用户交互还要长期运行的任务,其运行不依赖任何用户界面。
服务不是运行在一个独立的进程当中的,而是 依赖于创建服务时所在的应用程序进程。当应用程序的进程被杀掉时,所依赖于该进程的服务也会停止运行。
服务并不会自动开启线程,所有的代码都是默认在主线程当中的。这需要我们在服务内部手动创建子线程,并在这里执行具体的任务,否则可能出现主线程被阻塞住的情况。

2.服务基本用法

Service使用步骤如下:
1. 继承service类
2. AndroidManifast.xml配置清单文件中<application>节点里对服务进行注册<service name=".ServiceName"/>

服务不能自己运行,需要通过Contex.startService()或Contex.bindService()启动服务

2.1 startService()用法

通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService()或者stopSelf()方法,此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onStartCommand(),如果服务已经启动再次调用只会触发onStartCommand()方法,onStart方法在API 5时被废弃,替代它的是onStartCommand方法。

    public class MainActivity extends AppCompatActivity {
        private Button btn_startservice;
        private  Button btn_stopservice;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn_startservice = (Button) findViewById(R.id.btn_startserver);
            btn_stopservice = (Button) findViewById(R.id.btn_stopservice);

            btn_startservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                //借助Intent来实现启动服务
                    Intent startIntent = new Intent(MainActivity.this, StartService.class);
                    startService(startIntent);
                }
            });

            btn_stopservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    Intent stopIntent = new Intent(MainActivity.this, StartService.class);
                    //停止服务
                    stopService(stopIntent);
                }
            });
        }
    }
    //service类
    public class StartService extends Service {

        @Override
        public void onCreate(){
            super.onCreate();
            Log.d("startService", "onCreate executed");
        }
        @Override
        public int onStartCommand(Intent intent, int flag, int startId){
            Log.d("startService", "onStartCommand executed");
            return super.onStartCommand(intent, flag, startId);
        }
        @Override
        public void onDestroy(){
            super.onDestroy();
            Log.d("startService", "onDestroy executed");
        }
        @Override
        public IBinder onBind(Intent intent){
            throw new UnsupportedOperationException("Not yet implemented");
        }

    }
显示结果:
    02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onCreate executed
    02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onStartCommand executed
    02-21 09:10:07.933 3712-3712/com.example.servicetest D/startService: onStartCommand executed
    02-21 09:10:09.703 3712-3712/com.example.servicetest D/startService: onDestroy executed

应用程序界面中使用startservice按钮 调用onCreate() onStartCommand(),再次按只调用onStartCommand(),按stopservice按钮调用onDestroy()。

2.2 bindService()方式

使用bindService()启动的服务与调用者(Context)绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onBind(),如果服务已经启动再次调用不会再触发这两个方法,调用者退出(或不存在)时系统会调用服务的onUnbind()–>onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()–>onDestory(),
使用bindService可以实现与正在运行的service进行联系交流。而startService适合自己在后台长期运行,若与之交流频繁会造成性能问题。

    //创建一个Binder对象对下载功能进行管理
    public class DownBinderService extends Service {
        /**
         * 1. 添加了一个public内部类继承Binder,并添加两个方法;
         * 2. 新建一个IBinder对象——new那个Binder内部类;
         * 3. onBind方法返还那个IBinder对象。
         */
        private DownloadBinder mBinder = new DownloadBinder();
        //继承Binder的DownloadBinder内部类,并写了两个可被操作的方法。
        class DownloadBinder extends Binder {
            public void startDownload(){
                Log.d("DownBinderService", "startdownload");
            }
            public int getProgress(){
                Log.d("DownBinderService","getprogress..");
                return 0;
            }
        }

        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;

        }
    }
    //MainActivity中的onCreate()里写如下代码服务的绑定与解绑定
            btn_bindservice = (Button) findViewById(R.id.btn_bindservice);
            btn_unbindservice = (Button) findViewById(R.id.btn_unbindservice);

            btn_bindservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    Intent bindIntent = new Intent(MainActivity.this, DownBinderService.class);
                    //绑定服务
                    bindService(bindIntent, connection, BIND_AUTO_CREATE);
                }
            });
            btn_unbindservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    //解绑服务
                    unbindService(connection);
                }
            });
//MainActivity里写下面服务回调的代码
        private DownBinderService.DownloadBinder downloadBinder;
        //在Activity中,我们通过ServiceConnection接口来取得建立连接
    //    定义服务绑定的回调,传递给bindService()
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                downloadBinder = (DownBinderService.DownloadBinder) service;
                downloadBinder.startDownload();
                downloadBinder.getProgress();
            }
        //与服务联系中断的时候就调用这个方法
            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
    };

bindService()调用方法的步骤:

  • 在服务的内部创建一个内部类(如上述的DownloadBinder)提供方法,可以间接调用服务的方法
  • 实现服务的onBind()方法,返回的就是这个内部类DownloadBinder 的对象(实际也是IBinder对象)
  • 在Activity 绑定服务。
  • 在服务成功绑定的回调方法onServiceConnected, 会传递过来一个 IBinder对象
  • 强制类型转化为自定义的接口类型(如downloadBinder = (DownBinderService.DownloadBinder) service;),调用接口里面的方法。

创建了ServiceConnection匿名类,要重写其中的两个方法,在服务成功绑定和解绑定的时候调用。

绑定是异步进行的,bindService()将立即返回,并不会向客户端返回 IBinder 。为了接收 IBinder ,客户端必须创建一个 ServiceConnection 的实例,并把它传给 bindService()。 ServiceConnection 包含了一个回调方法,系统将会调用该方法来传递客户端所需的那个 IBinder。

注意:
只有activity、服务和content provider才可以绑定到服务上,不能从广播接收器(broadcast receiver)中绑定服务。

3. Service生命周期

两种Service方式的生命周期图

Bounded方式下在onUnbind() 还以调用onRebind():当再绑定服务, 这次绑定的服务对象是之前已经创建好的且没有被销毁(被执行onDestroy()),所以这次绑定服务时就会调用onRebind()方法,并且本次不会调用onBind()。

发布了30 篇原创文章 · 获赞 5 · 访问量 7682

猜你喜欢

转载自blog.csdn.net/c0586/article/details/56319723