妥妥的去面試之Android基礎(四)

樹獺非懶發表於2019-02-21

筆者由於在近期需要找工作,所以近期最主要的任務就是準備面試,不打無準備之仗。只有你準備充分了,那麼你想得到的機會才可能有機會入你懷中。

筆者會將準備面試的學習過程記錄下來,方便自己覆盤的同時也希望能給一道找工作的小夥伴們一些幫助。筆者準備的內容大綱如下

Android面試大綱.png

妥妥的去面試之Android基礎(一)

妥妥的去面試之Android基礎(二)

妥妥的去面試之Android基礎(三)

接下來開始本篇部落格的正菜:

1.Bitmap使用時需要注意什麼?

  • 要選擇合適的圖片規格,因為不同規格的圖片所佔用的記憶體不同

ALPHA_8 每個畫素佔用1byte記憶體
ARGB_4444 每個畫素佔用2byte記憶體
ARGB_8888 每個畫素佔用4byte記憶體(預設)
RGB_565 每個畫素佔用2byte記憶體

  • 圖片壓縮。通過BitmapFactory對圖片進行壓縮,這樣就會降低記憶體佔用從而在一定程度上避免OOM,提高Bitmap載入時的效能。
  • 複用記憶體。通過軟引用(記憶體不夠的時候才會回收掉)來複用記憶體塊,就不需要再重新給這個bitmap申請一塊新的記憶體,避免了一次記憶體的分配和回收帶來的效能消耗。
  • 使用recycle()方法及時回收記憶體,避免記憶體洩露。

在Android中,Bitmap的儲存分為兩部分,一部分是Bitmap的資料,一部分是Bitmap的引用。 在Android2.3時代,Bitmap的引用是放在堆中的,而Bitmap的資料部分是放在棧中的,需要使用者呼叫recycle方法手動進行記憶體回收,而在Android2.3之後,整個Bitmap,包括資料和引用,都放在了堆中,這樣,整個Bitmap的回收就全部交給GC了,這個recycle方法就再也不需要使用了。

2.服務有幾種啟動方式?服務和Activty或服務之間怎麼通訊?

啟動服務兩種方式

1.startService

onCreate() --> onStartCommand() --> onDestroy()

  • 如果服務已經開啟,再次開啟的話不會重複的執行onCreate(), 而是會呼叫onStartCommand()。
  • 一旦服務開啟後就和開啟者沒有任何關係了。
  • 開啟者不能呼叫服務裡面的方法。

2.bindService

onCreate() --> onBind() --> onUnbind() --> onDestroy()

bind的方式開啟服務後,如果開啟者被銷燬了,它也會跟著一起銷燬。繫結者可以呼叫服務裡的方法。

3.通訊方式

服務和Activity、服務和服務之間可以通過Binder物件、Broadcast(廣播)進行通訊。

3.Handler為什麼會出現記憶體洩漏,為什麼繼承Handle就不會出現記憶體洩漏?

在使用Handler的時候,往往是需要在子執行緒中做耗時任務的,但是當任務未執行完就把該Handler所在的Activity銷燬的話,它是無法被GC的。因為持有非靜態內部類的引用是無法被記憶體回收,所以會出現記憶體洩露。

解決方法主要在於兩點:

  • 將Handler宣告為靜態內部類。因為靜態內部類不會持有外部類的引用,所以不會導致外部類例項出現記憶體洩露。
  • 在Handler中新增對外部Activity的弱引用。由於Handler被宣告為靜態內部類,不再持有外部類物件的引用,導致無法在handleMessage()中操作Activity中的物件,所以需要在Handler中增加一個對Activity的弱引用。

通過繼承Handler就可以實現一個Handler靜態內部類,還可以在構造方法中新增對外部Activity的弱引用。

public class MainActivity extends Activity {
    ......
 
    private final MyHandler mHandler = new MyHandler(this);
 
    private static class MyHandler extends Handler {
        private final WeakReference<MainActivity> mActivity;
 
        public MyHandler(MainActivity activity) {
            this.mActivity = new WeakReference<MainActivity>(activity);
        }
 
        @Override
        public void handleMessage(Message msg) {
          
        }
    }
}

複製程式碼

4.在Activity中建立一個thread跟在service中建立一個thread之間的區別?

  • 在Activity中被建立:該Thread的就是為這個Activity服務的,完成這個特定的Activity交代的任務,主動通知該Activity一些訊息和事件,Activity銷燬後,該Thread也沒有存活的意義了
  • 在Service中被建立:這是保證最長生命週期的Thread的唯一方式,只要整個Service不退出,Thread就可以一直在後臺執行,一般在Service的onCreate()中建立,在onDestroy()中銷燬。所以,在Service中建立的Thread,適合長期執行一些獨立於APP的後臺任務,比較常見的就是:在Service中保持與伺服器端的長連線。

5.Bundle傳遞資料為什麼需要序列化?

序列化,表示將一個物件轉換成可儲存或可傳輸的狀態。

需要序列化的原因有三種情況:

  1. 永久性儲存物件,將物件的位元組序列儲存到本地檔案中;
  2. 物件在網路中傳遞
  3. 物件在IPC間傳遞

相關文章