Android四大组件之Service

android开发的四大组件分别是:Activity(活动),活动,与用户交互界面; Service(服务),Content Provider(内容提供器),Broadcast Receiver(广播)。

今天介绍一下Service(服务)。

Service的生命周期

Service有两种不同的创建方式,两种方式的生命周期(回调的方法)也不一样
在这里插入图片描述

被启动(startService)的服务的生命周期:

  • 如果一个Service被某个Activity调用Context.startService 方法启动,不管是否有Activity使用bindService(绑定)或unbindService(解除绑定)到该Service,该Service都在后台运行。
  • 如果一个Service被startService 方法多次启动,onCreate方法只会调用一次,而onStartCommand每次启动都会被调用,并且系统只会创建Service的一个实例(同时只需要调用一次stopService)。该Service会一直在后台运行,不管对应程序的Activity是否在运行,直到被调用stopService或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。

被绑定(bindService)的服务的生命周期:

  • 如果一个Service被某个Activity调用Context.bindService方法绑定启动,不管调用bindService 调用几次,onCreate和onBind方法都只会调用一次,同时onStartCommand方法始终不会被调用
  • 当连接建立之后,Service将会一直运行,除非调用Context.unbindService (该方法调用的是onUnbind和onDestroy)断开连接或者之前调用bindService的Context不存在了(如Activity被finish),系统将会自动停止Service。

被启动又被绑定的服务的生命周期:

  • 如果一个Service又被启动又被绑定,则该Service会一直在后台运行。
  • 不管调用startService启动多少次Service,onCreate始终只会调用一次,onStartCommand每次启动都会被调用。
  • 调用unbindService不会停止Service,必须同时调用unbindService与stopService才能停止服务。

小提示:
不管是什么原因导致Service被终止,onDestroy方法都会被调用,在这里应当做一些清除工作,如停止在Service中创建并运行的线程。

实例

理论知识说完之后咱们也要动动手,撸几行代码试验一下,实验才是检验真理的唯一标准。

布局

我们在activity_main.xml中放置四个Button按钮“startService”、“stopService”、“bondService”、“unbindService”,分别调用四个方法。

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/bnt_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="startService"
            android:textAllCaps="false" />

        <Button
            android:id="@+id/bnt_destroy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="stopService"
            android:textAllCaps="false" />

        <Button
            android:id="@+id/bnt_bond"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="bondService"
            android:textAllCaps="false" />

        <Button
            android:id="@+id/bnt_unbond"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="unbindService"
            android:textAllCaps="false" />
    </LinearLayout>

创建Service类

先说一下创建类的方法吧。

方法一:
自己创建一个类继承Service类,并重写一系列方法
在这里插入图片描述
注意:这种方式创建完成之后要在AndroidManifest.xml中声明注册Service类

方法二:
Android Studio可以直接创建Service类,如下图所示:
在这里插入图片描述

为了方便,我们建立两个Service类,一个用于学习startService()方式启动服务的StartService,另一个用于bondService()方式绑定服务的BindService。

StartService类

public class StartService extends Service {
    public StartService() {
    }

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

    //当Service第一次创建时,回调该方法(只一次),除非Service被销毁重新创建
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("调用方法:", "onCreate");
    }

    //当其他组件调用startService()方法请求启动Service时,该方法被回调(每次)。
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("调用方法:", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    //当Service被销毁时回调,释放占用的资源
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("调用方法:", "onDestroy");
    }
}

BindService类

public class BindService extends Service {
    public BindService() {
    }

    //绑定服务时才会调用,必须要实现的方法
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("调用方法:", "onBind");
        return new MyBinder();//通过binder实现调用者client与Service之间的通信
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("调用方法:", "onUnbind");
        return super.onUnbind(intent);
    }

    //当Service第一次创建时,回调该方法(只一次),除非Service被销毁重新创建
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("调用方法:", "onCreate");
    }

    //当调用startService()方法请求启动Service时,该方法被回调(每次)。
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("调用方法:", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    //当Service被销毁时回调,释放占用的资源
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("调用方法:", "onDestroy");
    }

    class MyBinder extends Binder {
        public BindService getService() {
            System.out.println("绑定服务");
            return BindService.this;
        }
    }

    private final Random generator = new Random();

    //getRandomNumber是Service供client调用的公共方法
    public int getRandomNumber() {
        return generator.nextInt();
    }
}

启动Service

startService()方式启动Service,stopService()方式停止Service

        bnt_start = findViewById(R.id.bnt_start);
        bnt_destroy = findViewById(R.id.bnt_destroy);

        bnt_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, StartService.class);
                startService(intent);
            }
        });

        bnt_destroy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, StartService.class);
                stopService(intent);
            }
        });

bindService()方式绑定Service,unbindService()解绑停止Service

        bnt_bond = findViewById(R.id.bnt_bond);
        bnt_unbond = findViewById(R.id.bnt_unbond)
        
        bnt_bond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, BindService.class);
                /**
                 * 这里传入BIND_AUTO_CREATE,表示在Activity和Service关联后自动创建Service
                 * 这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行
                 */
                bindService(intent, conn, BIND_AUTO_CREATE);
            }
        });

        bnt_unbond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /**
                 * 如果没有绑定服务就执行unbindService就会报错
                 * java.lang.IllegalArgumentException: Service not registered: com.example.servicedemo.MainActivity$1@3f402f68
                 */
                unbindService(conn);
            }
        });

效果:
在这里插入图片描述
从gif图中可以检验出我们的理论是正确的,如果你也做到这里了,毫不犹豫地给自己一个赞吧,鼓励一下自己。

Demo下载

Service的基本使用就分享到这里,提供一下代码和大家分享学习一下:GitHub下载代码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值