Android入门教程 Service的用法

来源:互联网 发布:苏州 青少年编程 编辑:程序博客网 时间:2024/05/20 22:38

为什么要使用Service

我们在做项目过程中,经常遇到一些任务需要再后台执行(比如后台播放音乐、上传、下载等),这个时候就是Service大展身手的时候了。

举个例子:
音乐播放器在播放音乐的过程中,我们按下Home键,前往其他APP执行别的操作,假如播放音乐的操作全都在Activity中完成,那么我们退到后台时,这个Activity很有可能被清掉,就不能正常播放音乐了。但是,如果你用了Service,情况就不一样了,Service的生命周期是和Activity不一样的,系统清理的优先级也不一样,所以即使退到后台,照样能正常播放音乐。

这时候,有朋友又说了:Thread!我可以用一个Thread来播放音乐啊,你这个服务是不是就是相当于开启了一个Thread?

那我就来扒一扒Thread和Service的区别。

  • Thread:Thread是程序执行的最小单元,它是分配CPU的基本单位。
  • Service:Service是Android中的一种机制,它是在Main线程中运行的。总而言之,Service和Thread半毛钱关系都没有。

直观而言,Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。当你重新进入这个Activity时,也不要妄想你能通过这个Activity去操控之前的那个Thread。

怎么解决这个问题呢?

这个时候你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。

Service是什么

service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互、它必须由用户或者其他程序显式的启动、它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦。

Service怎么用

Service的启动方式分为startService和bindService两种。

startService

0、 新建类继承Service

public class MusicService extends Service
  • 重写onCreate方法
    Service在创建时调用的方法,可以用来做数据初始化,Service在没有停止之前,只会执行一次。

  • 实现onBind方法
    由于Service是一个抽象类,定义了一个onBind抽象方法,所以必须实现此抽象方法,return null 即可,此方法在startService方式用不上,无需理会。

  • 重写onStartCommand方法
    Service创建后会调用onStartCommand,此方法中可以接收调用者传递过来的参数,并且可以编写需要的逻辑代码,当重复调用Service时,onStartCommand会重复执行,onStart方法已弃用。

  • 重写onDestroy方法
    Service在退出时调用,此方法中可以编写释放资源的操作。

  • 在AndroidManifest文件中注册Service

<service android:name="com.lenovo.mymediaplayer.service.MusicService" ></service>
  • 使用startService方法启动Service
Intent serviceIntent = new Intent(MusicActivity.this, MusicService.class);// 绑定服务,启动startService(serviceIntent);
  • 使用stopService方法停止Service

使用startService启动Service的总结

  • onCreate只会执行一次,只要调用startService,onStartCommand一定会执行
  • Service运行在main线程中,做耗时操作需另开子线程。
  • 通过Intent进行传参,在onStartCommand中接收参数。
  • 无法获得Service对象,不能直接操作Service中的属性和方法。
  • 调用stopService后,Service会执行onDestroy方法后停止。

bindService

  • step1:新建类继承Service
  • step2:实现onBind方法
    这里不同于startService中实现onBind方法那样简单。这里需要在此方法中返回一个Binder子类对象。
  • step3:重写onCreate方法
  • step4:重写onUnBind方法
    在调用unbindService方法解除绑定后,触发此回调函数
  • step5:重写onDestroy方法
  • step6:在AndroidManifest中注册Service
  • step7:实现ServiceConnection接口
    这里是难点,通过代码示范。
  • step8:通过bindService绑定Service
  • step9:通过unbindService解绑Service

代码示范

Service代码

public class MyService extends Service{    private int count;    private MyBinder binder = new MyBinder();    private boolean stopFlag;    public class MyBinder extends Binder{        public int getCount(){            return count;        }    }    @Override    public IBinder onBind(Intent intent) {        System.out.println("执行onBind方法...");        return binder;    }    @Override    public boolean onUnbind(Intent intent) {        System.out.println("执行onUnBind方法...");        return true;    }    @Override    public void onCreate() {        super.onCreate();        System.out.println("执行onCreate方法");//      new Thread(new MyThread()).start();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        System.out.println("执行onStartCommand方法");        //三种返回值(仅限使用startService方法启动时有效果)        //START_STICKY,服务被异常杀掉后,会重启服务        //START_NOT_STICKY,服务被异常杀掉后,不会重启服务        //START_REDELIVER_INTENT,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onRebind(Intent intent) {        super.onRebind(intent);        System.out.println("rebind");    }    @Override    public void onDestroy() {        super.onDestroy();        stopFlag = true;        System.out.println("执行onDestroy方法");    }    class MyThread extends Thread{        @Override        public void run() {            while(!stopFlag){                try {                    Thread.sleep(1000);                    System.out.println(Thread.currentThread().getName()+"---"+Thread.currentThread().getId());                } catch (InterruptedException e) {                    e.printStackTrace();                }                count++;                System.out.println(count);            }        }    }}

启动Service的Activity代码

public class HomeActivity extends Activity {    private Button btn1;    private Button btn2;    private Intent intent;    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            System.out.println("onDisConnected");        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            System.out.println("connected");            MyServiceTwo ms = ((MyServiceTwo.MyBinder) service).getService();            ms.printServiceName();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 从5.0开始,谷歌要求必须使用显示intent启动service        intent = new Intent(this, MyService.class);        btn1 = (Button) findViewById(R.id.btn1);        btn2 = (Button) findViewById(R.id.btn2);        btn1.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                bindService(intent, conn, Service.BIND_AUTO_CREATE);            }        });        btn2.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                unbindService(conn);            }        });    }}

使用bindService方式绑定Service的总结:

  • onCreate,onBind只会执行一次
  • Service运行在main线程中,做耗时操作需另开子线程。
  • 可以直接操作Service中的属性和方法。
  • 调用unbindService后,Service会执行onUnbind,onDestroy方法后停止。
0 0
原创粉丝点击