Android 启动优化(七) - JetPack App Startup 使用及源码浅析
AsyncTask 使用及封装实践
本文字数: 12k 阅读时长 ≈ 11 分钟
前言
这篇博客主要是讲解AsyncTask的使用及封装实践,对于新手们还是有很大的参考意义的,尤其是AsyncTask的封装实践这部分。对于老鸟们,你们可以跳过了。同时需要声明的一点是,下面下载的例子只是进行简单的下载而已,并没有支持断点续传下载。需要的话请自行到github上面找相应的库,因为这并不是本篇博客的重点。
这篇博客主要讲解以下问题:
- AsyncTask的简单使用
- AsyncTask的封装使用
- AsyncTask使用注意事项
AsyncTask的使用例子
简介
AsyncTask ,异步任务。没错,就想字面上理解的那样。它允许我们在子线程执行耗时任务,在UI 线程更新操作(如更新进度条等)。简单来说,就是帮我们做好了子线程与UI 线程的通讯,我们只需要调用响应的方法实现即可。底层是用Handler消息机制实现的。
在Android开发中,我们经常需要下载各种东西,为了给用户较好的体验,我们经常需要显示下载进度。今天我们用以这个为例子,来教大家怎样使用AsyncTak。当然,github上面有很多开源库,实现断点下载,文件重命名等。不过这些不是本篇博客的重点。
效果图
AsyncTask的主要几个方法
- Void onPreExecute()
在task 任务开始执行的时候调用,在doInBackground(Params… params)方法之前调用,在主线程中执行
- Result doInBackground(Params… params)
主要用来执行耗时操作,在子线程中执行,Params为我们参数的类型。而Result这个泛型,是我们返回的类型(可以是Integer,Long,String等等类型,只要不是八种基本类型就OK),同时 Result 的类型将作为 onPostExecute(Result result)的参数。
- Void onProgressUpdate(Progress… values)
Runs on the UI thread after publishProgress(Progress…) is invoked. 当我们调用 publishProgress()方法的时候,会调用 onProgressUpdate()这个方法
Void onPostExecute(Result result)
在doInBackground()方法执行完毕之后,会调用这个方法,是在主线程中执行的。但如果我们手动调用了cancelled()方法,那么这个方法将不会被调用。void onCancelled()
在Task 任务取消的时候会调用
- execute(Params… params)
Executes the task with the specified parameters.当我们调用这个方法的时候,会执行任务
- executeOnExecutor(Executor exec, Params… params)
在指定的线程池里面执行Task
需要注意的是,Params,Progress,Result 并不是一种特定的类型,它其实是泛型,它支持除了八种基本类型之外的类型,跟普通的泛型一样。
AsyncTask使用的几个步骤
这里我们以下载一个apk为例讲解
- 写一个类继承AsyncTask,并传入Params,Progress,Result 。三个参数的类型。
比如我们传入的 Params,Progress,Result 的参数的类型分别为 Void, FileInfo, FileInfo,那我们可以这样写。
1 | private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo>{ |
那Void, FileInfo, FileInfo,这几个参数的类型在哪里体现出来呢?
请看下面注释
1 | private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo> { |
- 如果我们更新进度的话,需要重写 onProgressUpdate()方法,并在doInBackground()方法里面调用publishProgress()方法
1 | protected FileInfo doInBackground(Void... params) { |
- 当我们调用execute(Params… params) 或者 executeOnExecutor(Executor exec, Params… params) 方法的时候,Task将被防盗相应的 Executor 执行。
1 | MyDownloadTask myDownloadTask = new MyDownloadTask(mDownloadUrl, mDstPath); |
完整的Task代码如下
1 | private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo> { |
AsyncTask的封装使用
前面我们讲完了AsyncTask的基本使用,不知道你有没有发现,其实代码耦合性是挺高的,
- 我们直接在 onProgressUpdata(),onPostExecute()方法里面更新我们的界面,即我们的AsyncTask访问了我们Activity里面的控件,那如果我们修改了Activity的控件,我们岂不是又要去阅读AsyncTask的代码,去做相应的修改。
- 下一次我们如果要下载别的东西,按照我们前面的代码,我们又要重新复制一份,这样无疑是做了很多重复的工作。
说到这样,我相信大多数人的第一感觉就是把AsyncTask提取为外部类,封装起来。是的,确实,我们就是要把AsyncTask提取为外部类。那提取为歪不累之后呢?我们要访问Activity里面的空间,要怎样访问呢?
- 在Activity里面定义静态方法
- 把需要访问的View对象通过构造函数传递进来
- 采用接口回调机制
前面说到的三种方法,是可以做到AsyncTask与外界进行通讯的。但第一第二中方法明显不行。原因如下:
- 第一种方法定义静态方法,那View对象也必须定义为static变量,这static变量的级别比较高,不易被垃圾回收机制回收,易发生没存泄露。
- 第二种方法,把需要访问的View对象通过构造函数传递进来。如果需要访问的对象少的话,勉强可以接受,如果多的话,那岂不是要定义很多成员变量。不过最致命的还算是代码耦合性太高了。还不如AsyncTask直接作为内部类。
好了,说了这么多,下面我们一起来看怎样使用接口回调机制来进行解耦。
AsyncTask 使用接口回调机制来进行解耦
- 使用接口回调机制,首先我们必须有一个接口
1 | public interface DownloadListener { |
- 将DownLoadTask提取为一个外部类,并将需要传递的参数传递进来
1 | public class DownloadTask extends AsyncTask<Void,FileInfo,FileInfo> { |
- 在相应的地方调用我们接口的方法
1 | public class DownloadTask extends AsyncTask<Void,FileInfo,FileInfo> { |
使用
以后我们要下载东西,只需要调用下面的方法即可。同时,如果产品再更改需求,比如,从显示一个进度条ProgressDialog对话框,改成显示一个ProgressBar,我们只需要在
onProgress()里面做相应的修改就好了,在也不用去阅读DownloadTask里面的代码呢?减少了代码的耦合性,是不是瞬间感觉世界很美好呢?
1 | mDownloadTask = new DownloadTask(mDownloadUrl, mDstPath, null, new |
AsyncTask使用的注意事项
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
- The task instance must be created on the UI thread.(AsyncTask必须在UI 线程里面初始化
- execute(Params…) must be invoked on the UI thread.
- Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…) manually.(不要手动地调用 onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…) 这些方法)
- The task can be executed only once (an exception will be thrown if a second execution is attempted.) (Task任务只能被执行一次,否则会抛出异常)
相关知识点推荐:
2021 Android 如何自学,Android 学习路线分享,一位 5 年中大厂老哥跟你聊聊
本文字数: 5k 阅读时长 ≈ 5 分钟
光阴似箭,日月如梭,时间真的过得飞快。
加上实习,从事 Android 开发,差不多有 5 年了,在这里,我分享一下我的经验,在 Android 的学习路上,我是站在巨人的肩膀上成长起来的。
大概分为三个部分
一、Android 职业规划
二、Android 学习路线
三、如何进入大厂
三、Android 学习资料分享
Android 成长生涯
1-3 年
前 3 年,我觉得是我们成长最快的时候。
尤其是刚开始工作的一年,刚开始接触项目,我们会接触到很多新知识,比较网络框架的封装,Android 架构 MVVN,MVC,MVP 等。
这段时期是我们进步最快的时候,因为很多东西我们都不会,我们会逼着自己去学习。
第二到第三年,也是我们成长的关键时期。这时候,在项目中,我们基本会自己独立负责需求。这时候的我们,大多数基本功能都可以自己独立实现。需要注意的是代码风格和代码思维的培养。
代码风格,指的是编码习惯。比如方法命名,方法的合理拆分,适当添加注解,注释。听起来可能会很虚,但是千万别小看这些细节。反正我在组里见过一些工作五六年的,代码一坨一坨的,像 si 一样。
代码思维,有点类似于人的视野和思考方式吧。很多时候,实现某个效果,有很多种方案。我们为了应付需求,可能会随便选择一种,没有去了解其他方案。而这恰恰错过了我们成长的最佳时期。
记住,永远别给自己设限,或许在编程的路上会遇到很多问题,但是总会有解决方法的,而这取决你的态度。
3-5 年
这个时期,不出意外,我们基本都是高级工程师了。这时候大多数人会遇到瓶颈,不知道学些什么好。好像什么都会,但是不够深入。我也遇到这样的情况,现在正在深挖。
这方面我暂时也给不了太多意见,只能说,选择一个方向,静下心来,去学习,相信能收获到我们想要的。
学习方向有很多,比如 Android 性能优化(启动,卡顿, Crash 治理), JNI C++,gradle 打包,编译速度,音视频等等,这些都是大的方向。
最近写的一些文章,自我感觉还行,有兴趣的可以看看。
Android 启动优化(二) - 拓扑排序的原理以及解题思路
Android 启动优化(三)- AnchorTask 开源了
Android 启动优化(四)- AnchorTask 是怎么实现的
Android 启动优化(五)- AnchorTask 1.0.0 版本正式发布了
5 年之后
大多数技术人,一般会有以下方向。
- 第一:成为技术大神,比如架构师,及技术专家等。
- 第二:技术管理,比如技术总监等。
- 第三:技术转型,如转项目管理,产品等,你牛逼的话,说不定下一个张小龙就是你(哥们,想多了,那有这么容易)。
- 第四:自主创业,做自媒体等
我目前来说,可能会选择第一条路吧,成为一名技术专家。
在技术的路上,或许会很累,很难,可那又怎样呢
35 岁中年职业危机,很多职业都有,不仅仅局限于程序员。
从本质上面说,自身竞争力下降占很大原因。毕竟,优秀的人才从来不缺少机会。
既然选择了,便只顾风雨兼程。
为了未来有更多的选择,从现在开始,朝着自己的目标努力奋斗吧,书写属于自己的人生。
Android 学习路线
下面,说一下 Android 的学习路线,不会很具体,主要是从大的方面来说,感兴趣的可以看一下。
搭建基本的开发环境,敲下 Hello world
首先你配置好电脑开发环境。首先需要配置 Java,AndroidStudio 的开发环境。
现在的 IDE 对比几年前的,真的是方便多了,可以自动帮我们配置好环境变量。还记得当年刚开始配环境的时候,折腾了两三天。在配置变量的时候,有时候英文的逗号输成中文的,在 cmd 窗口输入 Java,一直提醒没有这个命令,一把鼻涕一行泪。
依稀还记得,当配置完环境之后,敲下第一段程序 Hello world 时的那份喜悦。
掌握基本的语法和常用的数据结构
第一:你要先掌握基本的语法,可以从一些书籍开始学起。跟着书本慢慢敲,从第一个程序 Hello World 慢慢敲起,万丈高楼平地起。
由于 Android 是用 java 或者 kotlin 语言开发的,建议优先掌握 java 语言。这里推荐两本书籍。
- java 编程思想,一本很经典的 java 书籍
- java 剑指 offer,面试神器。校招的时候,有很多面试题目,里面都有涉及到。
第二:掌握基本的语法之后,常用的数据结构,数组,链表,队列,栈。这些基本的概念和语法要知道。还有线程,文件 IO 操作,网络操作。
学完这些之后,Java 的基本知识你大概掌握了,这时候建议你动手写一些小项目或者 Demo,比如坦克大战,计算器等,这些网上都有代码。想跟着视频一起学的话,推荐马士兵的视频,可以在我的微信公众号 程序员徐公 回复”Java“,会将教程发给你
Android 学习入门
掌握这些之后,你可以去看一些 Android 入门的书籍或者一些视频。
书籍我推荐郭霖的第一行代码,目前出了第三版了,写得真不错。
视频的话,我推荐你可以看黑马的 Android 视频,里面会从一些基本语法讲起,接着是项目实战,会手把手教你实现简单的新闻客户端,360 手机卫士等等。
想获取黑马视频资料的话,可以去我的微信公众号程序员徐公回复”黑马“两字,会将教程发给你。
Android 进阶
学习完基本的知识之后,可以去看看任玉刚的 Android 开发艺术探索,虽然是几年前出版的,但真的是精华。
接着,可以关注一些架构,性能优化方面的。
- MVC, MVP, MVVN
- 内存泄露怎么检测,常见的内存泄露有哪些
- 怎么检测 ANR,有哪些手段呢,优缺点是什么
- 怎么捕获 Crash,Java Crash 和 native crash 有哪些不同呢
- Android 检测启动时间,启动优化怎么做,常见的 Android 启动优化手段有哪些
- Android gradle,是怎样打包的,怎样提高编译速度
这里推荐几篇不错的文章。
Android 启动优化(二) - 拓扑排序的原理以及解题思路
Android 启动优化(三)- AnchorTask 开源了
Android 启动优化(四)- AnchorTask 是怎么实现的
Android 启动优化(五)- AnchorTask 1.0.0 版本正式发布了
关注前沿技术
关注前沿技术,可以去一些论坛,公众号上面逛逛。
论坛的话,推荐掘金,CSDN
Android 技术公众号的话,推荐鸿洋,郭霖的公众号,当然还有我的公众号程序员徐公。文章的质量算是比较高的。
最后,有空的时候多去 github 或者 google 官网 看看,有什么新技术,一般第一时间会更新。
如何进入大厂
面试是一个双向选择的过程,我们要保持足够的自信。
在我看来,要进入大厂,有 4 点最重要。
- 编程能力,包括常用技术以及常用技术的原理,毕竟招人,是来干活的,不是来当爹的。
- 技术深度,在大厂,分工越来越越明确,职责越来越细。很多时候,需要的是某一个技术领域的人才,而不是什么都懂一点的全才。
- 算法。
- 软技能,沟通能力等
如何学习算法
现如今,如果你想进入大厂,腾讯,阿里,头条,拼多多等,不管是社招还是校招,肯定都会面试到算法的。
相信很多人有这样的想法,面试的时候早火箭,工作的时候拧螺丝。确实,这种情况非常常见,我也认同。但没办法,谁叫我们想进入大厂呢。
不过,这种情况也可以理解。怎么在几轮面试中确定面试者的水平呢?
肯定是考察算法,基础这些,原理这些。
虽然这些代表不了全部,但起码能在一定程度上代表了面试者的水平能力。要知道,编程语言其实都是想通的,编程思维和算法能力才是核心。
掌握了原理,编程思维,切换到另外一门语言其实是很快的。这也就是面试官喜欢考察算法和原理的原因。
至于要怎么学习算法,我简单归纳一下
第一:要了解基本的数据结果,数组,链表,Map,Set,二叉树等,了解他们的优缺点,时间复杂度,空间复杂度等
第二:要掌握一些常见的算法,递归,迭代,八大排序,二分查找,贪心算法等
第三:掌握一种算法,不仅要知道 what,还要知道 why(分析各种算法的优缺点),比如 topK问题,有常见的几种解决方案,排序,快排思想,海量数据堆排序
第四:刚开始学的时候,可能会比较吃力,可以先刷题,慢慢找感觉,从易到难。
- 比如,第一天,你刷这道算法题的时候看不懂,先不用着急,很多人都是这样过来的,先搜一下答案,看一下别人是怎么解决的。
- 看懂了之后,自己用代码写一遍,跑一遍。这很重要,很多时候,你以为你自己懂了,但当你在写的时候是写不出来的,在你动手写代码时,会不断加深你的印象
- 第二天,自己再写一遍,加深印象
第五:学好算法不是一日之功,需要长期的积累。建议的做法是每天做一两道题,题目不在多,贵在于理解。坚持一两个月,你会发现你的感觉逐渐好起来了。
https://github.com/gdutxiaoxu/Android_interview
Android 学习资料分析
黑马 52 期不加密视频
获取方式在微信公众号 “程序员徐公” 回复“黑马” 两字
01、安卓基础+JNI (14天)
02、Android应用开 发-代码版本管理和实战(1天)
03、android案例与项目_手机安全卫士(12天)
04、自定义控件与视图(2天)
05、android项目 实战_智慧北京(6天)
06、android项 目实战_谷歌应用市场(6天)
07、android进阶 高阶案例-QQ5.0特效专辑(2天)
08、android游戏开发_ 植物大战僵尸(3天)
09、android案例与项目_ 百度地图(1天_ 补充)
10、android项目实战_智能短信管理(3天_ 补充)
11、Android _WebView&HTML5开发(1天 _补充)
Java 马士兵视频
获取方式在微信公众号 “程序员徐公” 回复“java” 两字
第一部分:J2se学习视频内容包括:
尚学堂科技_马士兵_JAVA视频教程_JDK5.0_下载-安装-配置
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第01章_JAVA简介_源代码_及重要说明
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第02章_递归补充
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第02章_基础语法
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第03章_面向对象
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第04章_异常处理
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第05章_数组
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第06章_常用类
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第07章_容器
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第08章_IO
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第09章_线程
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第10章_网络
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第11章_GUI
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_专题_日期处理
尚学堂科技_马士兵_JAVA视频教程_J2SE_专题_正则表达式
第二部分:j2se练习项目视频内容包括:
第二部分:j2se练习项目视频内容包括:
尚学堂科技_马士兵_在线聊天系统雏形视频教程_java_eclipse
尚学堂科技_马士兵_坦克大战视频教程_java_eclipse
尚学堂科技_马士兵_坦克大战图片版
尚学堂科技_马士兵_JAVA_坦克大战网络版视频教程
尚学堂科技_马士兵_snake_贪吃蛇内部视频
小结
以上是我这些年来, Android 学习路上的一些简单分享。在 Android 的学习路上,我是站在巨人的肩膀上成长起来的,同样,我也希望成为你们的巨人。
希望我们可以成为朋友,成长路上的忠实伙伴!
黑马 Android 52 期学习视频,不加密的,免费分享给大家
本文字数: 502 阅读时长 ≈ 1 分钟
Android 黑马学习视频
目录
- 01、安卓基础+JNI (14天)
- 02、Android应用开 发-代码版本管理和实战(1天)
- 03、android案 例与项目_手机安全卫士(12天)
- 04、自定义控件与视图(2天)
- 05、android项目实战_ 智慧北京(6天)
- 06、android项目实战_谷歌应用市场(6天)
- 07、android进阶高阶案例-QQ5.0特效专辑(2天)
- 08、android游戏开发_植物大战僵尸(3天)
- 09、android案例与项目_ .百度地图(1天_ 补充)
- 10、android项目实战_ 智能短信管理(3天_ 补充)
- 11、Android_ WebView&HTML5开发(1天 补充)
获取方式
如果链接过期了,可以关注我的微信公众号“程序员徐公”,回复“黑马“两字,会自动发给你
- 公众号程序员徐公回复黑马,获取 Android 学习视频
- 公众号程序员徐公回复徐公666,获取简历模板,教你如何优化简历,走进大厂
- 公众号程序员徐公回复面试,可以获得面试常见算法,剑指 offer 题解
- 公众号程序员徐公回复马士兵,可以获得马士兵学习视频一份
Android 启动优化(六) - 深入理解布局优化
本文字数: 9.9k 阅读时长 ≈ 9 分钟
Android 启动优化(六) - 深入理解布局优化
Android 启动优化(五) - AnchorTask 1.0.0 版本更新了
本文字数: 7.4k 阅读时长 ≈ 7 分钟
Android 启动优化(五) - AnchorTask 1.0.0 版本更新了
Android 启动优化(四) - 手把手教你实现 AnchorTask
本文字数: 8.7k 阅读时长 ≈ 8 分钟
Android 启动优化(四) - 手把手教你实现 AnchorTask
Android 启动优化(三) - AnchorTask 使用说明
本文字数: 4.8k 阅读时长 ≈ 4 分钟
Android 启动优化(三) - AnchorTask 使用说明
Android 启动优化(二) - 拓扑排序的原理以及解题思路
本文字数: 4.4k 阅读时长 ≈ 4 分钟
Android 启动优化(二) - 拓扑排序的原理以及解题思路
Android 启动优化(一) - 有向无环图
本文字数: 2.2k 阅读时长 ≈ 2 分钟
Android 启动优化(一) - 有向无环图