AsyncTask是Android1.5开始提供的一个封装了Thread与Handler可以实现异步线程的简单方式,不需要再自己实现子线程,然后在主线程处接受数据。

因为AsyncTask是用线程池,所以呢效率比Thread、Handler的要高。(怎么理解这句话呢,个人感觉Message里的机制,在实例化Message的时候是没有用通常意义

上的构造函数方式Message msg = new Message(),而是通过Message.obtain(..)来实现的,具体的方式就是先在消息池里找已经实例化没有使用的消息,池是空的,

那么最后还是要new的。所以这里的效率高应该是这个意思),使用AsyncTask很方便,主要步骤如下:

  1、必须通过子类来继承AsyncTask来使用,看看这段源码的注释

 * <h2>Usage</h2>
* <p>AsyncTask must be subclassed to be used. The subclass will override at least
* one method ({@link #doInBackground}), and most often will override a
* second one ({@link #onPostExecute}.)</p>

  2、通过execute(..)方法启动线程

  3、必须重写doInBackground(..)方法,(这个方法是个抽象方法所以在写子类的时候会提示),这个方法主要进行耗时工作,

  4、子线程执行完毕会调用onPostExecute(Result result)方法,这个方法不要主动调用,这是一个回调,主要用于更新UI线程的内容,传入的result参数是doInBackground回传的,

    而Result是AsyncTask三个泛型参数中的最后一个。另外还注意一点如果子线程被cancel掉了那么这个方法是不会被执行的,下面是源码里的注释

 <p>Runs on the UI thread after {@link #doInBackground}. The
* specified result is the value returned by {@link #doInBackground}.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>

除此之外还有其他功能,比如在主线程实现进度条显示子线程工作进度:1、在子线程里调用publishProgress(Progress...values)  这个参数是不定长的,而且是第二个泛型指定类型

                                2、主线程里在方法onProgressUpdate(Progress...values) 这个是个回调方法,也不要主动调用。只要在这里更新UI就可以了。

要注意的问题:

1.异步任务的实例必须在UI线程中创建。

2.execute(Params... params)方法必须在UI线程中调用。

3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

4.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

5.当子线程任务被取消onPostExecute(..)方法不会被执行,onCancelled()会被执行。

6.指定泛型的参数时候要注意:params 指定的传入的是doInBackground(params...params)的参数,

              Progress指定的是publishProgress(Progress...progress)的参数,

              Result指定的是Result doInBackground(params...params)的参数

 在写AsyncTask子类的时候先确定好这几个参数,那么Andriod Studio会自动生成这几个函数的形参的

另外如果定义了这几个泛型,那么在实例化的时候一定要注意用如下的方式:

AsyncTask<String,Integer,Long> mAt = new myAsyncTask();

如果用:AsyncTask mAt = new myAsyncTask();的方式编译器不会报错,但是执行的时候会包 Object[] cast to String[] 出错,这里报什么错跟params定义的对象类型

有关如果定义的是Integer 就是cast to Integer[] 出错。后来看源码才知道如果用下面的定义执行的构造函数是:

public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
}; mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}

这里会抛出

An error occurred while executing doInBackground()

这段异常。

下面是一个实例:

public class MainActivity extends AppCompatActivity {
private Button btn_show,btn_cancel;
private ProgressBar pb;
private TextView tv_show;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_show = (Button)findViewById(R.id.btn_show);
btn_cancel = (Button)findViewById(R.id.btn_cancel);
tv_show = (TextView)findViewById(R.id.tv_show);
pb = (ProgressBar)findViewById(R.id.pb); final AsyncTask<String,Integer,Long> mAt = new myAsyncTask();
AsyncTask matt = new myAsyncTask();
btn_show.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mAt.getStatus() == AsyncTask.Status.RUNNING) {
return;
}else if(mAt.getStatus() == AsyncTask.Status.FINISHED){
return;
}else{
mAt.execute("Loading...", "sercond pararms");
}
}
}); btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAt.cancel(false); Toast.makeText(MainActivity.this,"取消",Toast.LENGTH_SHORT)
.show();
}
});
}
//params progress result
private class myAsyncTask extends AsyncTask <String,Integer,Long>{
@Override
protected Long doInBackground(String... params) {
Integer i = 0;
try {
for(;i<11;i++){
Thread.sleep(1000);
publishProgress(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Long ret = Long.valueOf(i.toString());
System.out.println(params[1]);
return ret;
} @Override
protected void onPreExecute() {
tv_show.setText("Loading...");
System.out.println("onPreExecute");
} @Override
protected void onProgressUpdate(Integer... values) {
//更新进度条
pb.setProgress(Integer.valueOf(values[0].toString()));
} @Override
protected void onPostExecute(Long s) {
Toast.makeText(MainActivity.this,"完成进度: "+ s.toString(), Toast.LENGTH_SHORT)
.show();
tv_show.setText("finished");
} @Override
protected void onCancelled(Long aLong) {
Toast.makeText(MainActivity.this,"进度: "+aLong.toString(),Toast.LENGTH_SHORT)
.show();
System.out.println("onCancelled: " + aLong.toString());
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.skymaster.hs.progressbar.MainActivity"> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="ProgressBar"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/btn_show"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="CANCEL"
android:layout_centerHorizontal="true"
android:layout_below="@id/btn_show"
android:id="@+id/btn_cancel"/>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_margin="5dp"
android:id="@+id/pb"
android:max="10"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_centerHorizontal="true"
android:id="@+id/tv_show"/>
</RelativeLayout>

              

AsyncTask实现异步线程通信的更多相关文章

  1. Android使用AsyncTask异步线程网络通信获取数据(get json)

    摘要: android 4.0以上强制要求不能在主线程执行耗时的网络操作,网络操作需要使用Thead+Handler或AsyncTask,本文将介绍AsyncTask的使用方法. 内容: 1.添加Ht ...

  2. JAVA基础知识之网络编程——-基于AIO的异步Socket通信

    异步IO 下面摘子李刚的<疯狂JAVA讲义> 按照POSIX标准来划分IO,分为同步IO和异步IO.对于IO操作分为两步,1)程序发出IO请求. 2)完成实际的IO操作. 阻塞IO和非阻塞 ...

  3. AsyncTask两种线程池

        AsyncTask两种线程池  http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后): 1.THREAD_POOL_EXECUTOR, ...

  4. 异步tcp通信——APM.Core 服务端概述

    为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...

  5. AsyncTask(异步任务)

    一.AsyncTask ①AsyncTask的源码: public abstract class AsyncTask<Params, Progress, Result> 三种泛型类型分别代 ...

  6. Erlang运行时中的无锁队列及其在异步线程中的应用

    本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过“线程进度”机制解决无锁队列的问题,并介绍 Erlang ...

  7. ZeroMq实现跨线程通信

    ZeroMq实现跨线程通信 之前在技术崇拜的技术经理指导下阅读了ZeroMq的基础代码,现在就将阅读的心得与成果记录一下,并重新模仿实现了一下经理的异步队列. 1.对外接口 //主要接口(1)void ...

  8. linux 异步IO通信

    一. 回顾 做java开发的,一定对BIO,NIO,AIO通信很了解了,现在再在下面罗列一下: 同步阻塞IO(JAVA BIO):  同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时 ...

  9. Java并发编程扩展(线程通信、线程池)

    之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...

随机推荐

  1. Java中通过JDBC远程连接Oracle数据库

    通过jdbc连接数据库,拢共分三步: 第一步:下载一个JDBC的驱动,然后把jar包扔到项目里并add to build path: 第二步:去本地oracle文件夹下找到“TNSNAMES.ORA” ...

  2. 2016-2017 CT S03E05: Codeforces Trainings Season 3 Episode 5 (2016 Stanford Local Programming Contest, Extended) J

    链接:http://codeforces.com/gym/101116 题意:给出n个点,要求一个矩形框将(n/2)+1个点框住,要面积最小 解法:先根据x轴选出i->j之间的点,中间的点(包括 ...

  3. Android 编程下图片的内存优化

    1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFactory.decodeResource 来设置一张大图,因为这些方法在完成 ...

  4. 2016年12月14日 星期三 --出埃及记 Exodus 21:9

    2016年12月14日 星期三 --出埃及记 Exodus 21:9 If he selects her for his son, he must grant her the rights of a ...

  5. java-pfx文件转换成16进制内容

    public static void main(String[] args) throws Exception { String path = "D://111.pfx"; Inp ...

  6. zh-cn en-uk、zh-tw表示语言(文化)代码与国家地区对照表(最全的各国地区对照表)

    af 公用荷兰语 af-ZA 公用荷兰语 - 南非 sq 阿尔巴尼亚 sq-AL 阿尔巴尼亚 -阿尔巴尼亚 ar 阿拉伯语 ar-DZ 阿拉伯语 -阿尔及利亚 ar-BH 阿拉伯语 -巴林 ar-EG ...

  7. CF 504E Misha and LCP on Tree(树链剖分+后缀数组)

    题目链接:http://codeforces.com/problemset/problem/504/E 题意:给出一棵树,每个结点上有一个字母.每个询问给出两个路径,问这两个路径的串的最长公共前缀. ...

  8. iOS深入学习(再谈block)

    之前写过一篇博客,把Block跟delegate类比,说明了使用block,可以通过更少的代码实现代理的功能.那篇博客将block定义为类的property. 过了这么长时间,对于block的内容有了 ...

  9. can not find UIAutomationClient

    'ClientApp.vshost.exe' (CLR v4.0.30319: ClientApp.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\asse ...

  10. [51NOD1393]0和1相等串(前缀和,map)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1393 题意:中文题面. 把0看成是-1,并且存一遍前缀和.这样 ...