Android开发学习之路--异步消息Handler,Message,Looper和AsyncTask之初体验
在简易音乐播放器中,用了Handler,也没有过多地去研究学习,这里再学习下android下的异步消息处理机制。这里用了Handler主要是在线程中不能更新UI,而需要通过Handler才可以。关于异步消息处理有几个概念。
1、Message:消息,线程间通讯的数据单元。例如后台要下载歌曲然后下载完成要更新ui,则可以发送一条包含更新信息的Message给UI线程。
2、MessageQueue:消息队列,用来存放所有通过Handler发布的消息,因为是队列,所以是先进先出的。
3、Handler:Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4、Looper:循环管理MessageQueue,循环取出MessageQueue中的Message,并交给相应的Handler进行处理。
5、线程:UI thread是main thread,android启动程序时会替他建立一个MessageQueue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。
下面来个例子吧还是,新建工程HandlerTest,编写简单布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical"
android:layout_margin="10dp"
tools:context="com.example.jared.handlertest.MainActivity"> <EditText
android:id="@+id/inputContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入要改变的内容"/> <Button
android:id="@+id/changeViewContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Change The ViewContent"
android:textAllCaps="false"/> <TextView
android:id="@+id/testHandler"
android:text="I am old!!!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:textSize="22dip"
android:layout_gravity="center"/> </LinearLayout>
这里输入内容,按button,改变TextView的内容。编写MainActivity代码如下:
package com.example.jared.handlertest; 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.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { public static final int UPDATA_VIEW = 1; private TextView textView;
private Button changeContent;
private EditText inputContent; private Thread mThread; private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATA_VIEW:
String mInputContent = inputContent.getText().toString();
textView.setText(mInputContent);
break;
default:
break;
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.testHandler);
inputContent = (EditText)findViewById(R.id.inputContent); changeContent = (Button)findViewById(R.id.changeViewContent);
changeContent.setOnClickListener(new myOnClickListener());
} private class myOnClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.changeViewContent:
mThread = new Thread(runnable);
mThread.start();
break;
default:
break;
}
}
} Runnable runnable = new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATA_VIEW;
mHandler.sendMessage(message);
}
};
}
这里先new了一个Handler,handleMessage方法处理发送的Message,Thread里面发送message,然后更新TextView的内容,运行如下:
基本的Handler已经完成了,下面再学习下AsyncTask。
AsyncTask是方便编写后台线程和UI线程的辅助类。它内部的实现是一个线程池,每个后台会提交到线程池中去执行。AsyncTask有三个模板函数:
1、Params:传递给后台任务的参数类型。
2、Progress:后台计算执行过程中,进步的单位类型。
3、Result:后台执行返回的结果的类型。
当标示不需要的类型的时候,只要用Void就行了。
AsyncTask需要重写5个方法,分别是:
1、onPreExecute方法:准备运行,该回调函数在任务被执行之后立即由UI线程调用,一般可以显示进度条。
2、doInBackground(Params ...)方法:正在后台运行,通常在这里执行耗时的后台计算,计算结果返回给函数,这里如果AsyncTask的第三个参数是Void的话不需要返回,这里不能更新UI,但是可以调用publishProgress(Progress ...)方法完成。
3、onProgressUpdate(Progress ...)方法:进度更新,UI线程在publishProgress(Progress ...)方法调用完成后被调用,一般动态显示一个进度。
4、onPostExecute(Result)方法:完成后台任务,会返回,这里可以进行些UI的操作,比如提醒任务执行的结果,以及关闭掉进度条对话框等。
5、onCancelled方法:取消任务,在调用AsyncTask的cancel()方法的时候调用。
下面通过AsyncTask的方式来进行上面的例子,Handler的代码就没有删除掉了,代码如下:
package com.example.jared.handlertest; import android.os.AsyncTask;
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.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { public static final int UPDATA_VIEW = 1; private TextView textView;
private Button changeContent;
private EditText inputContent; private Thread mThread; private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATA_VIEW:
String mInputContent = inputContent.getText().toString();
textView.setText(mInputContent);
break;
default:
break;
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.testHandler);
inputContent = (EditText)findViewById(R.id.inputContent); changeContent = (Button)findViewById(R.id.changeViewContent);
changeContent.setOnClickListener(new myOnClickListener());
} private class myOnClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.changeViewContent:
// mThread = new Thread(runnable);
// mThread.start();
changeViewContentTask task = new changeViewContentTask();
task.execute();
break;
default:
break;
}
}
} class changeViewContentTask extends AsyncTask<Void, Integer, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
return null;
} @Override
protected void onProgressUpdate(Integer... values) {
} @Override
protected void onPostExecute(Boolean b) {
String mInputContent = inputContent.getText().toString();
textView.setText(mInputContent);
} @Override
protected void onPreExecute() {
} @Override
protected void onCancelled() {
}
} Runnable runnable = new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATA_VIEW;
mHandler.sendMessage(message);
}
};
}
这里实例化一个task,然后task.execute();就可以执行了,效果如上就不添图了。
Android开发学习之路--异步消息Handler,Message,Looper和AsyncTask之初体验的更多相关文章
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
- Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
- Android开发学习之路--Activity之初体验
环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...
- Android开发学习之路--Android系统架构初探
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...
- Android开发学习之路--MAC下Android Studio开发环境搭建
自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...
- 【转】Android开发实践:自定义带消息循环(Looper)的工作线程
http://ticktick.blog.51cto.com/823160/1565272 上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也 ...
- Android开发学习之路-Android中使用RxJava
RxJava的核心内容很简单,就是进行异步操作.类似于Handler和AsyncTask的功能,但是在代码结构上不同. RxJava使用了观察者模式和建造者模式中的链式调用(类似于C#的LINQ). ...
随机推荐
- 勤拂拭软件Android开发之旅(1) 之 Android 开发环境搭建
勤拂拭软件工作室原创出品,欢迎转载,欢迎交流. 转载请注明原文:http://www.cnblogs.com/wangleiblog/p/6019063.html 勤拂拭软件Android开发之旅目录 ...
- 一起来Fit TDMA over WiFi(2)
3 收发流程分析与改进 收发流程分析涉及到具体代码,属于SDK驱动内容,不能完全公开,仅供参考,本系列文档中涉及到具体功能或代码时,请在自己的驱动代码中查找. QCA驱动从9.5开始,将原来的htc的 ...
- solr6.6初探之查询篇
关于搜索与查询,首先我们来看一张图: 这张图说明了solr查询原理: 1.当通过solr发起查询的时候,引擎会选择一个RequestHandler(从字面意思上来说就是请求处理器)来进行查询处理 2. ...
- Python Web学习笔记之多道程序设计技术和操作系统的特性
采用了多道程序设计技术的操作系统具有如下特性 : ① 并发性.它 是指两个或两个以上的事件或活动在同一时间间隔内发生.操作系统是一个并发系统,并发性是它的重要特征,操作系统的并发性指计算机系统中同时存 ...
- html高度塌陷以及定位的理解
高度塌陷的含义: 父元素的高度,默认被子元素撑开,目前来讲box2多高,box1就多高.此时如果子元素设置浮动,则会导致其完全脱离文档流,子元素脱离文档流将无法撑开父元素, 导致父元素的高度丢失,就是 ...
- 关于mysql初始化以及安全策略无法修改的问题
通过mysql官方的yum源来安装的mysql-community-server ,这里版本是MySQL 8.0. wget rpm -ivh mysql80-community-release- ...
- linux 删除命令
rm * 文件名rm -r */ 文件夹rm -rf * 文件夹或文件名 -r 代表文件夹之下的都删除掉 -f 代表暴力删除,无需确认直接删完
- Java实现23种设计模式
一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...
- Flume 读取RabbitMq消息队列消息,并将消息写入kafka
首先是关于flume的基础介绍 组件名称 功能介绍 Agent代理 使用JVM 运行Flume.每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks. Client ...
- linux C 刚初始化后的一个变量在调用一个静态库中函数后被异常修改为乱码
linux C 中声明并初始化一个变量const char a[512]="test";后,接着调用了一个静态库中的函数函数test(b);,a并没有传入test函数,但在调用这个 ...