Android 服务(Service)

一、服务的解释

服务(Service)是Android中实现后台运行的解决方案,它适合那些去执行不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖任何的与任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。

注意:服务并不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程。当某个应用程序被杀死时,所有依赖于该进程的服务也会停止运行。

服务并不会自动开启线程,所有的代码都是默认运行在主线程中的。我们在服务的内部手动创建了子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞住的情况。

二、Android多线程编程

1、线程的基本用法

这部分与Java相同,线程创建的两种方式。

2、在子线程中更新UI

与其他许多的GUI库一样,Android的UI也是不安全的。也就是说,如果想要更新应用程序的UI元素,则必须在主线程中进行,否则就会出现异常。

实践:新建AndroidThreadTest项目:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.zhj.androidthreadtest.MainActivity"><Buttonandroid:id="@+id/change_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Change Text"/><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="Hello world"android:textSize="20sp"/>
</RelativeLayout>

一个按钮,一个TextView,显示出Hello world,目标效果:当我们点击按钮时,会把Hello world 改变成 Nice to meet you。

我们开始写MainActivity.java

package com.zhj.androidthreadtest;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private TextView text;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text =(TextView)findViewById(R.id.text);Button changeText = (Button)findViewById(R.id.change_text);changeText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switch(v.getId()){case R.id.change_text:new Thread(new Runnable() {@Overridepublic void run() {text.setText("Nice to meet you");}}).start();break;default:break;}}});}
}

逻辑非常简单。我们在 按钮的点击事件中开启了一个子线程,然后在子线程中调用TextView的setText()方法将显示的字符串改成Nice to meet you。我们运行之后,点击按钮按钮发现程序崩溃了。

查看logcat日志:可以看出由于在子线程中更新UI造成的。


由此证实,An'd'roid确实不允许在子线程中进行UI操作的。但是有些时候我们必须在子线程中去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件。

对于这种情况,Android 提供了一套异步消息处理机制,完美解决了在子线程中进行UI操作的问题。我们先来了解一下异步消息处理的使用方法,

修改MainActivity的代码:

package com.zhj.androidthreadtest;import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {public static final int UPDATE_TEXT = 1; //表示更新TextView这个动作private TextView text;private Handler handler = new Handler(){//新增Handler对象,并重写handleMessage()方法,对具体的Message进行处理,public void handleMessage(Message msg){//如果发现Message的what字段的值等于UPDATA_TEXT,就将TextView显示的内容改成Nice to meet youswitch (msg.what){case UPDATE_TEXT ://在这里进行UI操作text.setText("Nice to meet you");break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text =(TextView)findViewById(R.id.text);Button changeText = (Button)findViewById(R.id.change_text);changeText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switch(v.getId()){case R.id.change_text:new Thread(new Runnable() {@Overridepublic void run() {Message message = new Message();//创建一个Message(android.os.Message)对象,并将他的what字段设置为UPDATE_TEXTmessage.what = UPDATE_TEXT;handler.sendMessage(message);//将Message对象发送出去}}).start();break;default:break;}}});}
}

来观察按钮的点击事件中的代码,我们并没有在子线程里直接进行UI操作,而是创建了一个Message(android.os.Message)对象,并将它的what字段指定为UPDATE_TEXT,然后调用Handler的sendMessage()方法将这条Message发送出去。Handler会收到这条Message,并在handlerMessage()方法中对它进行处理,注意此时的handlerMessage()方法中的代码就是在主线程中运行的了,所以我们放心在这里进行UI操作。

运行之后,我们会发现内容被替换成Nice to meet you 。

3、解析异步消息处理机制

Android中的异步消息处理主要分为4个部分:Message、Handler、MessageQueue和Looper。

    (1)Message:Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据,可以使用Message的what字段,还可以使用arg1和arg2字段来携带一些整型数据,使用obj字段携带一个Object对象。

    (2)Handler:处理者的意思,主要用于发送和处理消息的,发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列的辗转处理后,最终会传递到Handler的handleMessage()方法中。

    (3)MessageQueue:消息队列,主要用于存放所有通过Handler发送的消息。这部分消息会一直存放在消息队列中,等待被处理。每个线程中只有一个MessageQueue对象。

    (4)Looper:每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入到一个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handlerMessage()方法中。每个线程中也只有要给Looper对象。

我们把异步消息处理的整个流程再梳理一遍。首先需要在主线程中创建一个Handler对象,并重写handlerMessage()方法,这个方法里写你的逻辑。当主线程中需要进行UI操作时,就创建一个Message对象,并通过Handler把这条消息发送出去。之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的handlerMessage()方法中。由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,于是我们在这里可以进行UI操作了。


一条Message经过这样一个流程的辗转调用后,也就从子线程进入到了主线程,从不能更新UI变成了更新UI,整个异步消息处理的核心思想就是如下。

4、使用AsyncTask


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

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

相关文章

Moravec角点检测算子

Moravec角点检测算子 Moravec 在1981年提出Moravec角点检测算子[1]&#xff0c;并将它应用于立体匹配。 首先, 计算每个像素点的兴趣值, 即以该像素点为中心, 取一个w*w(如:5x5)的方形窗口, 计算0度、45度、90度、135度四个方向灰度差的平方和, 取其中的最小值作为该像素点的兴…

文件夹生成工具

很简单的一个小工具,输入一个字符串,可以为你生成相应的文件夹. 至于有什么用?我公司一个策划拿一顿饭给我要的. 下载地址: http://pan.baidu.com/s/1d0ewl 转载于:https://www.cnblogs.com/WhyEngine/p/3350053.html

(转载)深入理解Linux中内存管理---分段与分页简介

首先&#xff0c;必须要阐述一下这篇文章的主题是Linux内存管理中的分段和分页技术。 来回顾一下历史&#xff0c;在早期的计算机中&#xff0c;程序是直接运行在物理内存上的。换句话说&#xff0c;就是程序在运行的过程中访问的都是物理地址。如果这个系统只运行一个程序&…

java中main函数的args参数

先说一下args的作用&#xff1a;我们习惯将一些有用的参数传递给我们定义的函数&#xff0c;那么可曾想过有参数传递给main函数&#xff1f;args就是传递给main函数的一个数组参数。可是main函数作为程序(application程序)的入口点&#xff0c;是由系统自动调用的&#xff0c;怎…

黑马程序员-------------(十)Java基础知识加强(一)

JDK1.5新特性 目录1.之前已经学习过的JDK1.5新特性2.静态导入 StaticImport3.可变参数 ...4.高级for循环5.枚举6.泛型 Generic7.注解注&#xff1a;本章全部为重点内容。###################################################################################################…

java例子:九九乘法表

来吧直接上代码&#xff1a;public class Test{public static void main(String[] args) {for(int i 1; i<9;i){for (int j 1; j < i ;j ) {System.out.print(j"x"i""j*i" ");}System.out.print("\n");}} }运行之后&#xff1…

算法:查找

查找算法&#xff08;比较&#xff09;基本思想顺序查找顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线形表的一端开始&#xff0c;顺序扫描&#xff0c;依次将扫描到的结点关键字与给定值k相比较&#xff0c;若相等则表示查找成功&#xff1b;若扫描结束仍…

query上传插件uploadify参数详细分析

query上传插件uploadify参数详细分析 Uploadify Version 3.2 官网&#xff1a;http://www.uploadify.com/ 注&#xff1a;文件包里有两个js分别是&#xff1a;jquery.uploadify.js 和 jquery.uploadify.min.js&#xff0c;两者其实一样&#xff0c;只需载入其中一个js即可。很明…

type_traits应用

工作遇到这样的例子&#xff0c;对不同数据进行计算处理&#xff0c;得到一组结果集&#xff0c;包括计数、比例等。各个计算处理过程不同&#xff0c;结果集数据结构相同&#xff0c;但并非所有计算过程均有计数、比例的结果&#xff0c;有些可能只有计数&#xff0c;有些只有…

那些不能错过的XCode插件

XCode颜色显示插件ColorSense代码里的那些冷冰冰的颜色数值&#xff0c;到底时什么颜色&#xff1f;如果你经常遇到这个问题&#xff0c;每每不得不运行下模拟器去看看&#xff0c;那么这个插件绝对不容错过。更彪悍的是你甚至可以点击显示的颜色面板&#xff0c;直接通过系统的…

用JSLint精炼提升JavaScript代码

由于移动应用的盛行和HTML5的广泛运用&#xff0c;JavaScript正越来越流行。JavaScript受欢迎的部分原因是因为它的灵活便捷&#xff0c;你可以快速上手&#xff0c;它不需要重量级的开发环境&#xff0c;也不需要第三方应用支持&#xff0c;只要你打开一个文本编辑器&#xff…

网页选项卡的应用

&#xff08;1&#xff09;功能描述&#xff1a; 在页面中&#xff0c;设置三个不同名称的选项卡&#xff0c;当单机某个选项卡时&#xff0c;下面相对应的区域显示其内容信息&#xff0c;同时选项卡的背景色与内容信息的背景色浑然一体&#xff0c;并且字体加粗&#xff0c;表…

工欲善其事必先利其器系列之:在VS里面折叠js代码

之前用vs写js的时候经常因为js代码过长而且不能像cs文件里面的方法一样进行折叠而抓狂,直到在扩展库发现了这款插件有了它就可以把代码进行折叠了 插件地址转载于:https://www.cnblogs.com/Chendaqian/p/3396702.html

python- 基础 map方法

python中map()函数 map()是 Python 内置的高阶函数&#xff0c;它接收一个函数 f 和一个 list&#xff0c;并通过把函数 f 依次作用在 list 的每个元素上&#xff0c;得到一个新的 list 并返回。 例如&#xff0c;对于list [1, 2, 3, 4, 5, 6, 7, 8, 9] 如果希望把list的每个…

C算法编程题(二)正螺旋

前言 上一篇《C算法编程题&#xff08;一&#xff09;扑克牌发牌》 写东西前总是喜欢吐槽一些东西&#xff0c;还是多啰嗦几句吧&#xff0c;早上看了一篇博文《谈谈外企涨工资那些事》&#xff0c;里面楼主讲到外企公司包含的五类人&#xff0c;其实不只是外企如此&#xff0c…

scrapy框架-post使用

scrapy中使用FormRequest向网页提交数据 Scrapy post使用 如何post data&#xff1a; http://httpbin.org/post FormRequest : post请求 GitHub Login 借助浏览器分析登陆行为。 分析post的内容先尝试一次错误的登陆&#xff1a;如下&#xff1a;分析&#xff1a;需要post…

Oracle行列转换小结

目录结构如下&#xff1a;行转列列转行[一]、行转列 1.1、初始测试数据 表结构&#xff1a;TEST_TB_GRADE Sql代码 create table TEST_TB_GRADE ( ID NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE VARCHAR2(20 CHAR), SCORE FLOAT ) 初始…

python- 进阶 与flask的搭配使用---定时任务框架APScheduler学习详解

APScheduler简介 在平常的工作中几乎有一半的功能模块都需要定时任务来推动&#xff0c;例如项目中有一个定时统计程序&#xff0c;定时爬出网站的URL程序&#xff0c;定时检测钓鱼网站的程序等等&#xff0c;都涉及到了关于定时任务的问题&#xff0c;第一时间想到的是利用ti…

Mingw下g++编译执行顺序错误

今天写一个简单的线性表时&#xff0c;用Mingw中的g编译、调试、运行时发现一个奇怪的现象&#xff1a;程序的执行顺序与实际编写顺序不一致。 编译环境&#xff1a;代码编写 win7下 editplus Mingw 4.3.3 g 代码片段如下&#xff1a; 1 //function: create a list 2 //ti…

HDTV(1920x1080)码率和视频质量关系的研究 2 (实验结果)

上一篇文章中介绍了实验的准备工作&#xff0c; HDTV&#xff08;1920x1080&#xff09;码率和视频质量关系的研究 1 &#xff08;前期准备&#xff09; 本文介绍一下实验的结果。 首先来看一下主观评价的试验结果&#xff1a; 从实验结果来看&#xff0c;可以得出以下结论&…