• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android源码解析之(二)--)异步任务AsyncTask

android源码解析之(二)--)异步任务AsyncTask

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android asynctask,android中asynctask,android.os.asynctask,asynctask异步任务,asynctask源码等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android源码解析之(二)--)异步任务AsyncTask


android的异步任务体系中还有一个非常重要的操作类:AsyncTask,其内部主要使用的是java的线程池和Handler来实现异步任务以及与UI线程的交互。本文主要解析AsyncTask的的使用与源码。

首先我们来看一下AsyncTask的基本使用:

class MAsyncTask extends AsyncTask {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i(TAG, "onPreExecute...(开始执行后台任务之前)");
        }

        @Override
        protected void onPostExecute(Integer i) {
            super.onPostExecute(i);
            Log.i("TAG", "onPostExecute...(开始执行后台任务之后)");
        }

        @Override
        protected Integer doInBackground(Integer... params) {
            Log.i(TAG, "doInBackground...(开始执行后台任务)");
            return 0;
        }
    }

我们定义了自己的MAsyncTask并继承自AsyncTask;并重写了其中的是哪个回调方法:onPreExecute(),onPostExecute(),doInBackground();
然后开始调用异步任务:

new MAsyncTask().execute();

好了,下面我们开始分析异步任务的执行过程,首先查看一下异步任务的构造方法:

/**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     */
    public AsyncTask() {
        mWorker = new WorkerRunnable() {
            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(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);
                }
            }
        };
    }

咋一看AsyncTask的构造方法代码量还是比较多的,但是仔细一看其实这里面只是初始化了两个成员变量:mWorker和mFuture他们分别是:WorkerRunnable和FutureTask,熟悉java的童鞋应该知道这两个类其实是java里面线程池先关的概念。其具体用法大家可以在网上查询,这里具体的细节不在表述,重点是对异步任务整体流程的把握。

总结:异步任务的构造方法主要用于初始化线程池先关的成员变量。

接下来我们看一下execute方法:

@MainThread
    public final AsyncTask execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

这里发现该方法中添加一个@MainThread的注解,通过该注解,可以知道我们在执行AsyncTask的execute方法时,只能在主线程中执行,这里可以实验一下:

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.i("tag", Thread.currentThread().getId() + "");
                        new MAsyncTask().execute();
                    }
                }).start();
                Log.i("tag", "mainThread:" + Thread.currentThread().getId() + "");

然后执行,但是并没有什么区别,程序还是可以正常执行,我的手机的Android系统是Android5.0,具体原因尚未找到,欢迎有知道答案的童鞋可以相互沟通哈。但是这里需要主要的一个问题是:onPreExecute方法是与开始执行的execute方法是在同一个线程中的,所以如果在子线程中执行execute方法,一定要确保onPreExecute方法不执行刷新UI的方法,否则:

@Override
        protected void onPreExecute() {
            super.onPreExecute();
            title.setText("########");
            Log.i(TAG, "onPreExecute...(开始执行后台任务之前)");
        }
Process: com.example.aaron.helloworld, PID: 659
                                                                           android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                               at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6981)
                                                                               at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1034)
                                                                               at android.view.View.requestLayout(View.java:17704)
                                                                               at android.view.View.requestLayout(View.java:17704)
                                                                               at android.view.View.requestLayout(View.java:17704)
                                                                               at android.view.View.requestLayout(View.java:17704)
                                                                               at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:380)
                                                                               at android.view.View.requestLayout(View.java:17704)
                                                                               at android.widget.TextView.checkForRelayout(TextView.java:7109)
                                                                               at android.widget.TextView.setText(TextView.java:4082)
                                                                               at android.widget.TextView.setText(TextView.java:3940)
                                                                               at android.widget.TextView.setText(TextView.java:3915)
                                                                               at com.example.aaron.helloworld.MainActivity$MAsyncTask.onPreExecute(MainActivity.java:53)
                                                                               at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
                                                                               at android.os.AsyncTask.execute(AsyncTask.java:535)
                                                                               at com.example.aaron.helloworld.MainActivity$1$1.run(MainActivity.java:40)
                                                                               at java.lang.Thread.run(Thread.java:818)

若在子线程中执行execute方法,那么这时候如果在onPreExecute方法中刷新UI,会报错,即子线程中不能更新UI。

继续看刚才的execute方法,我们可以发现其内部调用了executeOnExecutor方法:

@MainThread
    public final AsyncTask executeOnExecutor(Executor exec,
            Params... params) {
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                case RUNNING:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task is already running.");
                case FINISHED:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task has already been executed "
                            + "(a task can be exec



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • AsyncTask注意事项,面试技巧和注意事项
  • 再谈Android AsyncTask的优缺点,androidasynctask
  • Android中AsyncTask分析--你所不注意的坑,androidasynctask
  • AsyncTask基础(笔记)
  • Android中AsyncTask基本用法与源码剖析(API 23)
  • android源码解析之(二)--)异步任务AsyncTask
  • AsyncTask源码探究,asynctask源码
  • android:异步任务asyncTask介绍及异步任务下载图片(带进度条)
  • Android线程操作对象AsyncTask线程机制
  • AsyncTask.cancel()的结束问题,asynctaskcancel

相关文章

  • 2017-05-26onSaveInstanceState和onRestoreInstanceState触发的时机,onsaveinstancestate
  • 2017-05-26linux和android调试工具介绍及方法汇总
  • 2017-05-26深度剖析:Android_PullToRefresh
  • 2017-05-26Android之上下文context,androidcontext
  • 2017-05-26【转】adb.exe,start-server' failed,adbserverfailed
  • 2017-05-26Linux内核系列—操作系统开发之HelloWorld,linuxhelloworld
  • 2017-05-26深入理解 Android 之 View 的绘制流程,androidview
  • 2017-05-26[Android]数据篇,android数据
  • 2017-05-26Android登录客户端,验证码的获取,网页数据抓取与解析,HttpWatch基本使用
  • 2017-05-26Android应用:横竖屏切换总结,android切换总结

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android Volley框架的使用(5),androidvolley
    • 一个难倒 3年 android开发经验 " 工程师 " 的 "bug"
    • org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to org.gradle.api.internal.file.collections.DefaultConfigurableFileCollection,gradletaskinputs
    • 用Android studio进行 OpenCV 开发的第一个项目,androidopencv
    • Android studio 插件之 GsonFormat (自动生成javabean)
    • Android触摸事件(三)-触摸事件类使用实例
    • Android 手机卫士11--窗体弹出PopupWindow,11--popupwindow
    • 编译器开发系列--Ocelot语言3.类型名称的消解,编译器--ocelot
    • UI篇(初识君面),ui初识君面
    • 天兔监控服务器和mysql,redis等监控

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有