目录

一.本文章要学习的内容

二.代码部分

(一)创建项目

(二)如何创建文件

(三)项目结构

(四)MainActivity

(五)MyService

(六)activity_main.xml

三.运行部分

(一)打开Device Manager

(二)选择上次创建的虚拟机(具体见博主第一篇发布的Android文章)

(三)运行

(四)运行结果

四.Service

(一)概念

1.作用

2.Service与Activity的区别

3.Service的特点

(二)Service分类 

1、Started Service

2、Bound  Service

(三)启动Service回调的方法

1.startService():启动服务

2.bindService():绑定服务

3.onCreate():创建服务

4.onStartcommand():重复开始服务

5.onBind():绑定服务

6.unbindService():解绑服务【相对于某个组件来说】

7.onUnbind()回调函数。

8.onUnbind():解绑服务【相对于服务来说】

9.onDestroy():销毁服务

10.stopService():结束服务

11.stopSelf():结束服务


一.本文章要学习的内容

1.充分理解Service的作用,与Activity之间的区别,掌握Service的生命周期以及对应函数,了解Service的主线程性质;

2.掌握主线程的界面刷新的设计原则,掌握启动service的方式,及其工作原理;

任务1:在service中实现随机数产生;

任务2:在Activity界面实现随机数的显示,并采用启动式完成service的启动

1、在service中实现随机数产生;

2、实现Service中的各个生命周期函数,并理解其功能;

2、在Activity界面实现随机数的显示,每2秒更新一次;

3、采用启动式完成service的启动;

二.代码部分

(一)创建项目

 

(二)如何创建文件

在java文件夹下的com.example.demo包下右键新建Service里的Service

(三)项目结构

(四)MainActivity

通过启动式 创建Service,点击开始后调用Intent以显式 的方式调用:MyService.Java
当点击开始按钮时,调用startService(serviceIntent);方法启动service,

package com.example.demo3;

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

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.example.demo3.R;

public class MainActivity extends AppCompatActivity {

    private static Handler handler = new Handler();
    private static TextView labelView = null;
    private static double randomDouble;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        labelView = (TextView) findViewById(R.id.randomname);
        Button start = (Button) findViewById(R.id.startrandom);
        Button stop = (Button) findViewById(R.id.stoprandom);
        final Intent serviceIntent = new Intent(MainActivity.this, MyService.class);
        start.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View view) {
                startService(serviceIntent);
            }
        });
        stop.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View view) {
                stopService(serviceIntent);
            }
        });
    }

    /**
     * UpdateGUI是共有的界面更新函数,后台线程通过调用该函数,将后台产生的数据refreshDouble传递到这个函数内部
     * POST -- 将Runnable对象传递给界面线程的消息队列
     *
     * @param refreshDouble
     */

    public static void UpdateGUI(double refreshDouble) {
        randomDouble = refreshDouble;
        handler.post(RefreshLable);
    }

    /**
     * Runnable对象中需要重载的run()函数,界面更新的代码在这里
     */
    private static Runnable RefreshLable = new Runnable() {
        @Override
        public void run() {
            labelView.setText(String.valueOf(randomDouble));
        }
    };
}

(五)MyService

调用进程:workThread = new Thread(null,backgroundWork,"WorkThread");
以2000ms为周期生成随机数
调用其中使用方法:UpdateGUI() 将生成的随机数抛到Lopper队列中,直到Runnable对象中的 run() 方法被调用,从而使随机数 回显到原来的文本框中。
 

package com.example.demo3;

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

import androidx.annotation.Nullable;


public class MyService extends Service {
    private Thread workThread;

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

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("onCreate");
        //线程组,需要执行的Runnable对象,线程的名称
        workThread = new Thread(null,backgroundWork,"WorkThread");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        if(!workThread.isAlive()){
            System.out.println("onStart");
            workThread.start();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        workThread.interrupt();
    }

    private Runnable backgroundWork = new Runnable() {
        @Override
        public void run() {
            try {
                while(!Thread.interrupted()){
                    double random = Math.random();
                    System.out.println(random);
                    MainActivity.UpdateGUI(random);
                    Thread.sleep(2000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
}

(六)activity_main.xml

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


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="随机数:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/randomname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />


    <TableRow
        android:layout_width="377dp"
        android:layout_height="80dp"
        android:orientation="vertical"

        >


        <Button
            android:id="@+id/startrandom"
            android:layout_width="377dp"
            android:layout_height="wrap_content"
            android:text="开始"
            android:textSize="20sp" />


    </TableRow>
    <Button
        android:id="@+id/stoprandom"
        android:layout_width="381dp"
        android:layout_height="wrap_content"
        android:text="结束"
        android:textSize="20sp" />
</LinearLayout>

三.运行部分

(一)打开Device Manager

(二)选择上次创建的虚拟机(具体见博主第一篇发布的Android文章)

(三)运行

(四)运行结果

四.Service

(一)概念

 Service是Android的四大组件之一。

1.作用

后台长期处理耗时的逻辑。

2.Service与Activity的区别

        不同点:Service与Activity功能大抵相同,区别在于Service不存在UI界面,Service在后台运行,不能与用户进行交互功能。

        相同点:都需要在清单文件中注册,且都有生命周期。

3.Service的特点

        (1)、在后台运行,即使应用退出,也不会停止服务,只有在杀死APP进程时,才会停止服务。

        (2)、Service运行在主线程中。所以,当我们执行一些耗时的操作时,可以在服务中创建子线程来处理耗时的操作。

        (3)、Service应用广泛,例如:音乐播放,下载文件等。

(二)Service分类 

按照启动方式可以分为:

1、Started Service

当组件通过调用 startService() 方法启动 Service ,这时,Service处于启动状态,可以在后台无限期的运行,只有自身调用stopSelf() 方法 或者 其他组件调用 stopService() 方法才会停止Service。

2、Bound  Service

当组件通过调用 bindService() 方法绑定 Service,这时,Service处于绑定状态,多个组件可以绑定在一个Service上,当绑定Service的所有组件解绑之后,该Service被销毁。

  两种启动方式的生命周期如下:

(三)启动Service回调的方法

1.startService():启动服务

        (手动调用)不受调用组件的控制,可以在后台无限期的运行。

2.bindService():绑定服务

        (手动调用)将多个组件与服务绑定在一块,随着组件的消亡而消亡。

3.onCreate():创建服务

        (自动调用)无论是开启服务还是绑定服务,最开始的回调函数肯定是onCreate(),当第一次创建Service的时候调用该方法,多次调用startService()方法不会重复调用onCreate() 方法。适合做一些初始化操作。

4.onStartcommand():重复开始服务

        (自动调用)当多次执行startService()方法的时候,onStartcommand()都会执行。

5.onBind():绑定服务

        (自动调用)当一个组件想要通过bindService()绑定service时,系统会回调该方法。该方法需要实现一个接口,通过返回IBinder对象实现用户通信。若不需要绑定service则返回null,否则必须实现。

6.unbindService():解绑服务【相对于某个组件来说】

        (手动调用)当组件想要与该服务解绑时调用,只有在所有用户解绑之后才会调用

7.onUnbind()回调函数。

8.onUnbind():解绑服务【相对于服务来说】

        (自动调用)当所有捆绑服务的组件解绑之后,系统自动调用onUnbind()函数,将服务解绑。

9.onDestroy():销毁服务

        (自动调用)当Service调用这个函数的时候,这个服务就销毁停止了。下次在用的时候只能执行onCreate()函数进行创建。

10.stopService():结束服务

        (手动调用)其他组件通过调用该函数,将以startService()启动的Service停止掉。

11.stopSelf():结束服务

        (手动调用)当前Service调用此方法来终结自己。

Logo

「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!

更多推荐