1. 程式人生 > >android精妙面試題集三

android精妙面試題集三

1、繪製Activity和Fragment生命週期流程圖,並以對比圖形式展示。

Activity生命週期圖:

https://img-blog.csdn.net/20130828141902812

Fragment生命週期圖:

http://images2015.cnblogs.com/blog/945877/201611/945877-20161123093212096-2032834078.png    

 

兩者對比圖:

http://img.my.csdn.net/uploads/201301/22/1358841101_4818.png

2、如何避免OOM異常

OOM(out of Memory)即記憶體溢位異常,也就是說記憶體佔有量超過了VM所分配的最大,導致應用程式異常終止。

通常OOM都發生在需要用到大量記憶體的情況下,因為Android的每一個應用都是一個Davlik虛擬機器,該虛擬機器的預設堆記憶體只有16M,遠遠無法跟我們的PC機比較,因此和容易導致OOM(Out Of Memory)異常的產生。導致這樣的異常主要有以下原因:①、載入大圖片或數量過多的圖片,因為圖片是超級耗記憶體的,②、操作資料庫的時候Cursor忘記關閉,③、資源未釋放,比如io流,file等,④、記憶體洩露。我們用用的OOM主要是載入圖片導致的。因為後面的三種原因都是可以通過約束程式設計師的編碼規範來進行預防,或者使用效能分析工具來檢查。所以大致分為兩類:

     ⑴,載入物件過大;

     ⑵,相應資源過多,沒有來不及釋放。

解決方案:

            ①在記憶體引用上做些處理,常用的有軟引用、強化引用、弱引用

            ②在記憶體中載入圖片時直接在記憶體中做處理,如:邊界壓縮.

            ③動態回收記憶體

            ④優化Dalvik虛擬機器的堆記憶體分配

            ⑤自定義堆記憶體大小

 

3、ANR是什麼?怎麼避免和解決ANR?

ANR:Application Not Responding,五秒

在Android中,活動管理器和視窗管理器這兩個系統服務負責監視應用程式的響應。

  當對輸入事件(如按鍵、觸控式螢幕事件)的響應超過5秒會出現ANR

  意向接受器(intentReceiver)超過10秒鐘仍未執行完畢會出現ANR。

  任何執行在主執行緒中的方法,都要儘可能的只做少量的工作。特別是活動生命週期中的重要方法如onCreate()和 onResume()等,潛在的比較耗時的操作,如訪問網路和資料庫,或者是開銷很大的計算如改變點陣圖的大小,需要在一個單獨的子執行緒中完成(或者是使用非同步請求,如資料庫操作)。

 

4、請描述您在工作中所採用的Android異常處理機制(體現優點缺點)

如果在debug模式下開發的時候,是可以通過檢視logcat日誌來檢視異常訊息,從而進行處理。

如果我們在釋出版本之後,使用者在使用的時候會crash掉,我們需要寫一個CrashHanler類結合log4j來記錄日誌,並且在發生crash時,將log檔案傳送到伺服器。
這樣程式就可以檢視使用者手機端的crash訊息了,方便我們處理在debug模式開發時未發現的異常。

https://yq.aliyun.com/ziliao/26275

 

5、Handler,Loader和AsyncTask有什麼區別,分別應用在哪些場景?

    Handler用於處理由looper分發的訊息

   loader結合listview處理非同步載入

     AsyncTask適合執行幾秒內的網路任務

 

6、子執行緒發訊息到主執行緒進行更新UI,有哪些方式?

方法一:用Activity物件的runOnUiThread方法更新 

在子執行緒中通過runOnUiThread()方法更新UI:

new Thread() {

        public void run() {

         //這兒是耗時操作,完成之後更新UI;

          runOnUiThread(new Runnable(){

                    @Override

                     public void run() {

                     //更新UI

                     imageView.setImageBitmap(bitmap);

}});}

}.start();

方法二:子執行緒呼叫Handler的sendMessage(message)傳送事件。

①主執行緒中定義Handler:

Handler mHandler = new Handler() {

    @Override

      public void handleMessage(Message msg) {

             super.handleMessage(msg);

             switch (msg.what) {

                 case 0:

                 //完成主介面更新,拿到資料

                   String data = (String)msg.obj;

                    updateWeather();

                    textView.setText(data);

                     break;

                  default:

                     break;

}}};

②子執行緒發訊息,通知Handler完成UI更新:

private void updateWeather() {

       new Thread(new Runnable(){

              @Override

              public void run() {

              //耗時操作,完成之後傳送訊息給Handler,完成UI更新;

                        mHandler.sendEmptyMessage(0);

                        //需要資料傳遞,用下面方法;

                        Message msg =new Message();

                        msg.obj = "資料";//可以是基本型別,可以是物件,可以是List、map等;

                        mHandler.sendMessage(msg);

}}).start();

}

方法三:View.post(Runnable )

public void onClick( View v ) {  
        new Thread( new Runnable() {  
                public void run() {  
                       // 耗時操作  
​    ​    ​    ​    ​    ​      loadNetWork();  
​                          myText.( new Runnable() {  
                                  myText.setText( 來自網路的資訊);  
                          });  
                 }  
        }).start();  
}

方法四:AsyncTask

//UI執行緒中執行  
new DownloadImageTask().execute( "www.91dota.com" );  
private class DownloadImageTask extends AsyncTask {  
    protected String doInBackground( String... url ) {  
         return loadDataFormNetwork( url[0] );//後臺耗時操作  
    }  

    protected void onPostExecute( String result ) {  
          myText.setText( result ); //得到來自網路的資訊重新整理頁面   

   }  
}

總結:

a.如果只是單純的想要更新UI而不涉及到多執行緒的話,使用View.post()就可以了;

b.需要另開執行緒處理資料以免阻塞UI執行緒,像是IO操作或者是迴圈,可以使用Activity.runOnUiThread();

c.如果需要傳遞狀態值等資訊,像是藍芽程式設計中的socket連線,就需要利用狀態值來提示連線狀態以及做相應的處理,就需要使用Handler + Thread的方式;

d.如果是後臺任務,像是下載任務等,就需要使用AsyncTask。

https://www.cnblogs.com/wenjiang/p/3180324.html

 

7、如何理解Activity、View、Window三者之間的關係?

Activity包含了一個PhoneWindow,而PhoneWindow就是繼承於Window的,Activity通過setContentView將View設定到了PhoneWindow上。View的事件監聽是由WindowManagerService來接受訊息,並回調Activity函式,比如onClickListener,noKeyDown等。

https://blog.csdn.net/zane402075316/article/details/69822438

 

8、Activity的幾種LaunchMode及使用場景

基本上我們可以直接指定一個launchMode屬性在AndroidManifest.xml 檔案中

<activity android:name=".views.MainActivity"

android:screenOrientation="portrait"

android:launchMode="singleTop"/>

standard 模式介紹

預設模式,每次啟用Activity時都會建立Activity例項,並放入任務棧中。

場景:鬧鐘的使用 standard。使用者可以啟動此activity的多個例項,這些例項可以是任何任務的一部分,也可以是活動堆疊中的任何地方的一部分。

singleTop 模式介紹

如果在任務的棧頂正好存在該Activity的例項,就重用該例項( 會呼叫例項的 onNewIntent() ),否則就會建立新的例項並放入棧頂,即使棧中已經存在該Activity的例項,只要不在棧頂,都會建立新的例項。

場景:瀏覽書籤頁面使用singleTop(搜尋功能)。雖然有可能是這一活動的多個例項,如果已經有一個在任務棧頂的活動將被重用和onnewintent()將被呼叫。這樣,你只需要返回一次返回到瀏覽器,如果書籤activity是開始多次。

singleTask 模式介紹

如果在棧中已經有該Activity的例項,就重用該例項(會呼叫例項的 onNewIntent() )。重用時,會讓該例項回到棧頂,因此在它上面的例項將會被移出棧。如果棧中不存在該例項,將會建立新的例項放入棧中。

場景:browseractivity使用singleTask。只有一個瀏覽器的活動的時間,它不成為一部分的任務,把它試圖開啟網頁。雖然它可能會返回到任何最近推出的它,當你回擊它實際上是固定在其自己的任務活動棧的底部。它將分享它的任務與活動,它推出像書籤.

singleInstance 模式介紹

在一個新棧中建立該Activity的例項,並讓多個應用共享該棧中的該Activity例項。一旦該模式的Activity例項已經存在於某個棧中,任何應用再啟用該Activity時都會重用該棧中的例項( 會呼叫例項的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰啟用該 Activity 都會進入同一個應用中。

場景:

alarmalert使用singleInstance。只有一個警報活動在一個時間,它總是自己的任務。它啟動的任何東西(如果有的話)成為它自己的新任務的一部分這種模式很少被使用。一些真正的用例是一個用於啟動或應用程式的活動,你是100%肯定只有一個活動。總之,我建議你不要使用這種模式,除非它是真的有必要。

https://blog.csdn.net/android_freshman/article/details/52948124

 

9、android中的幾種動畫

①Tween(補間)動畫,這種實現方式可以使檢視元件移動、放大、縮小以及產生透明度的變化;

②Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。

 

10、RxJava有哪些優點?

非同步、簡潔(邏輯、程式碼讀寫)。內部支援多執行緒操作,強大的map和flatmap保證了依賴上一次介面資料進行二次處理時不會發生巢狀,將各個模組分離。

https://www.jianshu.com/p/06d506e6b728

11、你瞭解哪些設計模式,應用場景是什麼?

http://mobile.51cto.com/android-535194.htm?mobile

12、 記憶體溢位和記憶體洩漏有什麼區別?何時會記憶體洩漏?如何優化記憶體?

 

13、簡述做過的專案,涉及到哪些技術點,遇到什麼技術難點,解決方案