Android学习之Service

Service

Service的作用

Service一般用于在后台处理耗时任务,比如下载任务。

Service的生命周期

在这里插入图片描述

生命周期方法作用
IBinder onBind(Intent intent)绑定服务的时候调用
int onStartCommand(Intent intent, int flags, int startId)服务启动的时候调用
boolean onUnbind(Intent intent)服务被解绑的时候调用
void onCreate()服务被创建的时候调用
startService(Intent service)启动服务
stopService(Intent name)停止服务
bindService(Intent service, ServiceConnection conn,
        int flags) | 绑定服务 |

| unbindService(ServiceConnection conn) | 解绑服务,只会执行一次,多次解绑服务会出现错误 |

启动服务和停止服务

启动服务需要调用startService()方法,停止服务需要调用stopService();服务启动后,其生命周期独立于启动它的Activity,即使Activity销毁了,服务也会在后台继续运行,除非我们停止服务或者服务已执行完成。
接下来通过一个例子来说明:
布局文件

<?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"
    tools:context=".MainActivity"
    android:orientation="vertical">


    <Button
        android:id="@+id/btn_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="启动服务"/>

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="停止服务"/>

    <Button
        android:id="@+id/btn_bind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="绑定服务"/>

    <Button
        android:id="@+id/btn_unbind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解绑服务"/>



</LinearLayout>

MyService类


public class MyService extends Service {

    private static final String TAG = "MyService";

    private int sum = 0;

    public MyService() {
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: 绑定服务");
       
        return null;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: 启动服务");
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: 解绑服务");
        return super.onUnbind(intent);
    }


    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate: 创建服务");
     
        super.onCreate();
    }



    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy: 服务销毁了");
        super.onDestroy();
    }


}

Activity中的代码


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final String TAG = "MainActivity";

    private ServiceConnection serviceConnection = new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
         
        }
      
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };


    private Button btnStart;
    private Button btnStop;
    private Button btnBind;
    private Button btnUnbind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        btnStart = findViewById(R.id.btn_start);
        btnStop = findViewById(R.id.btn_stop);
        btnBind = findViewById(R.id.btn_bind);
        btnUnbind = findViewById(R.id.btn_unbind);

        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        btnBind.setOnClickListener(this);
        btnUnbind.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                Intent intent1 = new Intent(this,MyService.class);
                startService(intent1);
                break;
            case R.id.btn_stop:
                Intent intent2 = new Intent(this,MyService.class);
                stopService(intent2);
                break;
            case R.id.btn_bind:
                Intent intent3 = new Intent(this,MyService.class);
                //第三个参数:服务绑定的方式,只要绑定存在就自动创建service
                bindService(intent3, serviceConnection,BIND_AUTO_CREATE);
                break;
            case R.id.btn_unbind:
                Intent intent4 = new Intent(this,MyService.class);
               unbindService(serviceConnection);
                break;
        }
    }
}

接下来我们来看一下实际的运行效果:
当我们依次点击启动服务、停止服务时,会打印出如下的日志;
在这里插入图片描述
那么,如果我们再点击启动服务以后,再次点击启动服务会是什么样的效果呢?可以看到当再次点击启动服务的时候,只会在日志中打印启动服务的语句,并不会重新创建服务,也就是说,如果服务已经创建了,后续重复启动,操作的都是同一个服务

在这里插入图片描述

绑定服务和解绑服务

服务的绑定需要通过ServiceConnection对象来实现,绑定和解绑的时候需要传入同一个ServiceConnection对象。
绑定服务需要使用 bindService()方法,这个方法的第一个参数是Intent类型的对象,第二参数是ServiceConnection类型的对象,第三个参数一般为BIND_AUTO_CREATE,表示服务没有被创建的时候会自动创建服务。
解绑服务使用unBindService()方法,这个方法的参数就是绑定服务时传入的ServiceConnection对象;

当我们依次点击绑定服务、解绑服务按钮时(在点击绑定之前服务没有被创建),可以看到如下效果,这说明了:如果服务不存在,点击绑定服务按钮会创建服务并绑定服务,点击解绑服务按钮会解绑服务并销毁服务;
在这里插入图片描述
如果在点击绑定服务、解绑服务按钮时,如果服务已经被创建的效果会是什么样的呢?
如果是点击绑定服务后,服务被创建了,那么再次点击绑定服务不会有任何输出:
在这里插入图片描述
如果是点击启动服务、绑定服务的话,会出现如下的效果,可以看到绑定服务只调用了onBind()方法:
在这里插入图片描述
这个时候我们再点击解绑服务,可以看到只解绑了服务并没有销毁服务:
在这里插入图片描述
只有再点击停止服务,才会销毁服务:
在这里插入图片描述
总结:
如果服务不存在:onCreate–>onBind–>onUnbind–>onDestory;
如果服务已存在:那么bindService方法只能使onBind方法被调用,而unbindService方法只能使onUnBind方法被调用;

绑定服务的应用

绑定服务的最大作用是实现对Service执行的任务进行进度监控。
IBinder是用于远程操作对象的一个基本接口。

MyService类
这个类在onCreate方法中开启线程执行耗时任务;onBind方法需要返回一个IBinder对象,我们这里是创建一个类继承了Binder类,Binder实现了IBinder接口的所有方法;MyBinder定义了一个返回sum的方法。onBind方法返回的对象会作为onServiceConnected方法的参数,所以我们可以在onServiceConnected方法中调用getProgress方法得到sum。


public class MyService extends Service {

    private static final String TAG = "MyService";

    private int sum = 0;

    public MyService() {
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: 绑定服务");
        //这里返回的对象会作为onServiceConnected方法的参数
        return new MyBinder();
    }



    class MyBinder extends Binder {
        //获取返回结果
        public int getProgress() {
            return sum;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: 启动服务");
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: 解绑服务");
        return super.onUnbind(intent);
    }


    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate: 创建服务");
        //执行耗时操作
       new Thread(new Runnable() {
           @Override
           public void run() {
               for (int i = 0; i < 100; i++) {
                   sum += i;
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           }
       }).start();

        super.onCreate();
    }


    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy: 服务销毁了");
        super.onDestroy();
    }
}

MainActivity类
ServiceConnection接口的onServiceConnected方法当客户端和service正常连接的时候,执行绑定服务会被调用,而onServiceDisconnected方法会在客户端和service失去连接的时候调用。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final String TAG = "MainActivity";

    private ServiceConnection serviceConnection = new ServiceConnection() {
        //当客户端和service正常连接的时候,执行绑定服务会被调用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected: 正常连接");
            MyService.MyBinder binder = (MyService.MyBinder)service;
            int progress = binder.getProgress();
            Log.d(TAG, "onServiceConnected: 进度: " + progress);

        }
        //当客户端和service失去连接的时候调用
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected: 失去连接");
        }
    };


    private Button btnStart;
    private Button btnStop;
    private Button btnBind;
    private Button btnUnbind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        btnStart = findViewById(R.id.btn_start);
        btnStop = findViewById(R.id.btn_stop);
        btnBind = findViewById(R.id.btn_bind);
        btnUnbind = findViewById(R.id.btn_unbind);

        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        btnBind.setOnClickListener(this);
        btnUnbind.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                Intent intent1 = new Intent(this,MyService.class);
                startService(intent1);
                break;
            case R.id.btn_stop:
                Intent intent2 = new Intent(this,MyService.class);
                stopService(intent2);
                break;
            case R.id.btn_bind:
                Intent intent3 = new Intent(this,MyService.class);
                //第三个参数:服务绑定的方式,只要绑定存在就自动创建service
                bindService(intent3, serviceConnection,BIND_AUTO_CREATE);
                break;
            case R.id.btn_unbind:
                Intent intent4 = new Intent(this,MyService.class);
               unbindService(serviceConnection);
                break;
        }
    }
}

当我们点击启动服务按钮,然后点击绑定服务按钮,然后点击解绑服务按钮,就可以看到如下的日志了,可以看到打印出了我们想要的结果。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值