四大组件之Service

四大组件之Service

一、什么是服务

服务是一个没有界面,长期运行在后台的一个组件,它适合执行那些不用和用户交互且需要长期运行的任务,例如播放MP3或者下载。

二、服务的启动方式

服务的启动方式有两种,一种为startService(),另外一种为bindService。

  • startService方式启动服务

    活动将服务开启之后 ,服务和活动之间基本没什么关系

    第一步:我们自定义一个类,继承Service类

    public class MyService extends Service {
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
        }
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            return super.onStartCommand(intent, flags, startId);
        }
        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
        }
    
    }
    

    第二步:在清单文件里面注册服务。其实四大组件都必须在清单文件里面注册。

    <service 
        android:name="com.example.servicedemo.MyService">
    </service>
    

    第三步:在MainActivity里面开启服务。我们通过在布局文件中添加了两个按钮,一个用来启动服务,一个用来停止服务,布局文件很简单,这里就不粘出来了。

    public class MainActivity extends Activity implements OnClickListener{
        private Button start_service;
        private Button stop_service;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            start_service = (Button) findViewById(R.id.start_service);
            stop_service = (Button) findViewById(R.id.stop_service);
    
            start_service.setOnClickListener(this);
            stop_service.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            int id =v.getId();
            Intent intent =new Intent(this,MyService.class);
            switch (id) {
            case R.id.start_service:
                startService(intent);
                Toast.makeText(this, "服务开启成功", 0).show();
                break;
            case R.id.stop_service:
                stopService(intent);
                Toast.makeText(this, "服务关闭成功", 0).show();
                break;
            }
        }
    }
    

    当我们点击了启动服务的按钮后,我们可以在手机上的Setting–>apps–>running里面看见我们的服务正在运行。当我们退出Activity后,服务还是会继续在后台运行。我们可以在running界面点击服务,然后点击stop按钮中断服务,也可以在MainActivity界面点击我们的关闭服务按钮关闭按钮。

  • bindService启动服务

    用bindService来启动服务,可以将Activity与服务绑定,并且可以通过service回传的对象来调用服务里面的方法。

    第一步:我们自定义一个类,继承Service类。这里我们需要在Myservice里面写个内部类MyBinder,它继承了Binder,我们利用service里面的onbind()方法,将内部类实例返回到Activity里面,这个类的对象可以调用service里面的方法。

    public class MyService extends Service {
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return new MyBinder();
        }
    
        // 服务里的方法
        public void method_1() {
            Log.i("TAG", "method_1");
        }
    
        public void method_2() {
            Log.i("TAG", "method_2");
        }
    
        //Binder类是IBinder的子类
        class MyBinder extends Binder {
            public void callMethod_1() {
                method_1();
            }
    
            public void callMethod_2() {
                method_2();
            }
        }
    
    }
    

    第二步:在清单文件里面注册service,这里和上面是一样的,这里就不再赘述。布局文件里面多添加了一个按钮,用来调用service里面的方法。

    第三部:在MainActivity里面开启服务

    public class MainActivity extends Activity implements OnClickListener{
        private Button start_service;
        private Button stop_service;
        private MyBinder mb;
        private MyServiceConnection conn;
        private Button callMethod;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            start_service = (Button) findViewById(R.id.start_service);
            stop_service = (Button) findViewById(R.id.stop_service);
            callMethod = (Button) findViewById(R.id.callMethod);
    
            start_service.setOnClickListener(this);
            stop_service.setOnClickListener(this);
            callMethod.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            int id =v.getId();
            Intent intent =new Intent(this,MyService.class);
            switch (id) {
            case R.id.start_service:
                conn = new MyServiceConnection();
                //绑定服务
                bindService(intent, conn, BIND_AUTO_CREATE);
                Toast.makeText(this, "服务开启成功", 0).show();
                break;
            case R.id.stop_service:
                //解除绑定
                unbindService(conn);
                Toast.makeText(this, "服务关闭成功", 0).show();
                break;
            case R.id.callMethod:
                mb.callMethod_1();
                mb.callMethod_2();
                Toast.makeText(this, "调用方法成功", 0).show();
                break;
            }
        }
        //Activity 与service之间的连接。当建立连接完成,会回调onServiceConnected方法,接收service回传过来的对象
        class MyServiceConnection implements ServiceConnection{
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mb = (MyBinder) service;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
    
            }
    
        }
    
    }
    

三、服务的生命周期

Service和Activity一样,都有自己的生命周期方法。

public class ExampleService extends Service {
    int mStartMode;       
    IBinder mBinder;     
    boolean mAllowRebind; 

    @Override
    public void onCreate() {
        // 服务第一次被创建的时候调用该方法
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 启动时候会被调用该方法
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // 客户端与service绑定的时候调用该方法
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // 所用的客户端都解除绑定后调用该方法
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // onUnbind已经被回调后,一个客户端又来绑定服务的时候。
    }
    @Override
    public void onDestroy() {
        // 服务销毁的时候调用
    }
}

四、两种启动Service的方式混合使用案例(音乐播放器)

下面我们通过这两种启动service的方式来写一个音乐播放器,主要是通过这个Demo来认识两种启动方式的作用。

  1. 布局文件:我们在布局文件里面写了三个Button,用来控制音乐的播放、暂停、继续播放。

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click_play"
        android:text="播放"/>
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click_play"
        android:text="暂停"/>
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click_play"
        android:text="继续播放"/>
    
    </LinearLayout>
    
  2. 创建一个服务,用来播放音乐。

        public class MusicService extends Service {
            MyBinder myBinder = new MyBinder();
            @Override
            public IBinder onBind(Intent intent) {
                // TODO Auto-generated method stub
    
                return myBinder;
            }
    
            //播放音乐
            public void play(){
                Log.i("TAG", "play");
            }
            //暂停音乐
            public void pause(){
                Log.i("TAG", "pause");
            }
            //继续播放
            public void resume(){
                Log.i("TAG", "resume");
            }
    
            private class MyBinder extends Binder implements Iservice{
    
                @Override
                public void callPlay() {
                    // TODO Auto-generated method stub
                    play();
                }
    
                @Override
                public void callPause() {
                    // TODO Auto-generated method stub
                    pause();
                }
    
                @Override
                public void callResume() {
                    // TODO Auto-generated method stub
                    resume();
                }
    
            }
    
        }
    

    这里我们将Mybinder实现了一个Iservice的接口,这是为了方便将service里面的方法暴露出去。利用这个接口,我们可以将我们想要暴露的方法暴露出去。

    public interface Iservice {
        public void callPlay();
        public void callPause();
        public void callResume();
    }
    
  3. 在清单文件中注册service。

    <service android:name="com.example.MusicService">
    
    </service>
    
  4. 在MainActivity中利用两种启动service.

    public class MainActivity extends Activity {
    
        private MyServiceConnection conn;
        private Iservice is;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Intent service =new Intent(this,MusicService.class);
            //启动服务
            startService(service);
           //绑定服务
            conn = new MyServiceConnection();
            bindService(service, conn, BIND_AUTO_CREATE);
        }
        //播放音乐
        public void click_play(View v){
            is.callPlay();
        }
        //暂停音乐
        public void click_pause(View v){
            is.callPause();
        }
        //继续播放
        public void click_resume(View v){
            is.callResume();
        }
        class MyServiceConnection implements ServiceConnection{
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                is = (Iservice) service;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
    
            }
        }
        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            //解除绑定
            unbindService(conn);
        }
    }
    

如果想实现具体的播放音乐的功能,可以自己在MusicService 里面利用MediaPlayer 类来实现这个功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值