对于Android为什么要使用多线程,因为从Android4.0之后,谷歌规定了网络操作不允许放在主线程中执行,由此就有了多线程的机制,有个JAVA学习经验的朋友一定知道多线程指的是什么,简单来讲就是,在JAVA程序中,main()函数开启的即为这个程序的主线程,而我们为了完成一些耗时操作又不想影响到主线程的执行,这是我们往往通过Thread对象创建一个子线程来执行。简单的说,一个程序只有一个主线程,可以有多个主线程。在Android世界中也是这样,Android属于单线程模型,耗时操作必须放在非主线程中执行,故而谷歌为了方便我们使用线程,为我们提供一个AsyncTask多线程操作对象。

  对于Android使用线程还有一点需要特别注意,哪就是Android不允许在子线程中更新UI,相信很多初学者一定遇到过这个问题,这个怎么解决呢?在Activity中,我们可以通过

new Thread(new Runnable() {

            @Override
public void run() {
Log.v("abc", "子线程执行");
runOnUiThread(new Runnable() { @Override
public void run() {
Log.v("abc", "返回主线程执行");
}
});
}
}).start();

来实现我们的效果,不过有一点需要注意的是,在Fragement中,runOnUiThread()不能使用,所以大家在使用时稍微注意一下即可。当然了Android中我们还可以通过Handler+Messager来完成多线程操作,对于这里个的使用,在之前的博客中已经为大家介绍,就不在赘述,下面我们开始介绍本篇的重点:AsyncTask的使用。

  AsyncTask<Parans, Progress, Result>是一个抽象类,我们需要首先实现这个抽象类,然后才能使用,对于它的三个参数:Parans:启动任务时输入的参数类型;progress:后台任务执行中返回值的类型;Result:后台执行任务完成后返回的结果类型。

  构建AsyncTask子类的回调方法:1、doInBackground:必须重写,异步执行后台线程将要完成的任务; 2、onPreExecute:执行后台耗时操作前被调用,通过用户完成一些初始化操作;3、onPostExecute:当doInBackground()完成之后,系统会自动调用,并将doInBackground()执行后的返回值,传递给onPostExecute()方法,简单来说就是,doInBackground()完成耗时操作,结果交个onPostExecute()方法更新UI;4、onProgressUpdate:在doInBackground()方法中,调用publishProgress()方法,更新任务的执行进度后,就会触发该方法。

  说了这么多,相信你心中还有一定的疑惑,下面我们通过两个简单的Android小程序,为大家具体介绍一下AsyncTask的使用方法:

 a、AsyncTask中是个抽象方法的执行顺序:

  1、创建一个AsyncTask子类对象:

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    @Override
protected void onPreExecute() {
super.onPreExecute();
Log.v("abc", "onPreExecute");
} @Override
protected Void doInBackground(Void... arg0) {
Log.v("abc", "doInBackground");
publishProgress(arg0);
return null;
} @Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.v("abc", "onPostExecute");
} @Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Log.v("abc", "onProgressUpdate");
} }

  2、在MainActivity中调用给子线程,进行执行:

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyAsyncTask().execute();//启动执行 }

  3、执行后打印的log日志:

  通过这个日志信息,是不是解决了你心中的疑惑,下面我们看一个使用AsyncTask加载网络图片的例子。

 b、加载网络图片:

  1、首先创建一个承载Activity布局文件的xml:

<RelativeLayout 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:layout_margin="10dp"
tools:context=".MainActivity" > <ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"
/> </RelativeLayout>

  布局文件很简单,就是一个ImageView+ProgressBar,在加载ImageView是我们通过ProgressBar来提醒用户等待。

  2、创建我们的Activity对象:

public class AsyncTaskImager extends Activity {

    private ProgressBar pb;
private ImageView image;
private static final String url = "https://www.baidu.com/img/bdlogo.png"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imager);
init();
new ImageAsyncTask().execute(url);
} private void init() {
pb = (ProgressBar) findViewById(R.id.progressbar);
image = (ImageView) findViewById(R.id.img);
} class ImageAsyncTask extends AsyncTask<String, Void, Bitmap>{ @Override
protected void onPreExecute() {
super.onPreExecute();
pb.setVisibility(View.VISIBLE);
} @Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
URLConnection conn = null;
String url = params[0];
try {
conn = new URL(url).openConnection();
InputStream in = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);
bitmap = BitmapFactory.decodeStream(bis);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
} @Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
pb.setVisibility(View.GONE);
image.setImageBitmap(result);
}
} }

  到这里我们的大功已经基本完成了,最后不要忘记在AndroidManifest.xml中进行一下声明。

  3、添加网络操作权限:

<uses-permission android:name="android.permission.INTERNET"/>

  因为我们需要使用到网络连接,所以我们需要在AndroidManifest.xml中添加一个网络访问权限。

  4、最后配上一张运行结果:

  

  到这里关于AsyncTask的介绍就可以画上一个句号了,大家有什么疑问,欢迎留言讨论。对于本人理解上的不足,欢迎批评指点。谢谢

Android线程机制——AsyncTask的更多相关文章

  1. Android线程管理之AsyncTask异步任务

    前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 线程管理相 ...

  2. Android - 消息机制与线程通信

    以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):http://blog.csdn.net/luosheng ...

  3. Android中使用Thread线程与AsyncTask异步任务的区别

    最近和几个朋友交流Android开发中的网络下载问题时,谈到了用Thread开启下载线程时会产生的Bug,其实直接用子线程开启下载任务的确是很Low的做法,那么原因究竟如何,而比较高大上的做法是怎样? ...

  4. android线程 Handler Message Queue AsyncTask线程模型 线程交互 + 修改Button样式 示例 最终easy整合版

     首先原谅我把文章的标题写的这么长.其实我还嫌弃它短了因为 写不下去了所以我就不写了.因为我实在不知道该怎么定义这篇文章的标题或许应该叫 "乱谈"比较合适. 这样可能还体现了 ...

  5. Android线程间异步通信机制源码分析

    本文首先从整体架构分析了Android整个线程间消息传递机制,然后从源码角度介绍了各个组件的作用和完成的任务.文中并未对基础概念进行介绍,关于threadLacal和垃圾回收等等机制请自行研究. 基础 ...

  6. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  7. Android线程管理之Thread使用总结

    前言 最近在一直准备总结一下Android上的线程管理,今天先来总结一下Thread使用. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Executo ...

  8. Android线程管理之ExecutorService线程池

    前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Execu ...

  9. Android多线程机制和Handler的使用

    参考教程:iMooc关于Handler,http://www.imooc.com/learn/267 参考资料:Google提供Android文档Communicating with the UI T ...

随机推荐

  1. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...

  2. Eclipse 包排版问题

    问题描述: 在Eclipse中,项目结构如下所示: 这样的显示方式,查找内容太不方便.使用不习惯. 解决方法: Eclipse中默认包的显示方式为flat,使其改为Hierarchical. 操作步骤 ...

  3. 查看Linux内存状况的命令及工具

    1.cat  /proc/meminfo cat  /proc/<pid>/statm  和 cat  /proc/<pid>/status  获取特定的进程的内存信息: 2. ...

  4. xxxx年度员工岗位技能调查表

    昨天应公司要求设计了一张 <员工岗位技能调查表>,写微博有2个目的:第一是供大家参考,第二是记录下从事质量管理工作走过的点点滴滴.这是我第一次写工作方面的博客,之后会坚持写下去的. --- ...

  5. 转:给 C# 开发者的代码审查清单

      给 C# 开发者的代码审查清单   [感谢@L就是L 的热心翻译.如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线.] 这是为C#开发者准备的通用性代码审查清单,可以当做开发过程中的参考. ...

  6. Qt实现的根据进程名来结束进程

    1.头文件及实现部分: #include <windows.h> #include <tlhelp32.h> #include "psapi.h" #pra ...

  7. HTML5-块元素标签的使用

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. 《利用Python进行数据分析》第7章学习笔记

    数据规整化:清理.转换.合并.重塑 合并数据集 pandas.merge pandas.concat combine_first 数据库风格的DataFrame合并 索引上的合并 join()实例方法 ...

  9. \(\S1 \) Gaussian Measure and Hermite Polynomials

    Define on \(\mathbb{R}^d\) the normalized Gaussian measure\[ d \gamma(x)=\frac{1}{(2\pi)^{\frac{d}{2 ...

  10. WebStorm 11激活方法

    由于最新jetbrains发布了IntelliJ IDEA 15. PyCharm 5.PhpStorm10.WebStorm 11等各个版本,但是改变了注册方法.原先的注册码包括注册机都已经不能使用 ...