安卓学习笔记-------四大组件之Service

目录

一、什么是Service

二、Service的启动方式

1. 调用startService()启动服务: 

2. 调用bindService()绑定服务:

 三、Service的生命周期

简介

总体的Service生命周期流程图:

四、Service的创建过程

1. 定义要创建的Service类

2. 定义布局--设置按钮来开启服务和关闭服务和调用服务方法

3.  MainActivity入口程序

4. 加入Service

5. 效果


一、什么是Service

Service是安卓四大组件之一。Service即服务,与另一组件Activity不同的是,Service是跑在后台的,用户是看不到的,而Activity是用于与用户交互的,用户是能看到的。

服务是一个后台运行的组件,执行长时间运行且不需要用户交互的任务。即使应用被销毁也依然可以工作。

二、Service的启动方式

Service的启动有两种方法:

1. 调用startService()启动服务: 

若安卓的应用程序组件(如Activity)调用了startService(),则服务就会在后台启动起来,但是无法与用户交互。

特点:

一旦服务开启,那么就跟调用者(开启者)没有关系了,即使开启者关闭或者挂了,服务都仍然会在后台运行,若要关闭服务,需要额外调用stopService()来关闭。而且开启者也不能够调用服务中的方法。

2. 调用bindService()绑定服务:

当安卓应用程序的组件调用了bindService()来开启服务,那么调用者(开启者)就会和服务绑定在一起,

特点:

如果调用者挂了,那么服务也会跟着挂。当需要停止服务时,调用unbindServer()来解绑并关闭。

而且,这种方式能够让用户与服务进行交互,例如通过点击按钮调用服务中的某个方法。

 三、Service的生命周期

简介

以下是官方给出的Service两种启动方式的生命周期:

通过 startService()启动:

通过startService()启动的Service,会自动调用onCreate() ,进行初始化工作,然后将会自动调用 onStartCommand(),执行相对应的服务的代码,这时候服务就相当于跑起来了。但手动调用stopService()后,服务就会停止,并自动调用onDestroy()对相应的资源进行释放。

因此其生命周期一般是:

onCreate()->onStartCommand()->onDestroy()

但注意的是,一个Service只会调用一次onCreate(),若调用了多次 startService()的话,只会调用一次onCreate(),但会多次调用onStartCommand()。因此这时候的生命周期是: 

onCreate->onStartCommand()->....onStartCommand()->onDestroy()

通过bindService()启动:

通过bindService()启动的Service,也会自动调用onCreate()进行初始化工作,但不同的是,接下是会调用onBind()进行绑定,当手动调用unbindService()时,就会自动调用 onUnbind()解绑,并最后调用onDestroy()做一个资源的释放。

因此其生命周期是:

onCreate->onBind->onUnBind->onDestroy

若是先startService()开启服务,再通过bindService()绑定,则生命周期是:

onCreate->onStartCommand->...服务运行中....->(此时外界要求绑定服务)->onBind-> ...服务绑定&运行中...->onUnBind->onDestroy

 

4个常用的手动调用方法:

5个自动调用的方法:

总体的Service生命周期流程图:

四、Service的创建过程

无论是对于startService()或者是bindService()方式的开启服务,都首先需要:

1.定义对应的Service类

2. 在Androidmanifest.xml 文件中添加定义的Service类

1. 定义要创建的Service类

我们定义两个Service类,分别演示用 startService()方式启动和bindService()方式启动。

新建MyService.java   -----用startService()启动的服务

package com.example.servicetest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import androidx.annotation.Nullable;

public class MyService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println(" onBInd... ");
        return null;
    }

    public void onCreate(){
        System.out.println(" onCreate... ");
        super.onCreate();
    }

    public int onStartCommand(Intent intent,int flags,int startId){
        System.out.println(" startCommand...(此处启动服务对应操作。。) ");
        return super.onStartCommand(intent,flags,startId);
    }

    public void onDestroy(){
        System.out.println(" ondestroy... ");
        super.onDestroy();
    }
}

新建MyBindService() --- 用bindService()方式启动的服务

package com.example.servicetest;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class MyBindService extends Service {

    public static int SIZE = 3;
    public void onCreate() {
        System.out.println("onCreate()...");
        super.onCreate();
    }

    public class MyBinder extends Binder {
        public MyBindService getService() {
            System.out.println("MyBinder extends Binder的MyBindService getService()方法");
            return MyBindService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("DEBUG","public IBinder onBind(Intent arg0) 方法。。。");
        return new MyBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d("DEBUG","onUnbind(Intent intent)方法。。。");
        return super.onUnbind(intent);
    }

    @Override
    public void unbindService(ServiceConnection conn) {
        Log.d("DEBUG","unbindService(ServiceConnection conn)方法。。。");
        super.unbindService(conn);
    }

    @Override
    public void onDestroy() {
        Log.d("DEBUG","onDestroy()方法。。。");
        super.onDestroy();
    }

    public void Play(){
        Log.d("DEBUG","MyBindService.Play()方法,播放音乐");
    }

    public void Pause(){
        Log.d("DEBUG","MyBindService.Pause()方法,暂停");
    }
}

 

2. 定义布局--设置按钮来开启服务和关闭服务和调用服务方法

在布局中,为了演示startService()和bindService()两种方法启动服务,和stopService()关闭服务和unbindService()解绑服务,我们创建的按钮如下布局:

其中MUSIC和STOPMUSIC为提供为用户使用的服务的方法,用于用户与服务之间的交互。

布局的xml文件如下:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <Button
        android:id="@+id/start"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:layout_marginStart="88dp"
        android:layout_marginLeft="88dp"
        android:layout_marginTop="16dp"
        android:text="startService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <Button
        android:id="@+id/stop"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:text="stopService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.17" />

    <Button
        android:id="@+id/unbind"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:text="unbindservice"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.462" />

    <Button
        android:id="@+id/music"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:text="music"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.608" />

    <Button
        android:id="@+id/stopmusic"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:text="stopmusic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.753" />

    <Button
        android:id="@+id/bind"
        android:onClick="onClick"
        android:layout_width="234dp"
        android:layout_height="93dp"
        android:text="bindService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/start"
        app:layout_constraintVertical_bias="0.299" />
</androidx.constraintlayout.widget.ConstraintLayout>

3.  MainActivity入口程序

MainActivity 要 新建一个 ServiceConnection对象,此对象要实现两个回调函数,分别是 onServiceConnected() 和 onServiceDisconnected(),前者是当调用bindService()对服务进行绑定时 调用,后者是当调用unbindService()对服务进行解绑时 调用。

MainActivity.java

package com.example.servicetest;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Intent intent;
    Intent intent2;
    MyBindService service;

    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            service = ((MyBindService.MyBinder)binder).getService();
            int s = service.SIZE;
            Log.d("DEBUG","SIZE:"+s+",onServiceConnected()方法所在线程为:"+Thread.currentThread().getName());

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            int s = service.SIZE;
            Log.d("DEBUG","SIZE:"+s+",onServiceDisconnected()方法所在线程为:"+Thread.currentThread().getName());
        }
    };

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

    public void onClick(View view){
        switch (view.getId()){
            case R.id.start:
                intent = new Intent(MainActivity.this,MyService.class);
                Log.d("DEBUG","onClick.startService()");
                Toast.makeText(this,"开启线程startService",Toast.LENGTH_LONG).show();
                startService(intent);
                break;
            case R.id.stop:
                Log.d("DEBUG","onClick.stopService()");
                Toast.makeText(this, "关闭线程stopService", Toast.LENGTH_LONG).show();
                stopService(intent);
                break;
            case R.id.bind:
                intent2 = new Intent(MainActivity.this,MyBindService.class);
                //flag为true表示绑定成功,为false表示绑定失败
                boolean flag = bindService(intent2,conn, Service.BIND_AUTO_CREATE);
                //System.out.println(flag);
                Log.d("DEBUG","onClick.bindService()");
                Toast.makeText(this,"开始绑定",Toast.LENGTH_LONG).show();
                break;
            case R.id.unbind:
                stopService(intent2);
                unbindService(conn);
                Log.d("DEBUG","onClick.unbindService()");
                Toast.makeText(this, "解除绑定", Toast.LENGTH_SHORT).show();
                break;
            case R.id.music:
                service.Play();
                Toast.makeText(this,"播放音乐",Toast.LENGTH_LONG).show();
                break;
            case R.id.stopmusic:
                service.Pause();
                Toast.makeText(this,"暂停音乐",Toast.LENGTH_LONG).show();
                break;

        }
    }
}

 

4. 加入Service

若需要让定义的Service生效,必须将定义的Service写到Androidmanifest.xml中 

如下图:分别定义了两个服务 MyService和MyBindService,然后想要使得自定义的服务有效,则必须在Androidmanifest.xml中记录。

5. 效果

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值