Android四大组件之Service

Posted 康小庄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android四大组件之Service相关的知识,希望对你有一定的参考价值。

写在前面

1. Service基础知识点

1.1线程的相关概念:

首先在了解Service前先来了解下线程。

  • 程序:为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)。
  • 进程:运行中的程序,系统调度与资源分配的一个独立单位,操作系统会 为每个进程分配一段内存空间。程序的依次动态执行,经历代码的加载,执行, 执行完毕的完整过程。
  • 线程:比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个 进程中才能执行,线程由程序负责管理,而进程则由系统进行调度。
  • 多线程的理解:并行执行多个条指令,将CPU时间片按照调度算法分配给各个 线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉到"同时"而已。

1.2 线程的生命周期

1.3 创建线程的三种方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callabl接口

1.4 Service与Thread线程的区别

其实他们两者并没有太大的关系,不过有很多人经常把这两个混淆了。 Thread是线程,程序执行的最小单元,分配CPU的基本单位。 而Service则是Android提供一个允许长时间留驻后台的一个组件,最常见的 用法就是做轮询操作。或者想在后台做一些事情,比如后台下载更新。 记得别把这两个概念混淆。

1.5 Service的生命周期图

1.6 Service的生命周期解析

  • StartService()启动Service。
  • BindService()启动Service。
  • 还有一种,就是启动Service后,绑定Service

1.7 相关方法详解

  • onCreate():当Service第一次被创建后立即回调该方法,该方法在整个生命周期 中只会调用一次。
  • onDestory():当Service被关闭时会回调该方法,该方法只会回调一次。
  • onStartCommand(intent,flag,startId):早期版本是onStart(intent,startId), 当客户端调用startService(Intent)方法时会回调,可多次调用StartService方法, 但不会再创建新的Service对象,而是继续复用前面产生的Service对象,但会继续回调 onStartCommand()方法。
  • IBinder onOnbind(intent):该方法是Service都必须实现的方法,该方法会返回一个 IBinder对象,app通过该对象与Service组件进行通信。
  • onUnbind(intent):当该Service上绑定的所有客户端都断开时会回调该方法。

2. Service生命周期的验证

2.1 自定义一个Service,重写相关的方法,用户在logcat上打印验证:

编写布局文件,添加两个Button组件,Id分别设置为startButtonstopButton

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".MainActivity">

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="100dp">

        <Button
            android:id="@+id/startButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="100dp"
            android:text="Start" />

        <Button
            android:id="@+id/stopButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="122dp"
            android:text="Stop" />
    </TableRow>
    
</RelativeLayout>

预览下样式

在src/main/java/包名 目录中创建一个名为TestService1的类,代码如下:

package com.czie.service;

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

import androidx.annotation.Nullable;

public class TestService1 extends Service {
    @Nullable
    @Override
    //必须要实现的方法
    public IBinder onBind(Intent intent) {
        Log.i("CCC", "onBind方法被调用!");
        return null;
    }

    //Service被创建时调用
    @Override
    public void onCreate() {
        Log.i("CCC", "onCreate方法被调用!");
        super.onCreate();
    }

    //Service被启动时调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("CCC", "onStartCommand被调用!");
        return super.onStartCommand(intent, flags, startId);
    }

    //Service被关闭之前回调
    @Override
    public void onDestroy() {
        Log.i("CCC", "onDestroy被调用!");
        super.onDestroy();
    }
}

编写完毕后打开项目中的AndroidManifest.xml文件进行配置。 在<activity …> /activity>节点后添加如下代码:

<service android:name=".TestService1">
      <intent-filter>
    <action android:name="com.czie.service.testservice1" />
      </intent-filter>
 </service>

MainActivity中编写代码:

package com.czie.service;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private Button start, stop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = (Button) findViewById(R.id.startButton);
        stop = (Button) findViewById(R.id.stopButton);

        //创建启动Service的Intent,以及Intent属性
        final Intent intent = new Intent(this,TestService1.class);
        intent.setAction("com.czie.service.testservice1");
        //为两个按钮设置点击事件,分别是启动与停止service
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intent);
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });
    }
}

运行项目,点击按钮同时查看Log输出

2.2 IntentService的用法

在项目中的src/main/java/com.czie.service下创建一个名为TestService3的类

TestService3

package com.czie.service;

import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class TestService3 extends IntentService {

    //必须实现父类的构造方法
    public TestService3() {
        super("TestService3");
        // TODO Auto-generated constructor stub
    }

    //必须重写的核心方法
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        // TODO: 2021/6/21
        // Intent是从Activity发过来的,携带识别参数,根据参数执行不同的任务
        String action = intent.getExtras().getString("param");
        if (action.equals("s1")) Log.i("ccc", "启动service1");
        else if (action.equals("s2")) Log.i("ccc", "启动service2");
        else if (action.equals("s3")) Log.i("ccc", "启动service3");

        //服务休眠2秒
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 重写其他方法,用于查看方法的调用顺序
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i("ccc", "onBind方法被调用了!");
        return super.onBind(intent);
    }

    @Override
    public void setIntentRedelivery(boolean enabled) {
        Log.i("ccc", "setIntentRedelivery被调用了!");
        super.setIntentRedelivery(enabled);
    }

    @Override
    public void onDestroy() {
        Log.i("ccc", "onDestroy被调用了!");
        super.onDestroy();
    }
}

编写完毕后打开项目中的AndroidManifest.xml文件进行配置。 在<activity …> /activity>节点后添加如下代码:

<service android:name=".TestService3">
            <intent-filter>
                <action android:name="com.czie.service.testservice3" />
            </intent-filter>
        </service>

MainActivity中添加代码

package com.czie.service;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private Button start, stop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = (Button) findViewById(R.id.startButton);
        stop = (Button) findViewById(R.id.stopButton);


        Intent it1 = new Intent(this, TestService3.class);
        Bundle b1 = new Bundle();
        b1.putString("param", "s1");
        it1.putExtras(b1);

        Intent it2 = new Intent(this, TestService3.class);
        Bundle b2 = new Bundle();
        b2.putString("param", "s2");
        it2.putExtras(b2);

        Intent it3 = new Intent(this, TestService3.class);
        Bundle b3 = new Bundle();
        b3.putString("param", "s3");
        it3.putExtras(b3);


        //接着启动多次IntentService
        startService(it1);
        startService(it2);
        startService(it3);
        
        //创建启动Service的Intent,以及Intent属性
        final Intent intent = new Intent(this, TestService1.class);
        intent.setAction("com.czie.service.testservice1");
        //为两个按钮设置点击事件,分别是启动与停止service
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intent);
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });
    }
}

运行项目,查看Log的输出
IntentService每次启动,都会新建一个工作线程,但是始终只有一个IntentService的实例

写在最后

  • 掌握Service基本知识点和使用😄
  • 继续探索Service其他功能💪
  • 本篇文章对你有用的话,记得点个赞👍
  • 对本篇文章有任何问题,欢迎评论区指出❤️

以上是关于Android四大组件之Service的主要内容,如果未能解决你的问题,请参考以下文章

Android四大组件之service

Android四大组件service之Bound Service

android 四大组件之---Service

android 四大组件之Service 粘性与非粘性

Android四大组件之Service

android 四大组件之Service 结合通知