Android常見面試題學習第二天(原創)

61. Android dvm的進程和Linux的進程, 應用程序的進程是否爲同一個概念

DVM指Dalvik的虛擬機。每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。而每一個DVM都是在Linux 中的一個進程,所以說可以認爲是同一個概念。

62. sim卡的EF 文件有何作用

sim卡的文件系統有自己規範,主要是爲了和手機通訊,sim本身可以有自己的操作系統,EF就是作存儲並和手機通訊用的

63. JDK和JRE的區別是什麼?

Java運行時環境(JRE)是將要執行Java程序的Java虛擬機。它同時也包含了執行applet需要的瀏覽器插件。Java開發工具包(JDK)是完整的Java軟件開發包,包含了JRE,編譯器和其他的工具(比如:JavaDoc,Java調試器),可以讓開發者開發、編譯、執行Java應用程序。

64. 什麼是死鎖(deadlock)?

兩個進程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是兩個進程都陷入了無限的等待中。

65. Java中的HashMap的工作原理是什麼?

Java中的HashMap是以鍵值對(key-value)的形式存儲元素的。HashMap需要一個hash函數,它使用hashCode()和equals()方法來向集合/從集合添加和檢索元素。當調用put()方法的時候,HashMap會計算key的hash值,然後把鍵值對存儲在集合中合適的索引上。如果key已經存在了,value會被更新成新值。HashMap的一些重要的特性是它的容量(capacity),負載因子(load factor)和擴容極限(threshold resizing)。

66. hashCode()和equals()方法的重要性體現在什麼地方?

Java中的HashMap使用hashCode()和equals()方法來確定鍵值對的索引,當根據鍵獲取值的時候也會用到這兩個方法。如果沒有正確的實現這兩個方法,兩個不同的鍵可能會有相同的hash值,因此,可能會被集合認爲是相等的。而且,這兩個方法也用來發現重複元素。所以這兩個方法的實現對HashMap的精確性和正確性是至關重要的。

67. 數組(Array)和列表(ArrayList)有什麼區別?什麼時候應該使用Array而不是ArrayList?

Array可以包含基本類型和對象類型,ArrayList只能包含對象類型。
Array大小是固定的,ArrayList的大小是動態變化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
對於基本類型數據,集合使用自動裝箱來減少編碼工作量。但是,當處理固定大小的基本數據類型的時候,這種方式相對比較慢。

68. ArrayList和LinkedList有什麼區別?

ArrayList和LinkedList都實現了List接口,他們有以下的不同點:
(1)ArrayList是基於索引的數據接口,它的底層是數組。它可以以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每一個元素都和它的前一個和後一個元素鏈接在一起,在這種情況下,查找某個元素的時間複雜度是O(n)。
(2)相對於ArrayList,LinkedList的插入,添加,刪除操作速度更快,因爲當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。
(3)LinkedList比ArrayList更佔內存,因爲LinkedList爲每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。

69. Comparable和Comparator接口是幹什麼的?列出它們的區別

Java提供了只包含一個compareTo()方法的Comparable接口。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小於,等於,大於已經存在的對象。
Java提供了包含compare()和equals()兩個方法的Comparator接口。compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小於,等於,大於第二個參數。equals()方法需要一個對象作爲參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator並且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。

70. HashSet和TreeSet有什麼區別?

HashSet是由一個hash表來實現的,因此,它的元素是無序的。add(),remove(),contains()方法的時間複雜度是O(1)。
另一方面,TreeSet是由一個樹形的結構來實現的,它裏面的元素是有序的。因此,add(),remove(),contains()方法的時間複雜度是O(logn)。

71. 如果對象的引用被置爲null,垃圾收集器是否會立即釋放對象佔用的內存?

不會,在下一個垃圾回收週期中,這個對象將是可被回收的。

72. Java支持多繼承麼?

不支持,Java不支持多繼承。每個類都只能繼承一個類,但是可以實現多個接口。

73. 接口和抽象類的區別是什麼?

Java提供和支持創建抽象類和接口。它們的實現有共同點,不同點在於:
接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。
類可以實現很多個接口,但是隻能繼承一個抽象類
類如果要實現一個接口,它必須要實現接口聲明的所有方法。但是,類可以不實現抽象類聲明的所有方法,當然,在這種情況下,類也必須得聲明成是抽象的。
抽象類可以在不提供接口方法實現的情況下實現接口。
Java接口中聲明的變量默認都是final的。抽象類可以包含非final的變量。
Java接口中的成員函數默認是public的。抽象類的成員函數可以是private,protected或者是public。
接口是絕對抽象的,不可以被實例化。抽象類也不可以被實例化,但是,如果它包含main方法的話是可以被調用的。

74. 什麼是值傳遞和引用傳遞?

(1)對象被值傳遞,意味着傳遞了對象的一個副本。因此,就算是改變了對象副本,也不會影響源對象的值。
(2)對象被引用傳遞,意味着傳遞的並不是實際的對象,而是對象的引用。因此,外部對引用對象所做的改變會反映到所有的對象上。

75. 進程和線程的區別是什麼

進程是執行着的應用程序,而線程是進程內部的一個執行序列。一個進程可以有多個線程。線程又叫做輕量級進程。

76. 創建線程有幾種不同的方式?你喜歡哪一種?爲什麼?

有三種方式可以用來創建線程:
繼承Thread類
實現Runnable接口
應用程序可以使用Executor框架來創建線程池
實現Runnable接口這種方式更受歡迎,因爲這不需要繼承Thread類。在應用設計中已經繼承了別的對象的情況下,這需要多繼承(而Java不支持多繼承),只能實現接口。同時,線程池也是非常高效的,很容易實現和使用。

77. 概括的解釋下線程的幾種可用狀態

線程在執行過程中,可以處於下面幾種狀態:
就緒(Runnable):線程準備運行,不一定立馬就能開始執行。
運行中(Running):進程正在執行線程的代碼。
等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。
睡眠中(Sleeping):線程被強制睡眠。
I/O阻塞(Blocked on I/O):等待I/O操作完成。
同步阻塞(Blocked on Synchronization):等待獲取鎖。
死亡(Dead):線程完成了執行。

78. 什麼是迭代器(Iterator)?

Iterator接口提供了很多對集合元素進行迭代的方法。每一個集合類都包含了可以返回迭代器實例的迭代方法。迭代器可以在迭代的過程中刪除底層集合的元素。

79. 靜態內部類、內部類、匿名內部類,爲什麼內部類會持有外部類的引用?持有的引用是this?還是其它?

靜態內部類:使用static修飾的內部類
內部類:就是在某個類的內部又定義了一個類,內部類所嵌入的類稱爲外部類匿名內部類:使用new生成的內部類因爲內部類的產生依賴於外部類,持有的引用是類名.this

80. equals與==的區別

==是判斷兩個變量或實例是不是指向同一個內存空間 equals是判斷兩個變量或實例所指向的內存空間的值是不是相

81. Java的四種引用的區別

強引用:如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM 也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯式地將引用賦值爲null,這樣一來的話,JVM在合適的時間就會回收該對象
軟引用:在使用軟引用時,如果內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用纔會被垃圾回收器回收。
弱引用:具有弱引用的對象擁有的生命週期更短暫。因爲當 JVM 進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先級較低的線程,所以並不一定能迅速發現弱引用對象
虛引用:顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那麼它相當於沒有引用,在任何時候都可能被垃圾回收器回收。

82. 垃圾回收機制

標記回收法:遍歷對象圖並且記錄可到達的對象,以便刪除不可到達的對象,一般使用單線程工作並且可能產生內存碎片

標記-壓縮回收法:前期與第一種方法相同,只是多了一步,將所有的存活對象壓縮到內存的一端,這樣內存碎片就可以合成一大塊可再利用的內存區域,提高了內存利用率

複製回收法:把現有內存空間分成兩部分,gc運行時,它把可到達對象複製到另一半空間,再清空正在使用的空間的全部對象。這種方法適用於短生存期的對象,持續複製長生存期的對象則導致效率降低。
分代回收發:把內存空間分爲兩個或者多個域,如年輕代和老年代,年輕代的特點是對象會很快被回收,因此在年輕代使用效率比較高的算法。當一個對象經過幾次回收後依然存活,對象就會被放入稱爲老年的內存空間,老年代則採取標記-壓縮算法

83. 數組與鏈表區別

數組
數組存儲區間是連續的,佔用內存嚴重,故空間複雜的很大。但數組的二分查找時間複雜度小,爲O(1);數組的特點是:尋址容易,插入和刪除困難;

鏈表
鏈表存儲區間離散,佔用內存比較寬鬆,故空間複雜度很小,但時間複雜度很大,達O(N)。鏈表的特點是:尋址困難,插入和刪除容易。

84. 說說hashMap是怎樣實現的

哈希表:由數組+鏈表組成的
當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在數組中的位置(即下標),如果數組該位置上已經存放有其他元素了,那麼在這個位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上。

82. HashMap和 HashTable 的區別

HashTable比較老,是基於Dictionary 類實現的,HashTable 則是基於 Map接口實現的
HashTable 是線程安全的, HashMap 則是線程不安全的
HashMap可以讓你將空值作爲一個表的條目的key或value

83. wait()和sleep()的區別

sleep來自Thread類,和wait來自Object類
調用sleep()方法的過程中,線程不會釋放對象鎖。而 調用 wait 方法線程會釋放對象鎖
sleep睡眠後不出讓系統資源,wait讓出系統資源其他線程可以佔用CPU
sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒

84. 若Activity已經銷燬,此時AsynTask執行完並且返回結果,會報異常嗎?

當一個App旋轉時,整個Activity會被銷燬和重建。當Activity重啓時,AsyncTask中對該Activity的引用是無效的,因此onPostExecute()就不會起作用,若AsynTask正在執行,折會報 view not attached to window manager 異常
同樣也是生命週期的問題,在 Activity 的onDestory()方法中調用Asyntask.cancal方法,讓二者的生命週期同步

85. TCP三次握手

TCP/IP協議高,因爲其擁有三次握手雙向機制,這一機制保證校驗了數據,保證了他的可靠性。
UDP就沒有了,udp信息發出後,不驗證是否到達對方,所以不可靠。
但是就速度來說,還是UDP協議更高,畢竟其無需重複返回驗證,只是一次性的

86. http協議瞭解多少,說說裏面的協議頭部有哪些字段?

http(超文本傳輸協議)是一個基於請求與響應模式的、無狀態的、應用層的協議;http請求由三部分組成,分別是:請求行、消息報頭、請求正文。
HTTP消息報頭包括普通報頭、請求報頭、響應報頭、實體報頭

87. https瞭解多少

HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。

88. 談談 HTTP 中Get 和 Post 方法的區別

GET - 從指定的服務器中獲取數據,明文發送內容
POST - 提交數據給指定的服務器處理

  1. POST請求不能被緩存下來
  2. POST請求不會保存在瀏覽器瀏覽記錄中
  3. 以POST請求的URL無法保存爲瀏覽器書籤
  4. POST請求沒有長度限制

89. Fragment 如何實現類似 Activity 棧的壓棧和出棧效果的?

Fragment 的事物管理器內部維持了一個雙向鏈表結構,該結構可以記錄我們每次 add 的
Fragment 和 replace 的 Fragment,然後當我們點擊 back 按鈕的時候會自動幫我們實現退棧操作。

90. Fragment 在你們項目中的使用

Fragment 是 android3.0 以後引入的的概念,做局部內容更新更方便,原來爲了到達這一點要把多個佈局放到一個 activity 裏面,現在可以用多 Fragment 來代替,只有在需要的時候才加載Fragment,提高性能。
Fragment 的好處:

  1. Fragment 可以使你能夠將 activity 分離成多個可重用的組件,每個都有它自己的生命週期和UI。
  2. Fragment 可以輕鬆得創建動態靈活的 UI 設計,可以適應於不同的屏幕尺寸。從手機到平板電腦。
  3. Fragment 是一個獨立的模塊,緊緊地與 activity 綁定在一起。可以運行中動態地移除、加入、交換等。
  4. Fragment 提供一個新的方式讓你在不同的安卓設備上統一你的 UI。
  5. Fragment 解決 Activity 間的切換不流暢,輕量切換。
  6. Fragment 替代 TabActivity 做導航,性能更好。
  7. Fragment 在 4.2.版本中新增嵌套 fragment 使用方法,能夠生成更好的界面效果

91. 如何切換 fragement,不重新實例化

正確的切換方式是 add(),切換時 hide(),add()另一個 Fragment;再次切換時,只需 hide()當前,show()另一個

92. 內存不足時,怎麼保持Activity的一些狀態,在哪個方法裏面做具體操作?

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,它們不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。當應用遇到意外情況(如:內存不足、用戶直接按Home鍵)由系統銷燬一個Activity,onSaveInstanceState() 會被調用。但是當用戶主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。除非該activity是被用戶主動銷燬的,通常onSaveInstanceState()只適合用於保存一些臨時性的狀態,而onPause()適合用於數據的持久化保存。 onRestoreInstanceState()在onStart() 和 onPostCreate(Bundle)之間調用。

93. Android中的Context, Activity,Appliction有什麼區別?

相同:Activity和Application都是Context的子類。
Context從字面上理解就是上下文的意思,在實際應用中它也確實是起到了管理上下文環境中各個參數和變量的總用,方便我們可以簡單的訪問到各種資源。
不同:維護的生命週期不同。 Context維護的是當前的Activity的生命週期,Application維護的是整個項目的生命週期。
使用context的時候,小心內存泄露,防止內存泄露,注意一下幾個方面:

  1. 不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity本身生命週期是一樣的。
  2. 對於生命週期長的對象,可以使用application,context。
  3. 避免非靜態的內部類,儘量使用靜態類,避免生命週期問題,注意內部類對外部對象引用導致的生命週期變化。

94. Context是什麼?

它描述的是一個應用程序環境的信息,即上下文。
該類是一個抽象(abstract class)類,Android提供了該抽象類的具體實現類(ContextIml)。
通過它我們可以獲取應用程序的資源和類,也包括一些應用級別操作,例如:啓動一個Activity,發送廣播,接受Intent,信息,等。

95. Service 是否在 main thread 中執行, service 裏面是否能執行耗時的操

默認情況,如果沒有顯示的指 servic 所運行的進程, Service 和 activity 是運行在當前 app 所在進程的 main thread(UI 主線程)裏面。
service 裏面不能執行耗時的操作(網絡請求,拷貝數據庫,大文件 )
不管是application activity 還是service, 如果在主線程中寫了耗時操作,很容易引起ANR, 應用程序無響應. 耗時操作應該用子線程處理.
特殊情況 ,可以在清單文件配置 service 執行所在的進程 ,讓 service 在另外的進程中執行

96. 說說 Activity、Intent、Service 是什麼關係

他們都是 Android 開發中使用頻率最高的類。其中 Activity 和 Service 都是 Android 四大組件
之一。他倆都是 Context 類的子類 ContextWrapper 的子類,因此他倆可以算是兄弟關係吧。不過
兄弟倆各有各自的本領,Activity 負責用戶界面的顯示和交互,Service 負責後臺任務的處理。Activity和 Service 之間可以通過 Intent 傳遞數據,因此可以把 Intent 看作是通信使者。

97. 爲什麼要用 ContentProvider?它和 sql 的實現上有什麼差別?

ContentProvider 屏蔽了數據存儲的細節,內部實現對用戶完全透明,用戶只需要關心操作數據的uri 就可以了,ContentProvider 可以實現不同 app 之間共享。
Sql 也有增刪改查的方法,但是 sql 只能查詢本應用下的數據庫。而 ContentProvider 還可以去增刪改查本地文件. xml 文件的讀取等。

98. 說說 ContentProvider、ContentResolver、ContentObserver 之間的關係

a. ContentProvider 內容提供者,用於對外提供數據
b. ContentResolver.notifyChange(uri)發出消息
c. ContentResolver 內容解析者,用於獲取內容提供者提供的數據
d. ContentObserver 內容監聽器,可以監聽數據的改變狀態
e. ContentResolver.registerContentObserver()監聽消息。

99. SurfaceView和View的區別是什麼?

SurfaceView中採用了雙緩存技術,在單獨的線程中更新界面

100. View的繪製過程

一個View要顯示在界面上,需要經歷一個View樹的遍歷過程,這個過程又可以分爲三個過程,也就是自定義View中的三要素:大小,位置,畫什麼,即onMesure(),onLayout(),onDraw()。
1.onMesure()確定一個View的大小;
2.onLayout()確定View在父節點上的位置;
3.onDraw()繪製View 的內容;

101. 講一下android中進程的優先級?

前臺進程
可見進程
服務進程
後臺進程
空進程

102.根據自己的理解描述下Android數字簽名

所有的應用程序都必須有數字證書,Android系統不會安裝一個沒有數字證書的應用程序Android程序包使用的數字證書可以是自簽名的,不需要一個權威的數字證書機構簽名認證。
如果要正式發佈一個Android程序,必須使用一個合適的私鑰生成的數字證書來給程序簽名,而不能使用adt插件或者ant工具生成的調試證書來發布。數字證書都是有有效期的,Android只是在應用程序安裝的時候纔會檢查證書的有效期。如果程序已經安裝在系統中,即使證書過期也不會影響程序的正常功能。

103. View、surfaceView、GLSurfaceView

View
顯示視圖,內置畫布,提供圖形繪製函數、觸屏事件、按鍵事件函數等,必須在UI主線程內更新畫面,速度較慢
SurfaceView
基於view視圖進行拓展的視圖類,更適合2D遊戲的開發,是view的子類,類似使用雙緩機制,在新的線程中更新畫面所以刷新界面速度比view快
GLSurfaceView
基於SurfaceView視圖再次進行拓展的視圖類,專用於3D遊戲開發的視圖,是surfaceView的子類,openGL專用

104. AsyncTask的執行分爲四個步驟

繼承AsyncTask。
實現AsyncTask中定義的下面一個或幾個方法onPreExecute()、doInBackground(Params…)、onProgressUpdate(Progress…)、onPostExecute(Result)。
調用execute方法必須在UI thread中調用。
該task只能被執行一次,否則多次調用時將會出現異常,取消任務可調用cancel。內存溢出和內存泄漏有什麼區別?何時會產生內存泄漏?
內存溢出:當程序運行時所需的內存大於程序允許的最高內存,這時會出現內存溢出;內存泄漏:在一些比較消耗資源的操作中,如果操作中內存一直未被釋放,就會出現內存泄漏。比如未關閉io,cursor。

105. Activity的狀態有幾種?

運行
暫停
停止

106. Fragment 的 replace 和 add 方法的區別

Fragment 本身並沒有 replace 和 add 方法,FragmentManager纔有replace和add方法。我們經常使用的一個架構就是通過RadioGroup切換Fragment,每個 Fragment 就是一個功能模塊。
Fragment 的容器一個 FrameLayout,add 的時候是把所有的 Fragment 一層一層的疊加到了。FrameLayout 上了,而 replace 的話首先將該容器中的其他 Fragment 去除掉然後將當前Fragment添加到容器中。
一個 Fragment 容器中只能添加一個 Fragment 種類,如果多次添加則會報異常,導致程序終止,而 replace 則無所謂,隨便切換。因爲通過 add 的方法添加的 Fragment,每個 Fragment 只能添加一次,因此如果要想達到切換效果需要通過 Fragment 的的 hide 和 show 方法結合者使用。將要顯示的 show 出來,將其他 hide起來。這個過程 Fragment 的生命週期沒有變化。
通過 replace 切換 Fragment,每次都會執行上一個 Fragment 的 onDestroyView,新 Fragment的 onCreateView、onStart、onResume 方法。基於以上不同的特點我們在使用的使用一定要結合着生命週期操作我們的視圖和數據。

107. 什麼是 IntentService?有何優點?

IntentService 是 Service 的子類,比普通的 Service 增加了額外的功能。先看 Service 本身存在兩個問題:
爲 Service 的 onStartCommand 提供默認實現,將請求 Intent 添加到隊列中;
IntentService使用隊列的方式將請求的Intent加入隊列,然後開啓一個worker thread(線程)來處理隊列中的Intent,對於異步的startService請求,IntentService會處理完成一個之後再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程序的主線程,這裏就給我們提供了一個思路,如果有耗時的操作與其在Service裏面開啓新線程還不如使用IntentService來處理耗時操作。

108. 什麼是 AIDL?如何使用?

aidl 是 Android interface definition Language 的英文縮寫,意思 Android 接口定義語言。
使用 aidl 可以幫助我們發佈以及調用遠程服務,實現跨進程通信。將服務的 aidl 放到對應的 src 目錄,工程的 gen 目錄會生成相應的接口類,我們通過 bindService(Intent,ServiceConnect,int)方法綁定遠程服務,在 bindService中 有 一 個 ServiceConnec 接 口 , 我 們 需 要 覆 寫 該 類 的onServiceConnected(ComponentName,IBinder)方法,這個方法的第二個參數 IBinder 對象其實就是已經在 aidl 中定義的接口,因此我們可以將 IBinder 對象強制轉換爲 aidl 中的接口類。我們通過 IBinder 獲取到的對象(也就是 aidl 文件生成的接口)其實是系統產生的代理對象,該代理對象既可以跟我們的進程通信, 又可以跟遠程進程通信, 作爲一箇中間的角色實現了進程間通信。
69.AIDL 的全稱是什麼?如何工作?能處理哪些類型的數據?
AIDL 全稱 Android Interface Definition Language(AndRoid 接口描述語言) 是一種接口描述語言; 編譯器可以通過 aidl 文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程跨界對象訪問的目的。需要完成兩件事情:
引入 AIDL 的相關類.;
調用 aidl 產生的 class
理論上, 參數可以傳遞基本數據類型和 String, 還有就是 Bundle 的派生類, 不過在 Eclipse 中,目前的 ADT 不支持 Bundle 做爲參數。

109. Android中任務棧的分配

Task實際上是一個Activity棧,通常用戶感受的一個Application就是一個Task。從這個定義來看,Task跟Service或者其他Components是沒有任何聯繫的,它只是針對Activity而言的。Activity有不同的啓動模式, 可以影響到task的分配

110. 子線程中能不能 new handler?爲什麼?

不能,如果在子線程中直接 new Handler()會拋出異常 java.lang.RuntimeException: Can’tcreate handler inside thread that has not called
那麼這個Looper.prepare()方法是什麼時候在哪裏調用的呢?
當我們在主線程中創建Handler對象的時候沒有問題,是因爲主線程會自動調用Looper.prepare()方法去給當前主線程創建並設置一個Looper對象,隨意在Handler構造函數中從當前線程的對象身上拿到這個Looper。但是子線程中並不會自動調用這個方法,所以要想在子線程中創建Handler對象就必須在創建之前手動調用Looper.prepare()方 法,否則就會報錯。

111. 談談你對 Bitmap 的理解, 什麼時候應該手動調用 bitmap.recycle()

Bitmap 是 android 中經常使用的一個類,它代表了一個圖片資源。 Bitmap 消耗內存很嚴重,如果不注意優化代碼,經常會出現 OOM 問題,優化方式通常有這麼幾種:
使用緩存;
壓縮圖片;
及時回收;
至於什麼時候需要手動調用 recycle,這就看具體場景了,原則是當我們不再使用 Bitmap 時,需要回收之。另外,我們需要注意,2.3 之前 Bitmap 對象與像素數據是分開存放的,Bitmap 對象存在Java Heap 中而像素數據存放在 Native Memory 中, 這時很有必要調用 recycle 回收內存。 但是 2.3之後,Bitmap 對象和像素數據都是存在 Heap 中,GC 可以回收其內存。

112. Activity間通過Intent傳遞數據大小有沒有限制?

Intent在傳遞數據時是有大小限制的,這裏官方並未詳細說明,不過通過實驗的方法可以測出數據應該被限制在1MB之內(1024KB),筆者採用的是傳遞Bitmap的方法,發現當圖片大小超過1024(準確地說是1020左右)的時候,程序就會出現閃退、停止運行等異常(不同的手機反應不同),因此可以判斷Intent的傳輸容量在1MB之內。

113. andorid 應用第二次登錄實現自動登錄

有兩種方式:
1、一個是用shareperence 或者數據庫保存上次請求成功的賬號和密碼
2、採用token或者session之類的標記,第一次請求下來保存一個token 下次直接提交這個token給服務器,服務器檢查是否有這個,這種可以保證服務器隨時可以踢掉此用戶登錄

114. 即時通訊是是怎麼做的?

使用asmark 開源框架實現的即時通訊功能.該框架基於開源的 XMPP 即時通信協議,採用 C/S 體系結構,通過 GPRS 無線網絡用 TCP 協議連接到服務器,以架設開源的Openfn’e 服務器作爲即時通訊平臺。
客戶端基於 Android 平臺進行開發。負責初始化通信過程,進行即時通信時,由客戶端負責向服務器發起創建連接請求。系統通過 GPRS 無線網絡與 Internet 網絡建立連接,通過服務器實現與Android 客戶端的即時通信腳。
服務器端則採用 Openfire 作爲服務器。 允許多個客戶端同時登錄並且併發的連接到一個服務器上。服務器對每個客戶端的連接進行認證,對認證通過的客戶端創建會話,客戶端與服務器端之間的通信就在該會話的上下文中進行。

115. 怎樣對 android 進行優化?

對 listview 的優化。
對圖片的優化。
對內存的優化。
具體一些措施
儘量不要使用過多的靜態類 static
數據庫使用完成後要記得關閉 cursor
廣播使用完之後要註銷

116. GC是什麼? 爲什麼要有GC?

GC是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java 提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。

117. switch語句能否作用在byte上,能否作用在long上,能否作用在String上?

switch能作用在byte、char、short和int上,JDK1.7後可以作用在String上。

118. 同步和異步有何異同,在什麼情況下分別使用他們?

同步指同一時間只能一個線程執行該方法,其他線程需要等待。異步指多個線程可以同時執行某個方法,並共享同一資源。
同步可以讓訪問的資源具有安全性,因爲同一時間只能一個線程對其進行訪問。但是效率不高。
異步對訪問的資源會造成不穩定性,比如多個線程同時訪問一個資源,一個在修改、一個在刪除、一個在讀取,這樣可能會造成資源的混亂。但是由於同時運行, 執行效率得到提高。

119. 啓動一個線程是用run()還是start()?

start()方法啓動線程,run方法是線程執行的主方法。

120. 作用域public,private,protected,以及不寫時的區別

public公共修飾符,表示任意類都可以訪問。
protected爲受保護的修飾符,表示同類、同包以及不同包但是父子關係的是可以訪問。
不寫表示默認修飾符,或者稱爲package修飾符,該修飾符表示只有同類或同包下的類可以訪問,出了這個包就不能訪問了。
private爲私有修飾符,表示只有同類中可以訪問,出了這個類就不能訪問了。

121. 描述一下JVM加載class文件的原理機制?

JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。

122. 什麼是java序列化,如何實現java序列化?

序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。可以對流化後的對象進行讀寫操作,也可將流化後的對象傳輸於網絡之間。序 列化是爲了解決在對對象流進行讀寫操作時所引發的問題。
序列化的實現:將需要被序列化的類實現Serializable接口,該接口沒有需要實現的方法,implements Serializable只是爲了標註該對象是可被序列化 的,然後使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(對象流)對象,接着,使用ObjectOutputStream對象的 writeObject(Object obj)方法就可以將參數爲obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。

123. listView展示數據幾種形式

從sqlite拉取數據源顯示
從xml使用pull解析拉取數據源顯示
從網絡上拉取數據源顯示

124. 兩activity之間怎麼傳遞數據?

基本數據類型可以通過. Intent 傳遞數據
在A activity中
Intent intent = new Intent();
intent.putExtra(name, value)
Bundle bundle = new Bundle();
bundle.putBoolean(key,value);
intent.putExtras(bundle);
extras.putDouble(key, value)
// 通過intent putExtra 方法 基本數據類型 都傳遞
Intent i = getIntent();
i.getExtras();
intent.getStringExtra("key","value");
intent.getBooleanExtra("key","value")
Bundle bundle = new Bundle();
bumdle.putShort(key, value);
intent.putExtras(bumdle);
intent.putExtras(bundle)

125. 請解釋下Android程序運行時權限與文件系統權限的區別

Android程序執行需要讀取到安全敏感項必需在androidmanifest.xml中聲明相關權限請求, 打電話,訪問網絡,獲取座標,讀寫sd卡,讀寫聯繫人等..安裝的時候會提示用戶…
文件系統的權限是linux權限. 比如說sharedpreference裏面的Context.Mode.private Context.Mode.world_read_able Context.Mode_world_writeable

126. Android程序與Java程序的區別?

Android程序用android sdk開發,java程序用javasdk開發.
Android SDK引用了大部分的Java SDK,少數部分被Android SDK拋棄,比如說界面部分,java.awt swing package除了java.awt.font被引用外,其他都被拋棄,在Android平臺開發中不能使用。 android sdk 添加工具jar httpclient , pull opengl
將Java 遊戲或者j2me程序移植到Android平臺的過程中,Android SDK 與Java SDK的區別是很需要注意的地方。

127. 談談Android的優點和不足之處

1、開放性,開源ophone 阿里雲( 完全兼容android)
2、掙脫運營商束縛
3、豐富的硬件選擇 mtk android
4、不受任何限制的開發商
5、無縫結合的Google應用

缺點也有5處:
1、安全問題、隱私問題
2、賣手機的不是最大運營商
3、運營商對Android手機仍然有影響
4、山寨化嚴重
5、過分依賴開發商,缺乏標準配置

128. Android UI中的View如何刷新

在主線程中 拿到view調用Invalide()方法,查看畫畫板裏面更新imageview的方法
在子線程裏面可以通過postInvalide()方法;

129. 顯式intent和隱式intent的區別是什麼

顯式Intent:對於明確指出了目標組件名稱的Intent,我們稱之爲顯式Intent。
隱式Intent:對於沒有明確指出目標組件名稱的Intent,則稱之爲隱式Intent。
顯式Intent直接用組件的名稱定義目標組件,這種方式很直接。但是由於開發人員往往並不清楚別的應用程序的組件名稱,因此,顯式Intent更多用於應用程序內部傳遞消息。比如在某應用程序內,一個Activity啓動一個Service。
隱式Intent恰恰相反,它不會用組件名稱定義需要激活的目標組件,它更廣泛地用於在不同應用程序之間傳遞消息。
另外,在顯式Intent消息中,決定目標組件的唯一要素就是組件名稱,一旦名稱確定,就不需要其他內容即可找到相應組件。 但在隱式Intent中需要藉助過濾器IntentFilter 來尋找與之相匹配的組件

130. 什麼是ANR 如何避免它?

ANR:Application Not Responding。
產生原因:在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應,當用戶的操作在5s內應用程序沒能做出反應,BroadcastReceiver在10秒內沒有執行完畢,就會出現應用程序無響應對話框,這就是ANR。
解決方式:Activity應該在它的關鍵生命週期方法裏儘可能少的去做創建操作、潛在的耗時操作(網絡或數據庫操作等),或者高耗時的計算操作(改變位圖尺寸等),而應該在子線程裏(或者異步方式)來完成。主線程應該爲子線程提供一個Handler,以便子線程完成時能夠提交給主線程。

131. 系統上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?請說明原由

1、默認瀏覽器:
在Android程序中我們可以通過發送隱式Intent來啓動系統默認的瀏覽器。

Intent intent =new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url =Uri.parse("http://www.163.com");
intent.setData(content_url);
startActivity(intent);

2、指定瀏覽器:
如果手機本身安裝了多個瀏覽器而又沒有設置默認瀏覽器的話,系統將讓用戶選擇使用哪個瀏覽器來打開連接。
另外,也可以發送顯示Intent來啓動瀏覽器。如下面就是啓動Android原生瀏覽器的例子:

Intent intent =new Intent(); 
intent.setAction("android.intent.action.VIEW"); 
Uri content_url =Uri.parse("http://www.163.com"); 
intent.setData(content_url); 
intent.setClassName("com.android.browser","com.android.browser.BrowserActivity"); 
startActivity(intent);

注:要啓動其他瀏覽器只需修改intent.setClassName()裏面的參數就OK了。
常見的瀏覽器:

uc瀏覽器":"com.uc.browser", "com.uc.browser.ActivityUpdate“
opera瀏覽器:"com.opera.mini.android", "com.opera.mini.android.Browser"
qq瀏覽器:"com.tencent.mtt", “com.tencent.mtt.MainActivity"

131. 瞭解Android系統架構

應用層: Java應用開發工程師開發的所有應用程序比如地圖,瀏覽器,QQ等屬於該層,手機中的短信,撥號,瀏覽器等這些應用程序都是可以被開發人員開發的其他應用程序所替換,這點不同於其他手機操作系統固化在系統內部的系統軟件,更加靈活和個性化
應用框架層:Java framework層源碼OS定製開發爲應用層開發人員提供API
系統運行庫層: C語言包括C語言標準庫,多媒體庫,OpenGL ES, SQLite, Webkit,Dalvik虛擬機等,該層是對應用框架層提供支持的層, Java訪問硬件需通過NDK實現
Linux內核層:Android是基於Linux2.6內核,其核心繫統服務如安全性、內存管理、進程管理、網路協議以及驅動模型都依賴於Linux內核

132. DVM與JVM區別

區別一:dvm執行的是.dex格式文件jvm執行的是.class文件android程序編譯完之後生產.class文件,然後,dex工具會把.class文件處理成.dex文件,然後把資源文件和.dex文件等打包成.apk文件。apk就是android package的意思。jvm執行的是.class文件。
區別二:dvm是基於寄存器的虛擬機而jvm執行是基於虛擬棧的虛擬機。寄存器存取速度比棧快的多,dvm可以根據硬件實現最大的優化,比較適合移動設備。
區別三:.class文件存在很多的冗餘信息,dex工具會去除冗餘信息,並把所有的.class文件整合到.dex文件中。減少了I/O操作,提高了類的查找速度

133. C/S和B/S兩種架構的概念、區別和聯繫

一、C/S 架構
1、 概念
C/S 架構是一種典型的兩層架構,其全程是Client/Server,即客戶端服務器端架構,其客戶端包含一個或多個在用戶的電腦上運行的程序,而服務器端有兩種,一種是數據庫服務器端,客戶端通過數據庫連接訪問服務器端的數據;另一種是Socket服務器端,服務器端的程序通過Socket與客戶端的程序通信。
C/S 架構也可以看做是胖客戶端架構。因爲客戶端需要實現絕大多數的業務邏輯和界面展示。這種架構中,作爲客戶端的部分需要承受很大的壓力,因爲顯示邏輯和事務處理都包含在其中,通過與數據庫的交互(通常是SQL或存儲過程的實現)來達到持久化數據,以此滿足實際項目的需要。
2 、優點和缺點
優點:
2.1 C/S架構的界面和操作可以很豐富。
2.2 安全性能可以很容易保證,實現多層認證也不難。
2.3 由於只有一層交互,因此響應速度較快。
缺點:
2.4 適用面窄,通常用於局域網中。
2.5 用戶羣固定。由於程序需要安裝纔可使用,因此不適合面向一些不可知的用戶。
2.6 維護成本高,發生一次升級,則所有客戶端的程序都需要改變。
二、B/S架構
1、概念
B/S架構的全稱爲Browser/Server,即瀏覽器/服務器結構。Browser指的是Web瀏覽器,極少數事務邏輯在前端實現,但主要事務邏輯在服務器端實現,Browser客戶端,WebApp服務器端和DB端構成所謂的三層架構。B/S架構的系統無須特別安裝,只有Web瀏覽器即可。
B/S架構中,顯示邏輯交給了Web瀏覽器,事務處理邏輯在放在了WebApp上,這樣就避免了龐大的胖客戶端,減少了客戶端的壓力。因爲客戶端包含的邏輯很少,因此也被成爲瘦客戶端。
2 、優點和缺點
優點:
1)客戶端無需安裝,有Web瀏覽器即可。
2)BS架構可以直接放在廣域網上,通過一定的權限控制實現多客戶訪問的目的,交互性較強。
3)BS架構無需升級多個客戶端,升級服務器即可。
缺點:
1)在跨瀏覽器上,BS架構不盡如人意。
2)表現要達到CS程序的程度需要花費不少精力。
3)在速度和安全性上需要花費巨大的設計成本,這是BS架構的最大問題。
4)客戶端服務器端的交互是請求-響應模式,通常需要刷新頁面,這並不是客戶樂意看到的。(在Ajax風行後此問題得到了一定程度的緩解)

134. TCP/IP、Http、Socket的區別

網絡由下往上分爲
  物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層。
  通過初步的瞭解,我知道IP協議對應於網絡層,TCP協議對應於傳輸層,而HTTP協議對應於應用層,
  三者從本質上來說沒有可比性,
  socket則是對TCP/IP協議的封裝和應用(程序員層面上)。
  也可以說,TPC/IP協議是傳輸層協議,主要解決數據如何在網絡中傳輸,
  而HTTP是應用層協議,主要解決如何包裝數據。
  關於TCP/IP和HTTP協議的關係,網絡有一段比較容易理解的介紹:
  “我們在傳輸數據時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別數據內容。
  如果想要使傳輸的數據有意義,則必須使用到應用層協議。
  應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。
  WEB使用HTTP協議作應用層協議,以封裝HTTP文本信息,然後使用TCP/IP做傳輸層協議將它發到網絡上。”
  而我們平時說的最多的socket是什麼呢,實際上socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用接口(API)。
  通過Socket,我們才能使用TCP/IP協議。
  實際上,Socket跟TCP/IP協議沒有必然的聯繫。
  Socket編程接口在設計的時候,就希望也能適應其他的網絡協議。
  所以說,Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,
  從而形成了我們知道的一些最基本的函數接口,比如create、listen、connect、accept、send、read和write等等。
  網絡有一段關於socket和TCP/IP協議關係的說法比較容易理解:
  “TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作接口。
  這個就像操作系統會提供標準的編程接口,比如win32編程接口一樣,
  TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口。”
  關於TCP/IP協議的相關只是,用博大精深來講我想也不爲過,單單查一下網上關於此類只是的資料和書籍文獻的數量就知道,
  這個我打算會買一些經典的書籍(比如《TCP/IP詳解:卷一、卷二、卷三》)進行學習,今天就先總結一些基於基於TCP/IP協議的應用和編程接口的知識,也就是剛纔說了很多的HTTP和Socket。
  CSDN上有個比較形象的描述:HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。
  實際上,傳輸層的TCP是基於網絡層的IP協議的,而應用層的HTTP協議又是基於傳輸層的TCP協議的,而Socket本身不算是協議,就像上面所說,它只是提供了一個針對TCP或者UDP編程的接口。
  下面是一些經常在筆試或者面試中碰到的重要的概念,特在此做摘抄和總結。
  一、什麼是TCP連接的三次握手
  第一次握手:客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;
  第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
  第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
  握手過程中傳送的包裏不包含數據,三次握手完畢後,客戶端與服務器才正式開始傳送數據。
  理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。
  斷開連接時服務器和客戶端均可以主動發起斷開TCP連接的請求,斷開過程需要經過“四次握手”(過程就不細寫了,就是服務器和客戶端交互,最終確定斷開)
  二、利用Socket建立網絡連接的步驟
  建立Socket連接至少需要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另一個運行於服務器端,稱爲ServerSocket 。
  套接字之間的連接過程分爲三個步驟:服務器監聽,客戶端請求,連接確認。
  1、服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。
  2、客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。
  爲此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端套接字提出連接請求。
  3、連接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。
  而服務器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。
  三、HTTP鏈接的特點
  HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。
  HTTP連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束後,會主動釋放連接。從建立連接到關閉連接的過程稱爲“一次連接”。
  四、TCP和UDP的區別(考得最多。。快被考爛了我覺得- -\)
  1、TCP是面向鏈接的,雖然說網絡的不安全不穩定特性決定了多少次握手都不能保證連接的可靠性,但TCP的三次握手在最低限度上(實際上也很大程度上保證了)保證了連接的可靠性;
  而UDP不是面向連接的,UDP傳送數據前並不與對方建立連接,對接收到的數據也不發送確認信號,發送端不知道數據是否會正確接收,當然也不用重發,所以說UDP是無連接的、不可靠的一種數據傳輸協議。
  2、也正由於1所說的特點,使得UDP的開銷更小數據傳輸速率更高,因爲不必進行收發數據的確認,所以UDP的實時性更好。
  知道了TCP和UDP的區別,就不難理解爲何採用TCP傳輸協議的MSN比採用UDP的QQ傳輸文件慢了,但並不能說QQ的通信是不安全的,
  因爲程序員可以手動對UDP的數據收發進行驗證,比如發送方對每個數據包進行編號然後由接收方進行驗證啊什麼的,
  即使是這樣,UDP因爲在底層協議的封裝上沒有采用類似TCP的“三次握手”而實現了TCP所無法達到的傳輸效率。

135. HTTP和SOAP完全就是兩個不同的協議

HTTP只負責把數據傳送過去,不會管這個數據是XML、HTML、圖片、文本文件或者別的什麼。而SOAP協議則定義了怎麼把一個對象變成XML文本,在遠程如何調用等,怎麼能夠混爲一談。
這樣說兩種協議:
HTTP就是郵局的協議,他們規定了你的信封要怎麼寫,要貼多少郵票等。。。。
SOAP就是你們之間交流的協議,負責把你所需要表達的意思寫在信紙上,同時也負責讓對方能夠看得懂你的信。
Web service一般就是用SOAP協議通過HTTP來調用它,其實他就是一個WSDL文檔,客戶都可以閱讀WSDL文檔來用這個Web service。客戶根據WSDL描述文檔,會生成一個SOAP請求消息。Web service都是放在Web服務器 (如IIS) 後面的,客戶生成的SOAP請求會被嵌入在一個HTTP POST請求中,發送到Web服務器來。Web服務器再把這些請求轉發給Web service請求處理器。請求處理器的作用在於,解析收到的SOAP請求,調用Web service,然後再生成相應的SOAP應答。Web服務器得到SOAP應答後,會再通過HTTP應答的方式把它送回到客戶端。
webService協議主要包括兩個方面:傳輸協議和數據表示,關於傳輸協議可以是http或其他,數據表示也可以是鍵值對、xml或其他,只不過現在通用的是http+soap,當然其他的也可以,不知道這樣理解對不對?
SOAP簡單的理解,就是這樣的一個開放協議SOAP=RPC+HTTP+XML:採用HTTP作爲底層通訊協議;RPC作爲一致性的調用途徑,XML作爲數據傳送的格式,允許服務提供者和服務客戶經過防火牆在INTERNET進行通訊交互。

136. 怎麼讓在啓動一個Activity是就啓動一個service

首先定義好一個service,然後在Activity的onCreate裏面進行連接並bindservice或者直接startService

137. 使用多線程和雙緩衝

Android的SurfaceView是View的子類,她同時也實現了雙緩衝。你可以定義一個她的子類並實現Surfaceholder.Callback接口。由於SurfaceHolder.Callback接口,新線程就不要android.os.Handler幫忙了。SurfaceHolder中lockCanvas()方法可以鎖定畫布,繪製完新的圖像後調用unlockCanvasand Post解鎖。

138. Object有哪些公用方法?

方法equals測試的是兩個對象是否相等
方法clone進行對象拷貝
方法getClass返回和當前對象相關的Class對象
方法notify,notifyall,wait都是用來對給定對象進行線程同步的

139. Java的四種引用的區別

強引用:如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM 也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯式地將引用賦值爲null,這樣一來的話,JVM在合適的時間就會回收該對象
軟引用:在使用軟引用時,如果內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用纔會被垃圾回收器回收。
弱引用:具有弱引用的對象擁有的生命週期更短暫。因爲當 JVM 進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先級較低的線程,所以並不一定能迅速發現弱引用對象
虛引用:顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那麼它相當於沒有引用,在任何時候都可能被垃圾回收器回收。

140. 若Activity已經銷燬,此時AsynTask執行完並且返回結果,會報異常嗎?

當一個App旋轉時,整個Activity會被銷燬和重建。當Activity重啓時,AsyncTask中對該Activity的引用是無效的,因此onPostExecute()就不會起作用,若AsynTask正在執行,折會報 view not attached to window manager 異常
同樣也是生命週期的問題,在 Activity 的onDestory()方法中調用Asyntask.cancal方法,讓二者的生命週期同步

141. Activity銷燬但Task如果沒有銷燬掉,當Activity重啓時這個AsyncTask該如何解決?

還是屏幕旋轉這個例子,在重建Activity的時候,會回掉Activity.onRetainNonConfigurationInstance()重新傳遞一個新的對象給AsyncTask,完成引用的更新

142. Android 線程間通信有哪幾種方式(重要)

共享內存(變量);
文件,數據庫;
Handler;
Java 裏的 wait(),notify(),notifyAll()

143. 請介紹下 AsyncTask的內部實現,適用的場景

AsyncTask 內部也是 Handler 機制來完成的,只不過 Android 提供了執行框架來提供線程池來
執行相應地任務,因爲線程池的大小問題,所以 AsyncTask 只應該用來執行耗時時間較短的任務,
比如 HTTP 請求,大規模的下載和數據庫的更改不適用於 AsyncTask,因爲會導致線程池堵塞,沒有
線程來執行其他的任務,導致的情形是會發生 AsyncTask 根本執行不了的問題。

144. 推送心跳包是TCP包還是UDP包或者HTTP包

心跳包的實現是調用了socket.sendUrgentData(0xFF)這句代碼實現的,所以,當然是TCP包。

145. 如何實現文件斷點上傳

在 Android 中上傳文件可以採用 HTTP 方式,也可以採用 Socket 方式,但是 HTTP 方式不能上傳
大文件,這裏介紹一種通過 Socket 方式來進行斷點續傳的方式,服務端會記錄下文件的上傳進度,
當某一次上傳過程意外終止後,下一次可以繼續上傳,這裏用到的其實還是 J2SE 裏的知識。
這個上傳程序的原理是:客戶端第一次上傳時向服務端發送
“Content-Length=35;filename=WinRAR_3.90_SC.exe;sourceid=“這種格式的字符串,服務端 收到後會查找該文件是否有上傳記錄,如果有就返回已經上傳的位置,否則返回新生成的 sourceid 以及 position 爲 0,類似 sourceid=2324838389;position=0“這樣的字符串,客戶端收到返回後 的字符串後再從指定的位置開始上傳文件。

146. Fragment 在你們項目中的使用

Fragment 是 android3.0 以後引入的的概念,做局部內容更新更方便,原來爲了到達這一點要把多個佈局放到一個 activity 裏面,現在可以用多 Fragment 來代替,只有在需要的時候才加載Fragment,提高性能。

147. 如何自定義ViewGroup

1.指定的LayoutParams
2.onMeasure中計算所有childView的寬和高,然後根據childView的寬和高,計算自己的寬和高。(當然,如果不是wrap_content,直接使用父ViewGroup傳入的計算值即可)
3.onLayout中對所有的childView進行佈局。

148. View中onTouch,onTouchEvent,onClick的執行順序

dispatchTouchEvent—->onTouch—->onTouchEvent—–>onClick。在所有ACTION_UP事件之後才觸發onClick點擊事件。

149. ListView卡頓的原因與性能優化,越多越好

重用converView: 通過複用converview來減少不必要的view的創建,另外Infalte操作會把xml文件實例化成相應的View實例,屬於IO操作,是耗時操作。
減少findViewById()操作: 將xml文件中的元素封裝成viewholder靜態類,通過converview的setTag和getTag方法將view與相應的holder對象綁定在一起,避免不必要的findviewbyid操作
避免在 getView 方法中做耗時的操作: 例如加載本地 Image 需要載入內存以及解析 Bitmap ,都是比較耗時的操作,如果用戶快速滑動listview,會因爲getview邏輯過於複雜耗時而造成滑動卡頓現象。用戶滑動時候不要加載圖片,待滑動完成再加載,可以使用這個第三方庫glide
Item的佈局層次結構儘量簡單,避免佈局太深或者不必要的重繪
儘量能保證 Adapter 的 hasStableIds() 返回 true 這樣在 notifyDataSetChanged() 的時候,如果item內容並沒有變化,ListView 將不會重新繪製這個 View,達到優化的目的
在一些場景中,ScollView內會包含多個ListView,可以把listview的高度寫死固定下來。 由於ScollView在快速滑動過程中需要大量計算每一個listview的高度,阻塞了UI線程導致卡頓現象出現,如果我們每一個item的高度都是均勻的,可以通過計算把listview的高度確定下來,避免卡頓現象出現
使用 RecycleView 代替listview: 每個item內容的變動,listview都需要去調用notifyDataSetChanged來更新全部的item,太浪費性能了。RecycleView可以實現當個item的局部刷新,並且引入了增加和刪除的動態效果,在性能上和定製上都有很大的改善
ListView 中元素避免半透明: 半透明繪製需要大量乘法計算,在滑動時不停重繪會造成大量的計算,在比較差的機子上會比較卡。 在設計上能不半透明就不不半透明。實在要弄就把在滑動的時候把半透明設置成不透明,滑動完再重新設置成半透明。
儘量開啓硬件加速: 硬件加速提升巨大,避免使用一些不支持的函數導致含淚關閉某個地方的硬件加速。當然這一條不只是對 ListView。

150. 三級緩存的原理

從緩存中加載。
從本地文件中加載(數據庫,SD)
從網絡加載。
a.加載 bitmap 的時候無需考慮 bitmap 加載過程中出現的 oom(內存溢出)和 android 容器快速
滑動的時候出現的圖片錯位等現象。(16M)
b. 支持加載網絡圖片和本地圖片。
c. 內存管理使用的 lru 算法(移除裏面是有頻率最少的對象),更好的管理 bitmap 的內存

151. apk安裝卸載的原理

安裝過程:複製apk安裝包到data/app目錄下,解壓並掃描安裝包,把dex文件(dalvik字節碼)保存到dalvik-cache目錄,並data/data目錄下創建對應的應用數據目錄。
卸載過程:刪除安裝過程中在上述三個目錄下創建的文件及目錄。

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