在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》一書
Launch mode 和 Intent flags專題
Canvas & Drawables
UTAustinX_UT.9.01x: Effective Thinking Through Mathematics
《JavaScript 語(yǔ)言精粹》
Memory leak專題
React基礎(chǔ)
《Test Driven Development: By Example》一書
Developer tools
安卓開發(fā)技能樹
<a rel="nofollow" href="https://mp.weixin.qq.com/s?__biz=MzA3NDM
Best Practices for Interaction and Engagement
各個(gè)安卓版本引入的主要新特性
Building Apps with Connectivity &amp; the Cloud
List.toArray()再?gòu)?qiáng)轉(zhuǎn)是一定會(huì)失敗的
深入Android frameworks
Google dev 100 days系列視頻
Building Apps with Contacts &amp; Sign-In
關(guān)系型數(shù)據(jù)庫(kù)設(shè)計(jì)范式
《App研發(fā)錄》一書
REST API設(shè)計(jì)
Google IO 2015摘要
自定義View/ViewGroup以及高性能實(shí)現(xiàn)自定義UI
安卓系統(tǒng)點(diǎn)擊事件處理
《50 Android Hacks》一書
Building Apps with Content Sharing
Flux基礎(chǔ)
<a rel="nofollow" href="http://developer.android.com/training/in
依賴注入(以Dagger 2為例)
Java同步機(jī)制
Java對(duì)象內(nèi)存的使用情況
JSR133(Java memory model)
Google官方Material Design手冊(cè)(<a rel="nofollow" href="http://develop
Futurice公司安卓團(tuán)隊(duì)的建議
安卓性能優(yōu)化
  • 1.
Best Practices for Performance
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
<a rel="nofollow" href="http://blog.danlew.net/2014/11/19/styles
Handling Runtime Changes
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
Building Apps with Graphics &amp; Animation
<a rel="nofollow" href="http://tools.android.com/tech-docs/new-b
Android項(xiàng)目架構(gòu)
MVP(Model-View-Presenter)模式
<a rel="nofollow" href="http://www.infoq.com/cn/es6-in-depth/"">
《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》一書
Rx在Android中的最佳實(shí)踐
函數(shù)調(diào)用時(shí),傳遞參數(shù)應(yīng)該是不可變的(Immutable)
ProGuard
面向?qū)ο罅笤瓌t(SOLID+)
深入理解Java虛擬機(jī)
深入Java深淺拷貝、immutable、unmodifiable
Best Practices for User Input
UI上的一些高效方式/最佳實(shí)踐
<a rel="nofollow" href="https://blog.stylingandroid.com/ripples-
Best Practices for User Interface
安卓測(cè)試驅(qū)動(dòng)開發(fā)/安卓測(cè)試驗(yàn)證
暗時(shí)間:學(xué)會(huì)正確思考
技術(shù)筆記
Aspect Oriented Programming(AOP)
Best Practices for Background Jobs
安卓系統(tǒng)動(dòng)效專題
Feed系統(tǒng)的設(shè)計(jì)
Data binding(MVVM,Model-View-ViewModel)
Effective Java一書筆記
<a rel="nofollow" href="http://developer.android.com/training/in
Rx (Reactive eXtention)
MultiDex專題
一些很棒的點(diǎn)子
WebRTC

《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》一書

面向?qū)ο蟮牧笤瓌t

單例模式

  • 建議實(shí)現(xiàn)方式

    • 無參數(shù)時(shí),static inner holder class方式:
    public class Singleton {
        private Singleton() {
            // singleton
        }
    
        public static getInstance() {
            return InstanceHolder.sInstance;
        }
    
        private static class InstanceHolder {
            private static final Singleton sInstance = new Singleton();
        }
    }
    • 有參數(shù)時(shí),優(yōu)化的double check lock (DCL)方式,注意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;
        }
    }
    • this指針逃逸問題

      在DCL單例實(shí)現(xiàn)中,sInstance = new Singleton(context);實(shí)際上大致會(huì)進(jìn)行三個(gè)操作:

      1. Singleton的實(shí)例分配內(nèi)存;
      2. 調(diào)用Singleton的構(gòu)造函數(shù),初始化成員變量;
      3. 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)問題了。

  • 安卓系統(tǒng)的實(shí)踐(部分)
    • 各種system service就是單例,雖然他們使用binder機(jī)制和真正的service跨進(jìn)程通信,但是在本地的proxy就是單例的(APP進(jìn)程中的單例);
    • 每個(gè)APP都有各種各樣的Context,它的實(shí)現(xiàn)類是ComtextImpl,它在static代碼塊中初始化各種system service,并保存在一個(gè)map中,后續(xù)獲取的時(shí)候?qū)⒅苯訌膍ap中獲取;android 23起,初始化system service、緩存、單例邏輯的代碼從ContextImpl轉(zhuǎn)移到了SystemServiceRegistry中;
    • LayoutInflater工作原理
      • 實(shí)現(xiàn)類是PhoneLayoutInflater
      • 內(nèi)置view,在xml定義時(shí)不用聲明完整包名,因?yàn)?code>PhoneLayoutInflater在onCreateView函數(shù)中會(huì)自動(dòng)為其添加包名前綴
      • 最終view的創(chuàng)建都是通過createView函數(shù)完成,在其中通過反射創(chuàng)建view實(shí)例
      • inflate函數(shù)會(huì)解析xml布局文件,深度優(yōu)先遍歷,逐層創(chuàng)建view(通過createViewFromTag函數(shù)),并最終形成一棵view的樹

Builder模式

  • AutoValue及其在Android平臺(tái)的版本AutoParcel,不僅支持immutable,還支持builder模式
  • WindowManager
    • 實(shí)現(xiàn)類為WindowManagerImpl
    • Activity, Fragment, Dialog等組建的view顯示,都是通過的Window::setContentView()方法來實(shí)現(xiàn)的
    • Window是抽象類,其實(shí)現(xiàn)類為PhoneWindow它的setContentView方法,怎么和WindowManager關(guān)聯(lián)起來的??
    • WindowManager添加、移除view的實(shí)現(xiàn)工作在WindowManagerGlobal類中
    • ViewRootImpl是framework層與native層通信的橋梁,繼承自Handler
    • WMS只負(fù)責(zé)管理手機(jī)屏幕上View的z-order,即View的圖層順序,WMS管理的是屬于某個(gè)window下的view

原型模式

  • 在已有對(duì)象的基礎(chǔ)上構(gòu)造新對(duì)象,通常是clone;clone的效率通常比new的效率高,但不絕對(duì);需要注意深淺拷貝的問題。
  • Intent的查找與匹配
    • 系統(tǒng)啟動(dòng)之后,PackageManagerService會(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(組件);
    • 顯式Intent:直接指定了響應(yīng)Activity;隱式Intent:只指定了Action;
    • 啟動(dòng)Activity時(shí),會(huì)向PackageManagerService查詢intent對(duì)應(yīng)的activity,在PackageManagerService::queryIntentActivities(...)方法中;

工廠方法

  • 用工廠去創(chuàng)建產(chǎn)品(對(duì)象),工廠和產(chǎn)品都可以提供抽象類,具體類,以達(dá)到實(shí)現(xiàn)解耦的目的
  • Activity的啟動(dòng)過程
    • ActivityThread::main()是app的執(zhí)行起點(diǎn) ==>
    • thread.attach(false)把ActivityThread綁定到ActivityManagerService,它調(diào)用了ActivityManagerService::attachApplication方法 ==>
    • ActivityManagerService::attachApplication方法中間接調(diào)用了ActivityThread.ApplicationThread::bindApplicationActivityManagerService::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)品的功能;

策略模式

  • 某一需求可以有多種實(shí)現(xiàn)算法,將每種算法獨(dú)立封裝,且它們之間可以相互替換(實(shí)現(xiàn)相同的接口)。策略模式讓算法獨(dú)立于使用它們的客戶端而獨(dú)立變化。
  • 安卓系統(tǒng)動(dòng)畫原理
    • view.startAnimation(),動(dòng)畫是怎么實(shí)現(xiàn)的?隨時(shí)間改變view屬性的值;
    • 整個(gè)過程是怎樣的?繪制時(shí)利用TimeInterpolator獲取繪制的時(shí)間百分比,再利用TypeEvaluator把百分比計(jì)算為屬性值,設(shè)置給view;
    • 怎么做到隨時(shí)間流逝持續(xù)進(jìn)行上述過程?
      • 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)
      • 動(dòng)畫操作在Animator::getTransformation(long currentTime, Transformation outTransformation)函數(shù)中實(shí)現(xiàn)
    • ValueAnimator原理
      • 動(dòng)畫屬性都保存在PropertyValuesHolder類中
      • ValueAnimator::start()調(diào)用后,將會(huì)把動(dòng)畫指令發(fā)送給內(nèi)部的ValueAnimator.AnimationHandler類,而handler則使用Choreographer來進(jìn)行定時(shí)的刷新
      • 刷新時(shí)調(diào)用了ValueAnimator::doAnimationFrame(long frameTime) ==>
      • ValueAnimator::animationFrame(long currentTime) ==>
      • ValueAnimator::animateValue(float fraction) ==>
      • 具體實(shí)現(xiàn)類(例如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

狀態(tài)模式

一個(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á)到修改其行為的目的。

安卓事件輸入系統(tǒng)

  • InputReader,從硬件的事件(CPU中斷)中,讀取輸入事件,并封裝為Event對(duì)象,然后分發(fā)給InputDispatcher
  • InputDispatcher負(fù)責(zé)接收來自InputReader的事件,并分發(fā)給合適的窗口,同時(shí)監(jiān)控ANR
  • InputReaderThreadInputDispatcherThread,InputManagerInputManagerService,WindowManagerService

觀察者模式

又稱訂閱模式,定義了對(duì)象間一對(duì)多的依賴關(guān)系,當(dāng)特定的對(duì)象(subject)變化時(shí),所有依賴它的對(duì)象(observer)都會(huì)得到通知并自動(dòng)更新。

  • ListView中的觀察者模式
    • 更改adapter數(shù)據(jù)集之后,會(huì)調(diào)用notifyDataSetChanged
    • 會(huì)調(diào)用其內(nèi)部的observer的onChanged方法
    • 內(nèi)部的observer是AdapterView的內(nèi)部類(非靜態(tài)),其onChanged方法會(huì)觸發(fā)AdapterView重新布局,達(dá)到刷新UI的目的
  • BroadcastReceiver中的觀察者模式
    • 代碼注冊(cè)receiver過程: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
      • sticky處理:如果是sticky intent,最后一次發(fā)送此廣播的時(shí)候,ActivityManagerService會(huì)把這個(gè)intent保存起來,后面注冊(cè)相同action的接收器時(shí),就會(huì)得到最后一次的廣播,并重放
      • receiver會(huì)保存在ActivityManagerService中,并且會(huì)把receiver和filter進(jìn)行關(guān)聯(lián)
  • 發(fā)送廣播
    • sendBroadcast會(huì)把廣播通過binder發(fā)送給ActivityManagerService,后者通難過廣播的action找到相應(yīng)的接收器,然后把廣播放進(jìn)自己的消息隊(duì)列中
    • ActivityManagerService的消息隊(duì)列循環(huán)中會(huì)處理這個(gè)廣播,通過binder分發(fā)給注冊(cè)的ReceiverDispatcher,后者把這個(gè)廣播放到注冊(cè)Activity所在線程的消息隊(duì)列中
    • ReceiverDispatcher的內(nèi)部類Args在注冊(cè)Activity所在線程的消息隊(duì)列循環(huán)中處理這個(gè)廣播,即調(diào)用receiver.onReceive
  • ActivityManagerService使用一個(gè)map保存了filter與receiver,注冊(cè)就是加入map,發(fā)送就是查詢map并完成分發(fā)