以后会不定期的更新一下这个主题。
学习了几年android,感觉也遇到瓶颈了。完成项目需求也没什么难度,就是时间问题,深入的去定制和修改一些东西,反而感觉力不从心。最近换工作,去了一个二线大厂,项目的确庞大了很多,以前不爱看源码的我,因为需求的原因,不得不眼花缭乱的看着别人改的不再改的代码,偶尔遇到问题,也懒得网上查找,就直接打开了源码去查看原因。可能看久了我们项目的令人眼花缭乱的代码,突然android源码的结构清晰,设计严谨,考虑全面,从未如此鲜明的呈现在我眼前,只感觉眼前一亮,一种强大的吸引力,让我对google工程师们写的代码增加了几分“憧憬”和好奇。原来,真正的宝藏在身边呀。
所以,我就忍不住写这些博客,一起分享我的android源码之旅,一起见证google工程师们的“神来之笔”。
20170823:
一直想精通一下属性动画,但是项目中一直都没有机会用,都是用的其它的动画(逐帧动画、补间动画),所以打开源码,想看看到底怎样实现的,
于是 找到了 Animator 这个类。看到了如下实现,感觉不错,拿出来分享:
/**
* Pauses a running animation. This method should only be called on the same thread on
* which the animation was started. If the animation has not yet been {@link
* #isStarted() started} or has since ended, then the call is ignored. Paused
* animations can be resumed by calling {@link #resume()}.
*
* @see #resume()
* @see #isPaused()
* @see AnimatorPauseListener
*/
public void pause() {
if (isStarted() && !mPaused) {
mPaused = true;
if (mPauseListeners != null) {
ArrayList<AnimatorPauseListener> tmpListeners =
(ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
int numListeners = tmpListeners.size();
for (int i = 0; i < numListeners; ++i) {
tmpListeners.get(i).onAnimationPause(this);
}
}
}
}
有没有看到特别之处,其实不就是循环遍历它的listener,然后调用其方法嘛。但是google为什么要 mPauseListeners.clone()
?
我们都知道,如果遍历ArrayList集合过程中,我们增加或者删除了item,就会报
ConcurrentModificationException
,google工程师们通过arrayList.clone()
将内容赋给了临时集合,然后遍历这个临时集合,当外面对原来的listener集合增加或者删除listener时,不会出现这个异常。所以,不嘚嘚,你get到了吗?
20170906
String、StringBuffer、StringBuilder
面试都爱问他们三个的关系,最近扫了一下源码,又加深了一下理解:
首先要明白:String对象存储字符串是用的char[]。
你创建完String对象后,它就是不可变的(包括长度、内容),任何的更改都会产生新的String对象,包括拼接,replace,subSequence等。在它的这些变更内容的方法里,都进行了new char[],并且copy内容的过程。
StringBuffer、StringBuilder都是可变长度的,对他们内容更改不会产生新的对象。同String,也是用char[]存放内容,并且初始char[]长度是16,每次更改内容(如:append)都会进行char[]长度检查,如果不够则进行扩容,每次扩容为原来的2倍再加2。即:原来char[]长度 * 2 +2;
- StringBuffer、StringBuilder的区别在于StringBuffer是线程安全的,因为他的每一个操作内容的方法都是用
synchronized
修饰的。所以造成StringBuffer效率低下。这是他们的唯一区别。(他们都是继承AbstractStringBuilder
,方法调用过程都一样)。如果只是在单线程中使用,要用StringBuilder.
未完待续 …