自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

聚精会神搞建设

一心一意谋发展

  • 博客(355)
  • 资源 (6)
  • 收藏
  • 关注

原创 EventBus源码分析(四):线程模型分析(2.4版本)

EventBus有四种线程模型PostThread模式不需线程切换,直接在发布者线程进行事件处理。MainThread模式分类讨论:发布者线程是主线程则直接调用事件处理方法,否则通过Handler进行线程切换,切换到主线程处理事件,该模式下事件是串行执行的。BackgroundThread模式分类讨论:发布者线程不是主线程则在发布者线程直接处理事件,否则线程切换至线程池处理,所有该线程模式下的

2016-07-05 19:59:36 2194

原创 EventBus源码分析(三):post方法发布事件【获取事件的所有订阅者,反射调用订阅者事件处理方法】(2.4版本)

EventBus维护了一个重要的HashMap,这个HashMap的键是事件,值是该事件的订阅者列表,因此post事件的时候就能够从此HashMap中取出事件的订阅者列表,对每个订阅者反射调用事件处理方法。 private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;post方

2016-07-04 15:20:03 2751

原创 EventBus源码分析(二):register方法保存事件的订阅者列表(2.4版本)

EventBus维护了两个重要的map:事件到订阅者列表的map,发布事件的时候可以根据事件获取订阅者列表,这样可以逐一反射调用订阅者的事件处理方法。订阅者到事件列表的map,这样订阅者向EventBus解除注册(unregister)的时候可以根据订阅者获取该订阅者订阅的所有事件,对每个事件分别解除注册。因此register注册订阅者的时候,EventBus会通过反射寻找订阅者订阅的所有事件

2016-07-04 11:11:08 1240

原创 EventBus源码分析(一):入口函数提纲挈领(2.4版本)

本文是EventBus源码分析的第一篇文章,不拘泥于具体的实现细节,从宏观上把握EventBus的设计思路,而EventBus总体的设计思路为: EventBus实例保存了事件到订阅者列表的map,发布事件的时候,从该map中取出该事件的所有订阅者,在规定的线程中反射调用所有订阅者的事件处理方法。DCL单例创建EventBus对象EventBus提供了静态方法创建EventBus对象,实现方式为标

2016-07-01 15:58:42 1205

原创 Picasso源码分析(六):BitmapHunter与请求结果的处理

into方法流程回顾into方法首先检查了是否在主线程,控件是否为null,用户有没有设置uri或者资源id,是否调用了fit方法自适应压缩。接着根据into方法调用时间创建Request请求,并为该请求设置缓存用的key。接着判断是否要读内存缓存,可以读内存缓存并且命中的话就将缓存中的图片显示在控件然后返回,否则开启网络请求。网络请求的过程中暂时显示占位图。 网络请求的过程就是针对此次请求封装成

2016-06-22 16:30:48 1689 1

原创 Picasso源码分析(五):into方法追本溯源和责任链模式创建BitmapHunter

Picasso异步加载图片流程回顾首先通过with方法创建单例Picasso对象 public static Picasso with(Context context) { if (singleton == null) { synchronized (Picasso.class) { if (singleton == null) { sing

2016-06-21 16:58:14 4697 1

原创 java中异常处理finally和return语句的执行顺序

finally代码块的语句在return之前一定会得到执行如果try块中有return语句,finally代码块没有return语句,那么try块中的return语句在返回之前会先将要返回的值保存,之后执行finally代码块,最后将保存的返回值返回,finally代码块虽然对返回值进行修改也不影响返回值,因为要返回的值在执行finally代码块之前已经保存了,最终返回的是保存的旧值。如果try

2016-06-14 19:36:12 3893

原创 Picasso源码分析(四):不变模式、建造者模式和Request的预处理

Request的不变模式(Immutable Pattern)  不变模式可增强对象的强壮型,允许多个对象共享某一个对象,降低了对该对象进行并发访问时的同步化开销。如果需要修改一个不变对象的状态,那么就需要建立一个新的同类型对象,并在创建时将这个新的状态存储在新对象里。   不变模式只涉及到一个类。一个类的内部状态创建后,在整个生命周期都不会发生变化时,这样的类称作不变类。   不变模式的优点:

2016-06-14 17:06:55 2082

原创 Picasso源码分析(三):快照功能实现和HandlerThread的使用

HandlerThread原理和用法HandlerThread是一个Android系统提供的提供快速开发的工具类,功能为开启一个具有looper的线程,该线程的looper可以和handler绑定,也就是说创建handler的时候可以在handler构造函数传入handlerThread对象的looper,这样此handler的消息处理 方法handleMessage就会在handlerThread

2016-06-13 10:35:45 1379 1

原创 Picasso源码分析(二):默认的下载器、缓存、线程池和转换器

下载器当用户没有为Picasso指定下载器的时候Picasso会通过Utils.createDefaultDownloader(context)方法创建一个默认的下载器 static Downloader createDefaultDownloader(Context context) { try { Class.forName("com.squareup.okhttp.OkH

2016-06-12 22:45:55 4522

原创 Picasso源码分析(一):单例模式、建造者模式、面向接口编程

Picasso简单介绍Picasso使用建造者设计模式,使异步网络加载图片到控件这一复杂流程可以用一条方法链搞定。典型的Picasso加载图片的使用方式如下:Picasso.with(context).load(url).into(imageView); 传入上下文context构造获取Picasso然后异步加载图片链接获取图片最后显示在控件上,一气呵成 或者可以对加载到的图片进行尺寸压缩后再显示

2016-06-12 17:06:07 1873

原创 jdk源码分析之WeakHashMap

基本原理WeakHashMap特点是,当除了自身有对key的引用外,此key没有其他引用,那么WeakHashMap会在下次对WeakHashMap进行增删改查操作时及时丢弃该键值对,节约内存使用,此特性使得WeakHashMap非常适合构建缓存系统。 WeakHashMap是主要通过expungeStaleEntries函数的来实现移除其内部不用的entry从而达到的自动释放内存的目的。基本上只

2016-06-08 10:39:33 1551

原创 jdk源码分析之PriorityQueue

基本原理PriorityQueue(优先级队列)的数据结构是最小堆,采用数组作为底层数据结构。 不同于普通的遵循FIFO规则的队列,PriorityQueue每次都选出优先级最高的元素出队,优先队列里实际是维护最小堆,通过最小堆使得每次取出的元素总是优先级最高的。 /** * Priority queue represented as a balanced binary heap:

2016-06-07 16:36:44 765

原创 Volley源码分析【面向接口编程的典范】

基本原理Volley采用生产者消费者模型,生产者(Volley的使用者)通过调用add方法给请求队列添加请求,缓存调度器和网络调度器作为消费者从请求队列取出请求处理,根据不同情况决定走缓存还是走网络请求数据,最后切换线程,将请求的数据回调给UI线程。创建请求队列Volley通过静态工厂方法newRequestQueue生成一个请求队列RequestQueue public static Req

2016-06-03 16:28:08 3988

原创 jdk源码分析之LinkedHashMap

基本原理LinkedHashMap继承自HashMap,因此具有HashMap的所有特性。在HashMap的基础上,保持了key的插入顺序或者访问顺序。实现方法就是用双向循环链表将所有的entry链接起来,读取数据的时候直接读取此双向循环链表的数据即可。public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

2016-06-02 11:11:06 752 1

原创 jdk源码分析之ConcurrentHashMap

基本原理Hashtable使用synchronized锁住整张Hash表,锁的粒度太大导致Hashtable性能低下。ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁

2016-06-01 22:30:22 3289

原创 jdk源码分析之CopyOnWriteArrayList

CopyOnWriteArrayList的原理CopyOnWriteArrayList的核心思想是利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的数组,在新的数组上面修改,然后将新数组赋值给旧数组的引用,并通过volatile 保证其可见性,通过Lock保证并发写。底层数据结构private volatile transient Object[] array;final O

2016-05-25 14:53:09 684

原创 jdk源码分析之HashMap

HashMap的底层数据结构HashMap底层采用数组加链表的数据结构存储键值对 Hash根据key的哈希值转化为数组的下标将键值对存入数组中,数组的元素是一个链表,冲突的key放置在数组的同一个位置,使用链表将冲突的数据链接起来 数组的底层结构如下: /** * An empty table instance to share when the table is not in

2016-05-25 14:02:25 586

原创 jdk源码分析之ArrayList

ArrayList关键属性分析ArrayList采用Object数组来存储数据 /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffe

2016-05-24 13:52:55 888

原创 jdk源码分析之LinkedList

LinkedList关键属性size表示当前链表保存了多少数据,first指针指向链表第一个数据,last指针指向链表最后一个数据 transient int size = 0; /** * Pointer to first node. * Invariant: (first == null && last == null) || *

2016-05-23 15:06:34 845

原创 Android开发获取相机拍照的原图(并非缩略图)

Android开发拍照上传是个很常见的功能,通过如下代码可以激活相机进行拍照: Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(intent, PHOTO_REQUEST_CAREMA);通过下边的代码获取相机返回的照片数据: @Overri

2016-05-21 14:40:10 4457 1

原创 Android开发AsyncTask源码分析【模板方法模式】

模板方法定义了一个算法的框架,将框架中一些步骤延迟到子类中实现,使子类可以不修改一个算法的框架结构就可以重定义框架的某些步骤。模板方法实际上市封装一个固定的流程,流程的步骤在抽象类中已经定义好了,子类可以有不同的算法实现,这样就可以在框架流程不修改的情况下实现某下算法的替换AsyncTask的模板方法使用AsyncTask,只要构造AsyncTask对象,然后调用execute方法即可。

2016-05-19 21:07:53 455

原创 Android开发Message源码分析【享元模式|对象池】

享元模式是对象池的一种实现,尽可能减少内存的使用,使用缓存来共享可用的对象,避免创建过多的对象。Android中Message使用的设计模式就是享元模式,获取Message通过obtain方法从对象池获取,Message使用结束通过recycle将Message归还给对象池,达到循环利用对象,避免重复创建的目的

2016-05-19 14:54:21 1338 2

原创 Android开发Handler源码分析

Android中UI控件的访问是线程不安全的,加锁同步访问会影响性能,因此设置只能一个线程更新UI,就是主线程,或者说是UI线程。在UI线程中不能进行耗时的操作,耗时操作需要开启一个新的工作线程,工作线程不能更新UI,因此工作线程通过Handler通知UI线程更新UI

2016-05-19 12:48:17 415

原创 Android开发自定义控件实现一个折线图

实现一个如下图所示的折线图首先是控件绘图区域的划分,控件左边取一小部分(控件总宽度的八分之一)绘制表头,右边剩余的部分绘制表格确定表格的行列数,首先绘制一个三行八列的网格,设置好行列的坐标后开始绘制/*绘制三条横线*/canvas.drawLine(textWide, mLineYs[0], totalWidth, mLineYs[0], mPaintLine);

2016-05-18 17:15:39 4984 1

原创 AndroidStudio导入新项目一直卡在Building gradle project info的解决解决方案

尝试了各种办法,翻墙,离线gradle等,发现一个更好用更简单的办法:解决方案:1.随便找一个你能运行的as项目2.打开gradle-wrapper.properties,文件目录:项目/gradle/wrapper/gradle-wrapper.properties3.复制distributionUrl这一整行的内容,eg: distributio

2016-05-18 16:24:03 3016 1

原创 Android开发自定义控件实现一个圆形进度条【带数值和动画】

实现一个如下图所示的自定义控件,可以直观地展示某个球队在某个赛季的积分数和胜场、负场、平局数首先对画布进行区域划分,整个控件分上下两部分上边是个大的圆环,圆环中间两行文字,没什么难度,选好圆心坐标和半径后直接绘制即可,绘制文字也是如此。下部分是三个小的圆弧进度条,弧的末端绘制一个小的实心圆首先选好坐标和半径,然后先绘制三个圆环作为弧形进度条的背景之后从12点钟开始绘制进

2016-05-16 21:34:29 3550 2

原创 Android开发自定义控件实现一个球赛胜负数统计条

效果如下图所示,展示两个球队交战胜负信息首先此控件在水平方向均分为5份,第一份和第五份留白不绘制内容第二三四份分别绘制3列数据垂直方向分为N份,N和输入数据的最大值有关垂直方向下边百分之二十的空间显示文本,上边百分之八十的空间显示指定数量的横线,横线上方显示横线的数量因为垂直方向做了N等分,因此垂直方向相当于有了一个刻度,经过计算每条横线绘制在属于自己的刻度处即可‘

2016-05-12 16:04:27 886

原创 Android开发自定义控件实现一个足球积分榜RankBar

为了实现一个如下图红色方框所示的控件,系统自带控件并不能满足要求,因此需要继承View重新画一个这样的控件分析此控件发现分为3部分,中间的一列横线和左右两个标签中间的部分好绘制,通过循环调用canvas的drawLine方法即可然后分析左右两边的两个标签,因为左右两个是一样的,因此只分析左边的外围形状是一个圆环被拉出来了一个三角形,这个三角形是等边三角形,等边三角形的上边顶点设

2016-05-11 11:02:38 2128 1

原创 Android自定义控件之实现一个球赛比分条

效果图如下所示:该控件需要输入两个参数,左边的得分数和右边的的分数然后根据两边的得分的比例绘制中间的比分条首先将控件的宽度平均分配为10分,第一份和最后一份分别绘制左边的比分数字和右边的比分数字中间的8分宽度绘制比分条根据左右两个比分所占的比例,绘制两个两条首位相连的线段即可完整代码如下:public class CustomScoreBar extends V

2016-05-09 22:38:40 3048

原创 Android自定义控件实现一个带文本与数字的圆形进度条

实现的效果图如下所示:第一步:绘制下方有缺口的空心圆,称为外围大弧吧anvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4);第二步:计算绘制圆弧进度条时的起始角度,设置为外围大弧的左端点为进度值得起点,扫过的角度所占外围大弧的百分比就是进度值第三步:绘制数字、文字、百分号第四

2016-05-09 22:02:41 3562 1

原创 Android开发自定义控件实现一个饼状图

实现一个如图所示的控件,包括两部分,左边的饼状图和中间的两个小方块,及右边的两行文字实现起来比较简单,只是一些绘图API的调用核心代码在onDraw函数里边,,对静态控件进行绘制即可@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); /*饼状图的x坐标*/ fl

2016-05-09 17:17:12 3380

原创 封装Volley使Volley的每个请求都自动保存和发送Cookie

思路很简单,每次请求获取到服务器返回的response就解析头部获取cookie并保存,发送请求的时候就从本地读取cookie添加到头部发送给服务器第一步,解析http response头部的cookie并保存,自定义一个Request并重写其parseNetworkResponse方法/** * 解析数据,保存Cookie * @param response * @return

2016-05-09 09:15:53 1556

原创 Android开发中利用imeOptions属性将键盘回车键改成搜索等功能键【提高用户输入体验】

Android中键盘输入是用户输入交互的最常用最直接的手段,关于键盘输入,有几点可以提高用户使用体验。第一:弹出键盘整体页面上移,使键盘不遮挡控件,需要在AndroidManifest设置对应Activity的windowSoftInputMode属性stateVisible    设置为这个属性,可以将软键盘召唤出来,即使在界面上没有输入框的情况下也可以强制召唤出来

2016-05-09 08:26:09 4795 1

原创 Android开发调用第三方邮件应用发送邮件

重构一个项目,发现发送邮件的功能是自己实现的,使用java的一个类库在app内部集成了发送邮件的功能。这样实现问题比较多,该类库并非针对android设计,用在android上有很多稳定,性能低下,并且不稳定。在一个app内部实现一个发送邮件的功能感觉是跟鸡肋的,要自己处理邮件通信协议,还要处理富文本编辑、发送附件等问题。其实调用第三方或者系统自带邮件功能发送邮件是比较好的解决办法,也

2016-05-06 16:38:32 4423

原创 RecyclerView.addFocusables出现空指针异常NullPointerException的解决办法

如果使用的RecyclerView是API22版本,或者更低版本,如果RecycleView没有设置LayoutManager,那么RecycleView将会包空指针异常,异常信息只会显示java.lang.NullPointerExceptionat android.support.v7.widget.RecyclerView.addFocusables这时候会出现一头雾水,原因就是

2016-05-04 16:34:17 2626

原创 Android 自定义一个轮播图

有限空间内展示更多的内容,轮播图是个不错的选择,本文将实现一个轮播图SlideShowView,效果如下图所示:因为轮播图的每一个页面都有文字和图片,为了整合图片和文字,SlideShowView选择继承Fraementpublic class SlideShowView extends FrameLayout轮播图的主要属性如下:/*存储图片链接*/priv

2016-05-03 10:26:52 889

原创 用getChildFragmentManager解决Fragment嵌套Fragment数据丢失的问题

如下图所示的布局,外边的红色大框是个fragment,中间的小框是个viewpager,里边包含了若干的fragment。再次进入外边这个frament的时候,会出现中间viewpager中fragment数据丢失的问题,整个显示是一个空白,textview的内容全部不见了。在Fragment里面嵌套Fragment 的话,不要用getActivity().getSupport

2016-05-03 09:46:14 3501

原创 Volley中listener导致的内存泄露

项目中用Volley作为http框架,封装了一个JsonRequest,性能优化的时候,LeakCanary一直提示Volley的listener内存泄露,检查了很久也没发现哪里出现内存泄露public class JsonRequestImpl extends JsonRequestJSONObject > { public JsonRequestImpl(int method,

2016-04-26 11:38:13 2964 2

原创 调整数组顺序使奇数位于偶数前面,偶数和偶数之间的相对位置不变

题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。思路:先扫描一遍数组,做三件事,1、奇数往前挪,2、统计偶数个数,3、保存偶数到队列。扫描结束后,奇数都被挪到了前边,紧凑的挨在一块,后边留出了一些空余的位置,位置的个数就是偶数的个数。将保存在队列里边的偶数按照进队列

2016-04-25 15:59:50 2984

值得学习的MySQL行级锁、表级锁、页级锁详细介绍

值得学习的MySQL行级锁、表级锁、页级锁详细介绍

2019-03-13

为什么说B+树比B树更适合做文件索引

为什么说B+树比B树更适合做文件索引

2019-03-13

「Redis」Redis是单线程的,但Redis为什么这么快?

「Redis」Redis是单线程的,但Redis为什么这么快?

2019-03-13

如何成功运行Apache Mahout的Taste Webapp-Mahout推荐教程-Maven3.0.5-JDK1.6-Mahout0.5

教你成功运行mahout的taste webapp例子,网上的很多资料说的不清楚,或者版本冲突。正确的版本是jdk1.6 maven3.0.5 mahout0.5 。 摸索良久,亲测有效!

2016-11-23

安卓二维码生成与扫描完美解决方案

Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果 这篇文章写的不错,但是按照这篇文章使用二维码的话会出现竖屏扫描图像拉伸变长的问题(有一个地方计算错误),解决拉伸变长的问题后又会出现闪退的问题(传输大Bitmap对象导致闪退,改为Byte数组或者不传递Bitmap) 其他地方不动,即可完美移植二维码扫描功能

2016-03-08

10小时学会c语言,初学者入门必看。高效学习。

十小时学会c语言,初学者必看的入门读物Word文档

2011-04-04

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除