一、服务的解释

服务(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

Android 服务(Service)相关推荐

  1. Android 服务(Service)详解

    总结学习类文章 service(服务)是安卓中的四大组件之一,它通常用作在后台处理耗时的逻辑,与Activity一样,它存在自己的生命周期,也需要在AndroidManifest.xml配置相关信息. ...

  2. android创建标题栏,【Android】利用服务Service创建标题栏通知

    创建标题栏通知的核心代码 public void CreateInform() { //定义一个PendingIntent,当用户点击通知时,跳转到某个Activity(也可以发送广播等) Inten ...

  3. Android移动开发之【Android实战项目】后台服务Service

    桌面应用程序:可见 服务:不可见 长期在后台运行 帮助应用执行耗时的操作 安卓的服务:安卓四大组件之一 不可见 后台长期运行 界面与服务有时候要执行数据交互 文章目录 如何创建服务 创建一个类 继承S ...

  4. Android服务之Service(其一)

    转载地址:http://www.cnblogs.com/zhangdongzi/archive/2012/01/08/2316711.html android中服务是运行在后台的东西,级别与activ ...

  5. android 服务是什么问题,Android Studio 中的Service问题

    新手,在学习Service一开始就碰到了问题 是根据教程做的,在开启服务时闪退 MyService.java package com.example.administrator.myhhhhh; im ...

  6. android服务的应用,Android学习指南之十四:Service详解及应用实例

    上一节讲到了Gallery画廊,本节主要讲解Android组件Service,主要内容包括:Service的概念.生命周期及其应用实例. 一.Service简介 Service是Android程序中四 ...

  7. android服务开启线程,android之service与intentService的不同

    不知道大家有没有和我一样,以前做项目或者练习的时候一直都是用Service来处理后台耗时操作,却很少注意到还有个IntentService,前段时间准备面试的时候看到了一篇关于IntentServic ...

  8. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有什么 ...

  9. Android属于绑定服务特点是,android – 每个Service绑定是否需要一个ServiceConnection?...

    我想在我的Activity中绑定几个 Android服务,所以我可以监视用户的几个动作. 为了能够绑定每个服务,我将有几个,我的活动中是否需要几个私有ServiceConnections,如下所示? ...

  10. android服务无法启动,Android服务无法启动(Android service would't start)

    Android服务无法启动(Android service would't start) 我正在尝试在Android中实现简单的服务,但我无法统计基本服务. 这是我的主要课程: import java ...

最新文章

  1. 在MySQL和PostgreSQL之外,为什么阿里要研发HybridDB数据库?
  2. 全球40起黑客攻击或与CIA有关 长角牛黑客组织打卡“上班”
  3. 大豆和黄豆芽还能吃吗?
  4. python时间序列画图_简洁的Python时间序列可视化实现
  5. SpringBoot2.x开发案例之整合Quartz任务管理系统
  6. Android框架式编程之MVP架构
  7. Mono for Android 对话框 倒计时
  8. SLF4JLoggerContext cannot be cast to LoggerContext
  9. 计算机编码发展历史和编码方式
  10. (转) Linux(Centos7)yum安装最新mysql
  11. 《深入理解OSGi:Equinox原理、应用与最佳实践》笔记_1_运行最简单的bundlehelloworld...
  12. ExtJS 4无限制滚动条的Grid
  13. java 数组计算隐藏电话号码
  14. 61. 创建快速响应的Web应用
  15. 更换pycharm主题
  16. 2022年第五届中青杯赛题浅评
  17. 玩转RecyclerView | 实现子视图叠加 | 3D画廊效果 | 高级动效 | Android 3D坐标系介绍
  18. CAN总线概念(一)
  19. 【计算机视觉】张正友棋盘格标定法
  20. xstart连接linux桌面使用的端口,配置XManager5连接Linux图形化界面详解

热门文章

  1. html怎么使图片无法另存为,如何禁止图片另存为?禁止网页另存为到本地的方法...
  2. 数据结构单向不循环链表实现多项式合并
  3. js导出excel单元格内换行符代码_前端和excel的那些事
  4. 7-1 FireTruck 消防车 uva208
  5. 3ds Max 2018 在安装后无法启动或出现不稳定
  6. oracle 察看用户是否被锁,解锁以及改密码
  7. POJ 1308 Is It A Tree? (并查集)
  8. iOS Block全面分析
  9. [转]jQuery源码分析系列
  10. oracle中的mount是什么意思,oraclenomountmountopen直接的关系