騰訊Android社招面試源碼相關11題+原理詳解

對於這些專題的詳解,專門做了一個983頁的PDF版本,如下
騰訊Android社招面試源碼相關11題+原理詳解

(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
可以點擊關於我聯繫我獲取
(VX:mm14525201314)

Android源碼相關面試專題

1、Android屬性動畫實現原理

工作原理 :在一定時間間隔內,通過不斷對值進行改變,並不斷將該值賦給對象的屬性,從而實現該對象在該屬性上的動畫效果。
騰訊Android社招面試源碼相關11題+原理詳解

1)ValueAnimator:通過不斷控制值的變化(初始值->結束值),將值手動賦值給對象的屬性,再不斷調用View的invalidate()方法,去不斷onDraw重繪view,達到動畫的效果。

主要的三種方法:

a)ValueAnimator.ofInt(int values):估值器是整型估值器IntEaluator

b)ValueAnimator.ofFloat(float values):估值器是浮點型估值器FloatEaluator

c) ValueAnimator.ofObject(ObjectEvaluator, start, end):將初始值以對象的形式過渡到結束值,通過操作對象實現動畫效果,需要實現Interpolator接口,自定義估值器  

估值器TypeEvalutor,設置動畫如何從初始值過渡到結束值的邏輯。插值器(Interpolator)決定值的變化模式(勻速、加速等);估值器(TypeEvalutor)決定值的具體變化數值。

// 自定義估值器,需要實現TypeEvaluator接口
public class ObjectEvaluator implements TypeEvaluator{  

// 複寫evaluate(),在evaluate()裏寫入對象動畫過渡的邏輯
    @Override  
    public Object evaluate(float fraction, Object startValue, Object endValue) {  
        // 參數說明
        // fraction:表示動畫完成度(根據它來計算當前動畫的值)
        // startValue、endValue:動畫的初始值和結束值
  ... // 寫入對象動畫過渡的邏輯

        return value;  
        // 返回對象動畫過渡的邏輯計算後的值
    } 

2)ObjectAnimator:直接對對象的屬性值進行改變操作,從而實現動畫效果

ObjectAnimator繼承自ValueAnimator類,底層的動畫實現機制還是基本值的改變。它是不斷控制值的變化,再不斷自動賦給對象的屬性,從而實現動畫效果。這裏的自動賦值,是通過調用對象屬性的set/get方法進行自動賦值,屬性動畫初始值如果有就直接取,沒有則調用屬性的get()方法獲取,當值更新變化時,通過屬性的set()方法進行賦值。每次賦值都是調用view的postInvalidate()/invalidate()方法不斷刷新視圖(實際調用了onDraw()方法進行了重繪視圖)。

//Object 需要操作的對象; propertyName 需要操作的對象的屬性; values動畫初始值&結束值,
//如果是兩個值,則從a->b值過渡,如果是三值,則從a->b->c
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String propertyName, float ...values);

如果採用ObjectAnimator類實現動畫,操作的對象的屬性必須有get()和set()方法。

其他用法:

1)AnimatorSet組合動畫

AnimatorSet.play(Animator anim)   :播放當前動畫
AnimatorSet.after(long delay)   :將現有動畫延遲x毫秒後執行
AnimatorSet.with(Animator anim)   :將現有動畫和傳入的動畫同時執行
AnimatorSet.after(Animator anim)   :將現有動畫插入到傳入的動畫之後執行
AnimatorSet.before(Animator anim) :  將現有動畫插入到傳入的動畫之前執行

2) ViewPropertyAnimator直接對屬性操作,View.animate()返回的是一個ViewPropertyAnimator對象,之後的調用方法都是基於該對象的操作,調用每個方法返回值都是它自身的實例

View.animate().alpha(0f).x(500).y(500).setDuration(500).setInterpolator()

3)設置動畫監聽

Animation.addListener(new AnimatorListener() {
          @Override
public void onAnimationStart(Animation animation) {
              //動畫開始時執行
          }

           @Override
          public void onAnimationRepeat(Animation animation) {
              //動畫重複時執行
          }

         @Override
          public void onAnimationCancel()(Animation animation) {
              //動畫取消時執行
          }

          @Override
          public void onAnimationEnd(Animation animation) {
              //動畫結束時執行
          }
      });

2、補間動畫實現原理

主要有四種AlpahAnimation\ ScaleAnimation\ RotateAnimation\ TranslateAnimation四種,對透明度、縮放、旋轉、位移四種動畫。在調用View.startAnimation時,先調用View.setAnimation(Animation)方法給自己設置一個Animation對象,再調用invalidate來重繪自己。在View.draw(Canvas, ViewGroup, long)方法中進行了getAnimation(), 並調用了drawAnimation(ViewGroup, long, Animation, boolean)方法,此方法調用Animation.getTranformation()方法,再調用applyTranformation()方法,該方法中主要是對Transformation.getMatrix().setTranslate/setRotate/setAlpha/setScale來設置相應的值,這個方法系統會以60FPS的頻率進行調用。具體是在調Animation.start()方法中會調用animationHandler.start()方法,從而調用了scheduleAnimation()方法,這裏會調用mChoreographer.postCallback(Choregrapher.CALLBACK_ANIMATION, this, null)放入事件隊列中,等待doFrame()來消耗事件。

當一個 ChildView要重畫時,它會調用其成員函數 invalidate() 函數將通知其 ParentView 這個 ChildView 要重畫,這個過程一直向上遍歷到 ViewRoot,當 ViewRoot 收到這個通知後就會調用ViewRoot 中的 draw 函數從而完成繪製。View::onDraw() 有一個畫布參數 Canvas, 畫布顧名思義就是畫東西的地方,Android 會爲每一個 View 設置好畫布,View 就可以調用 Canvas 的方法,比如:drawText, drawBitmap, drawPath 等等去畫內容。每一個 ChildView 的畫布是由其 ParentView設置的,ParentView 根據 ChildView 在其內部的佈局來調整 Canvas,其中畫布的屬性之一就是定義和 ChildView 相關的座標系,默認是橫軸爲 X 軸,從左至右,值逐漸增大,豎軸爲 Y 軸,從上至下,值逐漸增大。
騰訊Android社招面試源碼相關11題+原理詳解
Android 補間動畫就是通過 ParentView 來不斷調整 ChildView的畫布座標系來實現的,在ParentViewdispatchDraw方法會被調用。

dispatchDraw() 
{ 
.... 
Animation a = ChildView.getAnimation() 
Transformation tm = a.getTransformation(); 
Use tm to set ChildView's Canvas; 
Invalidate(); 
.... 
}

這裏有兩個類:Animation 和 Transformation,這兩個類是實現動畫的主要的類,Animation 中主要定義了動畫的一些屬性比如開始時間、持續時間、是否重複播放等,這個類主要有兩個重要的函數:getTransformationapplyTransformation,在 getTransformation中 Animation 會根據動畫的屬性來產生一系列的差值點,然後將這些差值點傳給 applyTransformation,這個函數將根據這些點來生成不同的 Transformation,Transformation 中包含一個矩陣和 alpha 值,矩陣是用來做平移、旋轉和縮放動畫的,而 alpha 值是用來做 alpha 動畫的(簡單理解的話,alpha 動畫相當於不斷變換透明度或顏色來實現動畫),調用 dispatchDraw 時會調用 getTransformation來得到當前的 Transformation。某一個 View 的動畫的繪製並不是由他自己完成的而是由它的父 view 完成。

補間動畫TranslateAnimation,View位置移動了,可是點擊區域還在原來的位置,爲什麼?

View在做動畫是,根據動畫時間的插值,計算出一個Matrix,不停的invalidate,在onDraw中的Canvas上使用這個計算出來的Matrix去draw view的內容。

某個view的動畫繪製並不是由它自己完成,而是由它的父view完成,使它的父view畫布進行了移動,而點擊時還是點擊原來的畫布。使得它看起來變化了。

3、Android各個版本API的區別

主要記住一些大版本變化:

  • android3.0 代號Honeycomb, 引入Fragments, ActionBar,屬性動畫,硬件加速

  • android4.0 代號Ice Cream,API14:截圖功能,人臉識別,虛擬按鍵,3D優化驅動

  • android5.0 代號Lollipop API21:調整桌面圖標及部件透明度等

  • android6.0 代號M Marshmallow API23,軟件權限管理,安卓支付,指紋支持,App關聯,

  • android7.0 代號N Preview API24,多窗口支持(不影響Activity生命週期),增加了JIT編譯器,引入了新的應用簽名方案APK Signature Scheme v2(縮短應用安裝時間和更多未授權APK文件更改保護),嚴格了權限訪問
  • android8.0 代號O  API26,取消靜態廣播註冊,限制後臺進程調用手機資源,桌面圖標自適應

  • android9.0 代號P API27,加強電池管理,系統界面添加了Home虛擬鍵,提供人工智能API,支持免打擾模式

4、Requestlayout,onlayout,onDraw,DrawChild區別與聯繫

requestLayout()方法 :會導致調用measure()過程 和 layout()過程 。 說明:只是對View樹重新佈局layout過程包括measure()和layout()過程,如果view的l,t,r,b沒有必變,那就不會觸發onDraw;但是如果這次刷新是在動畫裏,mDirty非空,就會導致onDraw

onLayout()方法(如果該View是ViewGroup對象,需要實現該方法,對每個子視圖進行佈局)

onDraw()方法繪製視圖本身 (每個View都需要重載該方法,ViewGroup不需要實現該方法)

drawChild()去重新回調每個子視圖的draw()方法

5、invalidate和postInvalidate的區別及使用

View.invalidate(): 層層上傳到父級,直到傳遞到ViewRootImpl後觸發了scheduleTraversals(),然後整個View樹開始重新按照View繪製流程進行重繪任務。

invalidate:在ui線程刷新view
postInvalidate:在工作線程刷新view(底層還是handler)其實它的原理就是invalidate+handler
View.postInvalidate最終會調用ViewRootImpl.dispatchInvalidateDelayed()方法

public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
        Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
        mHandler.sendMessageDelayed(msg, delayMilliseconds);
    }

這裏的mHandlerViewRootHandler實例,在該Handler的handleMessage方法中調用了view.invalidate()方法。

case MSG_INVALIDATE:
                    ((View) msg.obj).invalidate();
break;

6、Activity-Window-View三者的差別

Activity:是安卓四大組件之一,負責界面展示、用戶交互與業務邏輯處理;
Window:就是負責界面展示以及交互的職能部門,就相當於Activity的下屬,Activity的生命週期方法負責業務的處理;
View:就是放在Window容器的元素,Window是View的載體,View是Window的具體展示。
三者的關係: Activity通過Window來實現視圖元素的展示,window可以理解爲一個容器,盛放着一個個的view,用來執行具體的展示工作。
騰訊Android社招面試源碼相關11題+原理詳解

7、談談對Volley的理解

8、如何優化自定義View

1)在要在onDraw或是onLayout()中去創建對象,因爲onDraw()方法可能會被頻繁調用,可以在view的構造函數中進行創建對象;

2)降低view的刷新頻率,儘可能減少不必要的調用invalidate()方法。或是調用帶四種參數不同類型的invalidate(),而不是調用無參的方法。無參變量需要刷新整個view,而帶參數的方法只需刷新指定部分的view。在onDraw()方法中減少冗餘代碼。

3)使用硬件加速,GPU硬件加速可以帶來性能增加。

4)狀態保存與恢復,如果因內存不足,Activity置於後臺被殺重啓時,View應儘可能保存自己屬性,可以重寫onSaveInstanceStateonRestoreInstanceState方法,狀態保存。

9、低版本SDK如何實現高版本api?

使用@TargetApi註解·
當代碼中有比AndroidManifest中設置的android:minSdkVersion版本更高的方法,此時編譯器會提示警告,解決方法是在方法上加上

@SuppressLint("NewApi")或者@TargetApi()。但它們僅是屏蔽了android lint錯誤,在方法中還要判斷版本做不同的操作。

@SuppressLint("NewApi")屏蔽一切新api中才能使用的方法報的android lint錯誤

@TargetApi()只屏蔽某一新api中才能使用的方法報的android lint錯誤,如@TargetApi(11)如果在方法中用了只有API14纔開始有的方法,還是會報錯。

10、描述一次網絡請求的流程

1)域名解析

瀏覽器會先搜索自身DNS緩存且對應的IP地址沒有過期;若未找到則搜索操作系統自身的DNS緩存;若還未找到則讀本地的hotsts文件;還未找到會在TCP/IP設置的本地DNS服務器上找,如果要查詢的域名在本地配置的區域資源中,則完成解析;否則根據本地DNS服務器會請求根DNS服務器;根DNS服務器是13臺根DNS,會一級一級往下找。

2)TCP三次握手

客戶端先發送SYN=1,ACK=0,序列號seq=x報文;(SYN在連接建立時用來同步序號,SYN=1,ACK=0代表這是一個連接請求報文,對方若同意建立連接,則應在響應報文中使SYN=1,ACK=1)

服務器返回SYN=1,ACK=1,seq=y, ack=x+1;

客戶端再一次確認,但不用SYN了,回覆服務端, ACK=1, seq=x+1, ack=y+1

3)建立TCP連接後發起HTTP請求

客戶端按照指定的格式開始向服務端發送HTTP請求,HTTP請求格式由四部分組成,分別是請求行、請求頭、空行、消息體,服務端接收到請求後,解析HTTP請求,處理完成邏輯,最後返回一個具有標準格式的HTTP響應給客戶端。

4)服務器響應HTTP請求

服務器接收處理完請求後返回一個HTTP響應消息給客戶端,HTTP響應信息格式包括:狀態行、響應頭、空行、消息體

5)瀏覽器解析HTML代碼,請求HTML代碼中的資源

瀏覽器拿到html文件後,就開始解析其中的html代碼,遇到js/css/image等靜態資源時,向服務器發起一個http請求,如果返回304狀態碼,瀏覽器會直接讀取本地的緩存文件。否則開啓線程向服務器請求下載。

6)瀏覽器對頁面進行渲染並呈現給用戶

7)TCP的四次揮手

當客戶端沒有東西要發送時就要釋放連接(提出中斷連接可以是Client也可以是Server),客戶端會發送一個FIN=1的沒有數據的報文,進入FIN_WAIT狀態,服務端收到後會給客戶端一個確認,此時客戶端不能發送數據,但可接收信息。

11、HttpUrlConnection 和 okhttp關係

兩者都可以用來實現網絡請求,android4.4之後的HttpUrlConnection的實現是基於okhttp

  • Bitmap對象的理解
  • looper架構
  • ActivityThread,AMS,WMS的工作原理
  • 自定義View如何考慮機型適配

onMeasure()getDefaultSize()的默認實現中,當view的測量模式是AT_MOST或EXACTLY時,View的大小都會被設置成子View MeasureSpecspecSize.子view的MeasureSpec值是根據子View的佈局參數和父容器的MeasureSpec值計算得來。當子view的佈局參數是wrap_content時,對應的測量模式是AT_MOST,大小是parentSize,

  • 自定義View的事件
  • AstncTask+HttpClient 與 AsyncHttpClient有什麼區別?
  • LaunchMode應用場景
  • AsyncTask 如何使用?
  • SpareArray原理
  • 請介紹下ContentProvider 是如何實現數據共享的?
  • AndroidService與Activity之間通信的幾種方式
  • IntentService原理及作用是什麼?

原理IntentService是繼承Service的一個抽象類,它在onCreate()方法中創建了一個HandlerThread,並啓動該線程。HandlerThread是帶有自己消息隊列和Looper的線程,根據HandlerThreadlooper創建一個Handler,這樣IntentServiceServiceHandlerhandleMessage()方法就運行在子線程中。handleMessage中調用了onHandleIntent()方法,它是一個抽象方法,繼承IntentService類需要實現該方法,把耗時操作放在onHandleIntent()方法中,等耗時操作運行完成後,會調用stopSelf()方法,服務會調用onDestory()方法消毀自己。如果onHandleIntent()中的耗時操作未運行完前就調用了stopSelf()方法,服務調用onDestory()方法,但耗時操作會繼續運行,直至運行完畢。如果同時多次啓動IntentService,任務會放在一個隊列中,onCreate()onDestory()方法都只會運行一次。

作用:用來處理後臺耗時操作,如讀取數據庫或是本地文件等。

  • 說說Activity、Intent、Service 是什麼關係
  • ApplicationContext和ActivityContext的區別
  • SP是進程同步的嗎?有什麼方法做到同步?
  • 談談多線程在Android中的使用
  • 進程和 Application 的生命週期
  • 封裝View的時候怎麼知道view的大小
  • RecycleView原理
  • AndroidManifest的作用與理解

(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
領取完整版PDF

騰訊Android社招面試源碼相關11題+原理詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章