建議實(shí)現(xiàn)方式
public class Singleton {
private Singleton() {
// singleton
}
public static getInstance() {
return InstanceHolder.sInstance;
}
private static class InstanceHolder {
private static final Singleton sInstance = new Singleton();
}
}
volatile關(guān)鍵字,在JDK1.5及以后,用于解決this指針逃逸問題:public class Singleton {
private static volatile Singleton sInstance;
private final Context mContext;
private Singleton(Context context) {
mContext = context;
}
public static getInstance(Context context) {
if (sInstance == null) {
synchronized(Singleton.class) {
if (sInstance == null) {
sInstance = new Singleton(context);
}
}
}
return sInstance;
}
}
在DCL單例實(shí)現(xiàn)中,sInstance = new Singleton(context);實(shí)際上大致會(huì)進(jìn)行三個(gè)操作:
Singleton的實(shí)例分配內(nèi)存;Singleton的構(gòu)造函數(shù),初始化成員變量;sInstance指向新分配的內(nèi)存空間(此時(shí)sInstance就不是null了);由于Java memory model的內(nèi)存緩存模型(寄存器,cache,主存),以及允許指令重排,在緩存層面,上述三步中后兩步順序是無法保證的,有可能是1-2-3,也有可能是1-3-2。如果是1-3-2,在A線程執(zhí)行,第三步執(zhí)行完之后,切換到B線程,則B線程執(zhí)行getInstance時(shí)將直接返回sInstance,因?yàn)锽線程將直接命中緩存,但是它的成員變量仍未初始化,一旦使用就會(huì)出現(xiàn)問題。
而volatile關(guān)鍵字則能保證每次讀數(shù)據(jù)都從主存讀取,不會(huì)受到緩存的影響,所以B線程從主存讀到的仍是null,就不會(huì)出現(xiàn)問題了。
Context,它的實(shí)現(xiàn)類是ComtextImpl,它在static代碼塊中初始化各種system service,并保存在一個(gè)map中,后續(xù)獲取的時(shí)候?qū)⒅苯訌膍ap中獲取;android 23起,初始化system service、緩存、單例邏輯的代碼從ContextImpl轉(zhuǎn)移到了SystemServiceRegistry中;LayoutInflater工作原理
PhoneLayoutInflateronCreateView函數(shù)中會(huì)自動(dòng)為其添加包名前綴createView函數(shù)完成,在其中通過反射創(chuàng)建view實(shí)例inflate函數(shù)會(huì)解析xml布局文件,深度優(yōu)先遍歷,逐層創(chuàng)建view(通過createViewFromTag函數(shù)),并最終形成一棵view的樹WindowManager
WindowManagerImplWindow::setContentView()方法來實(shí)現(xiàn)的Window是抽象類,其實(shí)現(xiàn)類為PhoneWindow,它的setContentView方法,怎么和WindowManager關(guān)聯(lián)起來的??WindowManager添加、移除view的實(shí)現(xiàn)工作在WindowManagerGlobal類中ViewRootImpl是framework層與native層通信的橋梁,繼承自HandlerPackageManagerService會(huì)掃描系統(tǒng)內(nèi)所有的APP,解析其manifest文件,得到所有APP注冊(cè)的所有各類組件,保存在系統(tǒng)中(內(nèi)存);后續(xù)使用Intent進(jìn)行跳轉(zhuǎn)時(shí),通過查找保存的組件信息,得知應(yīng)該啟動(dòng)哪個(gè)APP(組件);PackageManagerService::queryIntentActivities(...)方法中;ActivityThread::main()是app的執(zhí)行起點(diǎn) ==>thread.attach(false)把ActivityThread綁定到ActivityManagerService,它調(diào)用了ActivityManagerService::attachApplication方法 ==>ActivityManagerService::attachApplication方法中間接調(diào)用了ActivityThread.ApplicationThread::bindApplication和ActivityManagerService::attachApplicationLocked,前者把ApplicationThread對(duì)象綁定到ActivityManagerService ==>ActivityManagerService::attachApplicationLocked ==>ActivityManagerService::realStartActivityLocked ==>ActivityThread.ApplicationThread::scheduleLaunchActivity ==>ActivityThread.H::handleMessage ==>ActivityThread::handleLaunchActivity ==> ActivityThread::performLaunchActivity ==>Instrumentation::callActivityOnCreate ==>Activity::performCreate ==>Activity::onCreate四種角色:抽象的工廠類,定義工廠的接口;具體的工廠類,實(shí)現(xiàn)生產(chǎn)產(chǎn)品;抽象的產(chǎn)品類,定義產(chǎn)品的接口;具體的產(chǎn)品類,實(shí)現(xiàn)產(chǎn)品的功能;
view.startAnimation(),動(dòng)畫是怎么實(shí)現(xiàn)的?隨時(shí)間改變view屬性的值;TimeInterpolator獲取繪制的時(shí)間百分比,再利用TypeEvaluator把百分比計(jì)算為屬性值,設(shè)置給view;View::startAnimation(Animation animation)在設(shè)置了animation之后,調(diào)用invalidate,invalidate最終調(diào)用到ViewGroup::drawChild(Canvas canvas, View child, long drawingTime) ==>View::draw(Canvas canvas, ViewGroup parent, long drawingTime) ==>View::applyLegacyAnimation(ViewGroup parent, long drawingTime, Animation a, boolean scalingRequired) ==>applyLegacyAnimation函數(shù)中,完成了動(dòng)畫初始化、動(dòng)畫操作、界面刷新(本次動(dòng)畫操作完成后,再次invalidate)Animator::getTransformation(long currentTime, Transformation outTransformation)函數(shù)中實(shí)現(xiàn)ValueAnimator原理
PropertyValuesHolder類中ValueAnimator::start()調(diào)用后,將會(huì)把動(dòng)畫指令發(fā)送給內(nèi)部的ValueAnimator.AnimationHandler類,而handler則使用Choreographer來進(jìn)行定時(shí)的刷新ValueAnimator::doAnimationFrame(long frameTime) ==>ValueAnimator::animationFrame(long currentTime) ==>ValueAnimator::animateValue(float fraction) ==>ObjectAnimator)的重載中,ObjectAnimator::animateValue(float fraction) ==>PropertyValuesHolder::setAnimatedValue(Object target),在其中通過反射,為view設(shè)置屬性ValueAnimator的代碼使用反射工作,設(shè)置動(dòng)畫屬性時(shí)傳入的是字符串,容易產(chǎn)生錯(cuò)誤,有兩個(gè)不錯(cuò)的庫(kù)對(duì)這一點(diǎn)進(jìn)行了優(yōu)化:ViewAnimator, AnimatorCompat一個(gè)對(duì)象的行為取決于它的狀態(tài),最直接的實(shí)現(xiàn)是各個(gè)函數(shù)中對(duì)狀態(tài)進(jìn)行判斷(if-else或switch),采取不同的行為。狀態(tài)模式則是把狀態(tài)抽象為一個(gè)類,不同狀態(tài)下的行為封裝為不同的狀態(tài)實(shí)現(xiàn)類。改變對(duì)象的狀態(tài)時(shí),只需要修改其狀態(tài)對(duì)象,即可達(dá)到修改其行為的目的。
InputReader,從硬件的事件(CPU中斷)中,讀取輸入事件,并封裝為Event對(duì)象,然后分發(fā)給InputDispatcherInputDispatcher負(fù)責(zé)接收來自InputReader的事件,并分發(fā)給合適的窗口,同時(shí)監(jiān)控ANRInputReaderThread,InputDispatcherThread,InputManager,InputManagerService,WindowManagerService又稱訂閱模式,定義了對(duì)象間一對(duì)多的依賴關(guān)系,當(dāng)特定的對(duì)象(subject)變化時(shí),所有依賴它的對(duì)象(observer)都會(huì)得到通知并自動(dòng)更新。
notifyDataSetChangedonChanged方法registerReceiver ==> ContextWrapper::registerReceiver ==>ContextImpl::registerReceiver ==> ContextImpl::registerReceiverInternal
LoadedApk::getReceiverDispatcher函數(shù)創(chuàng)建了一個(gè)IIntentReceiver對(duì)象(Binder對(duì)象)ActivityManagerNative.getDefault().registerReceiver向ActivityManagerService注冊(cè)receiver,并把IIntentReceiver傳遞進(jìn)去,用于ActivityManagerService通知activity接收廣播 ==>ActivityManagerProxy::registerReceiver ===>ActivityManagerService::registerReceiver
receiver.onReceive