Android入门第42天-Android中的Service(IntentService)

news2024/10/8 18:11:59

开篇

在前一篇中我们讲了bindService的使用。并且我们留下了一个念想,即在bindService取值时故意阻塞30秒,引起了一次ANR并引出了今天的章节-IntentService。

IntentService的生命周期中有一个非常好的方法-onHandleIntent方法,它是一个abstract方法,开发者在实现IntentService时可以覆盖它来处理“长事务”。

IntentService

Android开发者官网说过:

  1. Service不是一个单独的进程,它和它的应用程序在同一个进程中
  2. Service不是一个线程,这样就意味着我们应该避免在Service中进行耗时操作

于是乎,Android给我们提供了解决上述问题的替代品,就是下面要讲的IntentService; IntentService是继承与Service并处理异步请求的一个类,在IntentService中有 一个工作线程来处理耗时操作,请求的Intent记录会加入队列。

这么神奇?

我们来看演示,如何来验证这个IntentService里的onHandleIntent处理这种长事务。

课程目标

设Service里有一个字符型数组:

   private String[] stdNames = new String[]{"小王", "小明", "小张"};

在Activity里输入数组下标后、等待30秒、然后把相对应的数组下标所对应的StudentName显示在Toast里,看看是不是会发生ANR。

该点击动作可以反复点击,因为每次点击后都会执行unbindService。

代码核心设计

IntentService没什么特殊的,它只是extends 自 IntentService,同时它拥有一个可以被覆盖的:onHandleIntent方法。

  1. 我们这次使用CallBack模式来实现Service里长事务结束后回调activity里的handler实现数值传递;
  2. 我们使用intent.putExtra来实现activity里的数值传递到service中去;

service注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DemoRealIntentService"
        tools:targetApi="31">
        <service
            android:name=".LongWaitingService"
            android:exported="false"></service>

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

 Service类-LongWaitingService

package org.mk.android.demorealintentservice;

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


public class LongWaitingService extends IntentService {
    private final String TAG = "LongWaitingService";
    private String[] stdNames = new String[]{"小王", "小明", "小张"};
    private Callback callback;
    private int stdNo;

    public class StudentBinder extends android.os.Binder {
        public LongWaitingService getService() {
            return LongWaitingService.this;
        }
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public static interface Callback {
        void onDataChange(String data);
    }

    public LongWaitingService() {
        super("LongWaitingService");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Log.i(TAG, ">>>>>>onStart");
    }
        @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            Log.i(TAG, ">>>>>>onHandleIntent");
            Log.i(TAG, ">>>>>>into a long waiting");
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(30000);
                        if (callback != null) {
                            String stdName = stdNames[stdNo];
                            callback.onDataChange(stdName);
                        }
                    } catch (Exception e) {
                    }
                }
            }.start();
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.i(TAG, ">>>>>>onBind方法被调用");
        this.stdNo = intent.getIntExtra("stdNo", -1);
        onHandleIntent(intent);
        return new StudentBinder();
    }
    //Service被关闭前回调
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, ">>>>>>onDestroyed方法被调用!");
    }
    @Override

    public boolean onUnbind(Intent intent) {

        Log.i(TAG,">>>>>>onUnbind");

        return false;

    }
}

主类-MainActivity.java

package org.mk.android.demorealintentservice;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private final String TAG = "LongWaitingService";
    private Button buttonGetValueFromBinder;
    private Button buttonClose;
    private Context ctx;
    private Intent intent;
    private LongWaitingService.StudentBinder stdBinder;
    private EditText etStdNo;
    Handler stdHandler = new StudentHandler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonGetValueFromBinder = (Button) findViewById(R.id.buttonGetValueFromBinder);
        etStdNo = (EditText) findViewById(R.id.etStdNo);
        ctx = MainActivity.this;
        intent = new Intent(ctx, LongWaitingService.class);

        buttonGetValueFromBinder.setOnClickListener(new OnClickListener());
    }
    private ServiceConnection conn = new ServiceConnection() {

        //Activity与Service断开连接时回调该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, ">>>>>>Service DisConnected");
        }

        //Activity与Service连接成功时回调该方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, ">>>>>>Service Connected");
            stdBinder = (LongWaitingService.StudentBinder) service;
            LongWaitingService stdService = stdBinder.getService();
            stdService.setCallback(new LongWaitingService.Callback() {
                @Override
                public void onDataChange(String data) {
                    Message msg = new Message();
                    msg.obj = data;
                    stdHandler.sendMessage(msg);
                }
            });
        }
    };

    class OnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            Intent eIntent;
            switch (view.getId()) {
                case R.id.buttonGetValueFromBinder:
                    int stdNo = Integer.valueOf(etStdNo.getText().toString());
                    intent.putExtra("stdNo", stdNo);
                    bindService(intent, conn, Service.BIND_AUTO_CREATE);
                    break;
            }
        }
    }
    class StudentHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            Log.i(TAG,">>>>>>Service的count" + "的值为:" + msg.obj.toString());
            Toast.makeText(getApplicationContext(), "Service的count" + "的值为:" + msg.obj.toString(), Toast.LENGTH_LONG).show();
            unbindService(conn);
        }
    }
}

来看运行效果

看,再也没有ANR了,结果成功通过CALL BACK回传Activity。

因此我们一般都会这么使用IntentService来实现一些资源异步加载、第三方API回调。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创建你的第⼀个XXL-Job分布式调度任务

文章目录一、程序讲解1. 注解介绍2. 编写代码二、执⾏器管理2.1. Appname2.2. 名称2.3. 注册⽅式2.4. 机器地址2.5. 效果图三、任务管理一、程序讲解 1. 注解介绍 在 Spring Bean 实例中&#xff0c;开发 Job ⽅法⽅式格式要求为 public ReturnT<String> execute(Stri…

ARM 重定位引入和链接脚本

一、一个事实&#xff1a;大部分指令是位置有关编码 位置无关编码(PIC&#xff0c;position independent code)&#xff1a;汇编源文件被编码成二进制可执行程序时&#xff0c;编码方式与位置&#xff08;内存地址&#xff09;无关。 位置有关编码&#xff1a;汇编源码编码成…

分布式智能家居项目雏形

需求分析 客户端进入室内后(局域网)能够主动发现服务(如: 环境服务&#xff0c;灯光服务) 各种服务可以有不同的载体(如&#xff1a;由不同设备提供) 各种服务之间&#xff0c;服务与客户端之间完全无耦合(服务可自由增减) 客户端可以是移动APP&#xff0c;也可以是桌面软件…

【计算机毕业设计】基于JSP的房产中介系统的设计与实现

分类号&#xff1a;TP315 U D C&#xff1a;D10621-408-(2007) 6032 -0 密 级&#xff1a;公 开 编 号&#xff1a;2003211030 学位论文 基于JSP的房产中介系统的设计与实现 摘要 计算机与通信技术为基础的信息系统正处于蓬勃发展的时期。随着科学技术的不断提高&#xff…

2022SDNU-ACM结训赛题解

首先感谢一下各位出题人的精心准备、验题人的辛勤付出、以及选手的积极参加 题解 Problem A 柳予欣的归来【数学】 出题人&#xff1a; bhq 没想到一血是被打完山大的牛客比赛后来结训赛玩的wyx拿走的&#xff01; 题目描述&#xff1a; 计算(∑0<d<pd−1)m(\sum_{0…

Procreate iPad绘画教程

Procreate iPad绘画教程 通过动手绘画课程了解您需要了解的有关 Procreate 的所有信息。现在为 Procreate 5 更新 课程英文名&#xff1a;Drawing and Painting on the iPad with Procreate 此视频教程共11.0小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#x…

Qt第二十八章:异步

所有的数据处理都应该通过异步进行 定义信号# 自定义信号源 class QCustomSignal(QObject):signal_update_table Signal(list)signal_get_token Signal(str)signal_send_mq Signal() 处理函数 Slot()def handle_search(self):def thread_function():user_info get_use…

uImage的制作工具mkimage详解(源码编译、使用方法、添加的头解析、uImage的制作)

1、mkimage工具的源码 (1)mkimage是uboot下面的一个工具&#xff0c;用来将zImage制作成uImage&#xff0c;制作内核启动镜像(给zImage镜像添加64字节的头信息成uImage)&#xff1b; (2)mkimage的源码在"uboot/tool"目录下&#xff0c;在编译uboot时默认会编译出mkim…

假设检验(2)参数的假设检验

下面我们分情况讨论参数的假设检验问题&#xff0e; 3.2. 1 一个正态总体均值的检验&#xff08;方差已知时&#xff09; 例3.2. 1 某车间生产铜丝&#xff0c;铜丝的主要质量指标是折断力&#xff0c;根据过去的经验知该车间生产的铜丝折断力江今换了一批质量较好的原材料&am…

手把手实例教你短视频定位,人设和变现方式,学会节省半年摸索时间

手把手实例教你短视频定位,人设和变现方式,学会节省半年摸索时间 昨天在我赢助手的公开课上分享了一个变现模型&#xff0c;不光是做短视频可以用&#xff0c;在所有互联网项目都可以用。 基础概念就是单价、客户数量和时间的关系。 举个例子&#xff1a; 你的目标是一年赚1…

数据结构:二叉树的链式结构

文章目录一.前言二.二叉树遍历2.1前序遍历/先根遍历2.2中序遍历/中根遍历2.3后序遍历/后根遍历2.4层序遍历2.5二叉树的销毁三.二叉树节点个数四.二叉树叶子节点的个数五.二叉树的高度六.二叉树第K层的节点个数七.找二叉树的节点八.题目8.1判断单值二叉树8.2相同的树8.3另一棵子…

[Redis-实战] 企业常用的缓存使用方案(查询、更新、击穿、穿透、雪崩) 附源码

目录 &#x1f34a; 缓存查询策略 &#x1f369; 缓存更新策略 &#x1f36d; 缓存穿透 &#x1f363; 缓存雪崩 &#x1f355; 缓存击穿 &#x1f47e; 项目源码下载​​​​​​​ &#x1f34a; 缓存查询策略 我们要查询的业务数据并不是经常改变的, 这里我们可以放到Redis…

用visa进行仪表通信

第二份工作一直跟仪表打交道&#xff0c;用仪表来测试&#xff0c;当然主要还是搞自动化。仪表连接通信当然需要用到visa啦。 一.NI VISA的安装和TCP/IP配置 这里看到有人对于安装NI VISA介绍的很清楚&#xff0c;具体想了解就看他的吧。 NI VISA安装和TCP/IP配置 二.安装Py…

第6部分 单区域OSPF

目录 6.1 OSPF 概述 6.2 实验1&#xff1a;点到点链路上的OSPF 1.实验目的 2.实验拓扑 3.实验步骤 4.实验调试 &#xff08;1&#xff09;show ip route &#xff08;2&#xff09;show ip ospf neighbor 6.3 OSPF 命令汇总 OSPF(Open Shortest Path First&#xff0c…

Java实现 LeetCode 500.键盘行

500.键盘行 给你一个字符串数组 words &#xff0c;只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 美式键盘 中&#xff1a; 第一行由字符 “qwertyuiop” 组成。第二行由字符 “asdfghjkl” 组成。第三行由字符 “zxcvbnm” 组成。 示例 1&…

【mysql是怎样运行的】-mysql字符集

文章目录1. 服务器级别2. 数据库级别3. 表级别4. 列级别MySQL 有 4 个级别的字符集和比较规则&#xff0c;分别是 服务器级别、数据库级别、表级别、列级别.1. 服务器级别 SHOW VARIABLES like character_set_server SHOW VARIABLES like collation_server在启动服务器程序时&a…

Vue响应式系统的作用与实现(一)

响应式系统的作用与实现 0.写在前面&#xff1a; 写了mini-vue之后的疑惑更多了&#xff0c;比如为什么要这样设计&#xff1f;这样做的好处是啥&#xff1f;为什么我想不出来&#xff1f;&#xff08;我真菜于是决定去看霍春阳大佬的Vue.js设计与实现。一些参考资料&#xf…

x265 帧间预测

帧间编码入口函数&#xff1a; 从 Analysis::compressCTU 是ctu编码的入口函数&#xff0c;根据 slice 类型判断是 I 还是 BP&#xff0c;如果是BP则执行帧间编码函数 Analysis::compressInterCU_rdx_x&#xff1a;&#xff1a;/*压缩分析CTU过程&#xff1a;1.为当前CTU加载QP…

m基于16QAM的自适应波束形成matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 16QAM全称正交幅度调制是英文Quadrature Amplitude Modulation的缩略语简称&#xff0c;意思是正交幅度调制&#xff0c;是一种数字调制方式。产生的方法有正交调幅法和复合相移法。 波束形成是…

工业级数据分发服务DDS之安全篇

目录引出问题分析问题未授权订阅者未授权发布者截胡篡改跨域攻击解决问题官方标准DDS的安全特性基于域的安全保护域内保护RTI方案RTI安全插件的特性DDS支持的加解密算法用于数据流保护的密码算法用于密钥交换的密码算法用于数字签名的密码算法RTPS-HMAC-Only插件用于数据流保护…