首页 文章 精选 留言 我的

精选列表

搜索[零点击],共10000篇文章
优秀的个人博客,低调大师

Android 从零开始打造异步处理框架

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/52847872 本文出自【赵彦军的博客】 概述 封装尝试 Handler优化 线程优化 框架使用 参考资料 概述 在Android中会使用异步任务来处理耗时操作,避免出现界面卡顿的问题,当然到目前为止可以使用的异步任务框架有很多,比如: 直接 new Thread() 用Android自带的AsyncTask 用RxJava 等等 今天我们就来自己尝试写一个异步任务处理框架,代码的设计思路参考AsyncTask 封装尝试 既然是异步的框架,那么肯定是在子线程中,所以第一步我们用自定义的ThreadTask继承Thread. 并且重写里面的run方法。 package com.zyj.app; /** * Created by ${zyj} on 2016/10/17. */ public class ThreadTask extends Thread { @Override public void run() { super.run(); } } 然后子线程需要把处理结果回调给主线程,我们需要定义3个方法: onStart 任务开始之前调用,运行在主线程。可以做显示进度条或者加载动画。 onDoInBackground 异步任务执行,运行在子线程。可以做耗时操作。 onResult 异步任务处理的结果,运行在主线程。 onDoInBackground这个方法是要在子类中实现的,所以要写成抽象的方法,那么ThreadTask类自然也要写成抽象类。同时这个方法会返回异步处理结果,这个结果的类型需要写成泛型,以便在子类中灵活运用。 package com.zyj.app; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; /** * Created by ${zyj} on 2016/10/17. */ public abstract class ThreadTask<T> extends Thread { @Override public void run() { super.run(); } /** * 任务开始之前调用,运行在主线程 */ @MainThread public void onStart(){ } /** * 子线程中调用,运行在子线程 * @return */ @WorkerThread public abstract T onDoInBackground() ; /** * 子线程返回的结果,运行在主线程 * @param t */ @MainThread public void onResult( T t ){ } } 另外子线程和主线程通信我们用的是Handler。Handler的初始化工作放在ThreadTask构造函数中完成。 private Handler handler ; public ThreadTask(){ handler = new Handler( Looper.getMainLooper()){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //在这里接收子线程发过来的消息 } } ; } 最后还需要一个execute() 方法启动线程。在启动的前一刻最好调用Onstart方法。 /** * 开始执行 */ public void execute(){ onStart(); start(); } 最后一个完整的ThreadTask类是这样的 package com.zyj.app; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; /** * Created by ${zyj} on 2016/10/17. */ public abstract class ThreadTask<T> extends Thread { private Handler handler ; public ThreadTask(){ handler = new Handler( Looper.getMainLooper()){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //在这里接收子线程发过来的消息 onResult((T) msg.obj); } } ; } @Override public void run() { super.run(); Message message = Message.obtain() ; message.obj = onDoInBackground() ; handler.sendMessage( message ) ; } /** * 任务开始之前调用,运行在主线程 */ @MainThread public void onStart(){ } /** * 子线程中调用,运行在子线程 * @return */ @WorkerThread public abstract T onDoInBackground() ; /** * 子线程返回的结果,运行在主线程 * @param t */ @MainThread public void onResult( T t ){ } /** * 开始执行 */ public void execute(){ onStart(); start(); } } 如何使用我们写好的框架? new ThreadTask<String>(){ @Override public void onStart() { super.onStart(); Log.d( "ThreadTask " , "onStart线程:" + Thread.currentThread().getName() ) ; } @Override public String onDoInBackground() { Log.d( "ThreadTask " , "onDoInBackground线程: " + Thread.currentThread().getName() ) ; //模拟耗时操作 try { Thread.sleep( 3000 ); } catch (InterruptedException e) { e.printStackTrace(); } return "结果返回了"; } @Override public void onResult(String s) { super.onResult(s); Log.d( "ThreadTask " , "onResult线程: " + Thread.currentThread().getName() + " 结果:" + s ) ; } }.execute(); 运行的结果: ThreadTask: onStart线程:main ThreadTask: onDoInBackground线程: Thread-229 ThreadTask: onResult线程: main 结果:结果返回了 Handler优化 到目前为止我们的框架初步就封装好了,但是有没有缺点呢,肯定是有的。首先每次创建一个ThreadTask的时候都会创建一个Handler,这显然不是我们想看到的。 要保证Handler的实例的唯一性,可以用单例模式来获取Handler /** * 单例模式,保证handler只有一个实例 * @return */ private static Handler getHandler(){ if ( handler == null ){ synchronized ( MHandler.class ){ if ( handler == null ){ handler= new MHandler( Looper.getMainLooper()) ; } } } return handler ; } MHandler是我们自定义的一个Handler类 private static class MHandler extends Handler { public MHandler( Looper looper ){ super( looper ); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); //在这里接收子线程发过来的消息 ResultData resultData = (ResultData) msg.obj; resultData.threadTask.onResult( resultData.data ); } } ResultData是一个消息实体 /** * handler发送数据的实体 * @param <Data> */ private static class ResultData<Data>{ ThreadTask threadTask ; Data data ; public ResultData( ThreadTask threadTask ,Data data ){ this.threadTask = threadTask ; this.data = data ; } } 一个完整的代码实例 package com.zyj.app; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; /** * Created by ${zyj} on 2016/10/17. */ public abstract class ThreadTask<T> extends Thread { private static Handler handler ; public ThreadTask(){ } @Override public void run() { super.run(); Message message = Message.obtain() ; message.obj = new ResultData<T>( this , onDoInBackground() ) ; getHandler().sendMessage( message ) ; } /** * 任务开始之前调用,运行在主线程 */ @MainThread public void onStart(){ } /** * 子线程中调用,运行在子线程 * @return */ @WorkerThread public abstract T onDoInBackground() ; /** * 子线程返回的结果,运行在主线程 * @param t */ @MainThread public void onResult( T t ){ } /** * 开始执行 */ public void execute(){ onStart(); start(); } /** * 单例模式,保证handler只有一个实例 * @return */ private static Handler getHandler(){ if ( handler == null ){ synchronized ( MHandler.class ){ if ( handler == null ){ handler= new MHandler( Looper.getMainLooper()) ; } } } return handler ; } private static class MHandler extends Handler { public MHandler( Looper looper ){ super( looper ); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); //在这里接收子线程发过来的消息 ResultData resultData = (ResultData) msg.obj; resultData.threadTask.onResult( resultData.data ); } } /** * handler发送数据的实体 * @param <Data> */ private static class ResultData<Data>{ ThreadTask threadTask ; Data data ; public ResultData( ThreadTask threadTask ,Data data ){ this.threadTask = threadTask ; this.data = data ; } } } 到现在已经解决了Handler多次创建的问题,那么这个ThreadTask本质上还是新建线程来运行异步任务,为了避免不断的创建线程,所以还需要一个线程池。 线程优化 首选定义一个线程池,默认最大10个线程。 /** * 线程池,创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 */ private static ExecutorService executorService = Executors.newFixedThreadPool( 15 ) ; 修改run()方法。 private void run() { executorService.execute(new Runnable() { @Override public void run() { Message message = Message.obtain() ; message.obj = new ResultData<T>( ThreadTask.this , onDoInBackground() ) ; getHandler().sendMessage( message ) ; } }); } execute() 方法 /** * 开始执行 */ public void execute(){ onStart(); run(); } 完整的代码实例 package com.zyj.app; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by ${zyj} on 2016/10/17. */ public abstract class ThreadTask<T> { private static Handler handler ; /** * 线程池,创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 */ private static ExecutorService executorService = Executors.newFixedThreadPool( 15 ) ; public ThreadTask(){ } private void run() { executorService.execute(new Runnable() { @Override public void run() { Message message = Message.obtain() ; message.obj = new ResultData<T>( ThreadTask.this , onDoInBackground() ) ; getHandler().sendMessage( message ) ; } }); } /** * 任务开始之前调用,运行在主线程 */ @MainThread public void onStart(){ } /** * 子线程中调用,运行在子线程 * @return */ @WorkerThread public abstract T onDoInBackground() ; /** * 子线程返回的结果,运行在主线程 * @param t */ @MainThread public void onResult( T t ){ } /** * 开始执行 */ public void execute(){ onStart(); run(); } /** * 单例模式,保证handler只有一个实例 * @return */ private static Handler getHandler(){ if ( handler == null ){ synchronized ( MHandler.class ){ if ( handler == null ){ handler= new MHandler( Looper.getMainLooper()) ; } } } return handler ; } private static class MHandler extends Handler { public MHandler( Looper looper ){ super( looper ); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); //在这里接收子线程发过来的消息 ResultData resultData = (ResultData) msg.obj; resultData.threadTask.onResult( resultData.data ); } } /** * handler发送数据的实体 * @param <Data> */ private static class ResultData<Data>{ ThreadTask threadTask ; Data data ; public ResultData( ThreadTask threadTask ,Data data ){ this.threadTask = threadTask ; this.data = data ; } } } 框架使用 方式1 new ThreadTask<String>(){ @Override public String onDoInBackground() { return "我是线程"; } }.execute(); 方式2 new MyTask().execute(); class MyTask extends ThreadTask<String> { @Override public void onStart() { super.onStart(); } @Override public String onDoInBackground() { try { //模拟耗时操作 Thread.sleep( 2000); } catch (InterruptedException e) { e.printStackTrace(); } return "ThreadTask" ; } @Override public void onResult(String s) { super.onResult(s); } } 参考资料 【1】Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池 【2】Android 自定义线程池的实战 【3】Java 单例模式 【4】Android Handler、Loop 的简单使用 【5】Android 更新UI的几种方式

优秀的个人博客,低调大师

Docker 从零开始制作基础镜像[centos]

http://www.oschina.net/news/62897/docker-hub-contains-high-risk-vulnerabilities这里有个统计,docker官方和个人发布的镜像由于版本等各种原因,漏洞较多,那我们如何自己从头开始做个定制的镜像呢? 对,找官方文档http://docs.docker.com/articles/baseimages/,这里说明的很清楚了 试验如下:在centos7机器上做centos镜像 直接参考这个脚本 https://raw.githubusercontent.com/docker/docker/master/contrib/mkimage-yum.sh ./mkimage-yum.sh-y/etc/yum.confcentos7 执行如上脚本,成功后,就可以看到镜像了【dockerimages】,概要说明一下,主要是如下几步: 1.tmp目录下建立临时目录和文件系统 2.使用yum安装相关的软件包 3.软件包安装和信息定制 4.tar打包 5.清理 建立目录结构[rootfs] target=$(mktemp-d--tmpdir$(basename$0).XXXXXX) set-x mkdir-m755"$target"/dev mknod-m600"$target"/dev/consolec51 mknod-m600"$target"/dev/initctlp mknod-m666"$target"/dev/fullc17 mknod-m666"$target"/dev/nullc13 mknod-m666"$target"/dev/ptmxc52 mknod-m666"$target"/dev/randomc18 mknod-m666"$target"/dev/ttyc50 mknod-m666"$target"/dev/tty0c40 mknod-m666"$target"/dev/urandomc19 mknod-m666"$target"/dev/zeroc15 #amazonlinuxyumwillfailwithoutvarsset if[-d/etc/yum/vars];then mkdir-p-m755"$target"/etc/yum cp-a/etc/yum/vars"$target"/etc/yum/ fi 软件包安装和信息定制 yum-c"$yum_config"--installroot="$target"--releasever=/--setopt=tsflags=nodocs\ --setopt=group_package_types=mandatory-ygroupinstallCore yum-c"$yum_config"--installroot="$target"-ycleanall ... 打包 tar--numeric-owner-c-C"$target".|dockerimport-$name:$version dockerrun-i-t$name:$versionechosuccess 清理 rm-rf"$target" 如果我们需要自己的安全增强软件等定制,只需要在第2步将我们的内容合并进去即可 生成的镜像可以作为我们工作的基础,当然你也可以push到开源社区

优秀的个人博客,低调大师

零报错却零产出:舞台工艺图纸 AI 批处理导出链路的三站排查手册

某滨海文化中心的一次舞台工艺图纸送审,六十多张 DWG 要在半小时内转成 DXF、抽出图号、和送审目录做比对,最后给出缺项清单。管线搭好了:Python 负责编排,AutoCAD Core Console(accoreconsole.exe)负责转换,ezdxf 负责读回来解析。第一次跑,控制台刷了满屏 [ OK ],退出码 0,日志里没有一个 ERROR。

优秀的个人博客,低调大师

本地生活学GEO优化:用户开始信AI一句话答案,你还在等蓝链点击?

一个做本地生活的老板最近发现:用户在问完AI之后,不再逐条点开搜索结果,而是直接采纳AI综合答案——答案里提到了谁,谁就拿到曝光。这篇把AI搜索时代品牌流量入口的改写讲透:SEO优化争「被找到」、GEO优化争「被推荐」,两者不是替代是叠楼,GEO优化是上层建筑、SEO优化是地基。结论先说:入口从「结果页第十条蓝链」挪到了「AI答案里被点名推荐的那句话」,品牌要争的是AI愿不愿意在答案里写上你的名字。

优秀的个人博客,低调大师

今晚直播|高晓松“在阿里工作是一种什么样的体验” 点击加入CIO学院,群内观看

音乐天才vs计算机天才,直播来啦! 25岁音乐作品上春晚,27岁举办“个人作品音乐会”,30岁导演电影,43岁《晓说》开播,46岁加入阿里巴巴,现任阿里娱乐战略委员会主席。 他就是高晓松,5年前加入阿里巴巴,花名矮大紧。在阿里工作是一种什么样的体验?高晓松有认真上班吗? 今天(3月26日)晚18:50,矮大紧在线营业,给你一份“不靠谱的职业规划”。 15岁考入西安交大少年班。23岁成为阿里最年轻的高级技术专家。32岁被评选为2017年度全球35位35岁以下的青年科技创新人才(TR35)。2017年受命在阿里云成立神秘的「A组」。 他就是阿里巴巴研究员,“白帽黑客”吴翰清,被大家亲切地称为“小黑”“道哥”。 今天(3月26日)晚19:20,道哥有话想说,关于自己,关于机器智能,关于未来,说给你听,说给世界听。 扫描二维码,相约「CIO学院」群,看直播,不见不散!

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册