Android是一種基於Linux的自由及開放源代碼的操做系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。這裏會不斷收集和更新Android基礎相關的面試題,目前已收集100題。javascript
Activity生命週期方法主要有onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()和onRestart()等7個方法。java
Fragment的生命週期linux
Fragment與Activity生命週期對比android
Fragment的生命週期方法主要有onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()、onPause()、onStop()、onDestroyView()、onDestroy()、onDetach()等11個方法。git
在Service的生命週期裏,經常使用的有:github
4個手動調用的方法web
startService() 啓動服務
stopService() 關閉服務
bindService() 綁定服務
unbindService() 解綁服務複製代碼
5個內部自動調用的方法面試
onCreat() 建立服務
onStartCommand() 開始服務
onDestroy() 銷燬服務
onBind() 綁定服務
onUnbind() 解綁服務複製代碼
Android中動畫分別幀動畫、補間動畫和屬性動畫(Android 3.0之後的)算法
幀動畫是最容易實現的一種動畫,這種動畫更多的依賴於完善的UI資源,他的原理就是將一張張單獨的圖片連貫的進行播放,從而在視覺上產生一種動畫的效果;有點相似於某些軟件製做gif動畫的方式。在有些代碼中,咱們還會看到android:oneshot="false" ,這個oneshot 的含義就是動畫執行一次(true)仍是循環執行屢次。sql
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/a_0"
android:duration="100" />
<item
android:drawable="@drawable/a_1"
android:duration="100" />
<item
android:drawable="@drawable/a_2"
android:duration="100" />
</animation-list>複製代碼
補間動畫又能夠分爲四種形式,分別是 alpha(淡入淡出),translate(位移),scale(縮放大小),rotate(旋轉)。
補間動畫的實現,通常會採用xml 文件的形式;代碼會更容易書寫和閱讀,同時也更容易複用。Interpolator 主要做用是能夠控制動畫的變化速率 ,就是動畫進行的快慢節奏。pivot 決定了當前動畫執行的參考位置
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>複製代碼
屬性動畫,顧名思義它是對於對象屬性的動畫。所以,全部補間動畫的內容,均可以經過屬性動畫實現。屬性動畫的運行機制是經過不斷地對值進行操做來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內部使用一種時間循環的機制來計算值與值之間的動畫過渡,咱們只須要將初始值和結束值提供給ValueAnimator,而且告訴它動畫所需運行的時長,那麼ValueAnimator就會自動幫咱們完成從初始值平滑地過渡到結束值這樣的效果。除此以外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等。
經常使用的佈局:
FrameLayout(幀佈局):全部東西依次都放在左上角,會重疊
LinearLayout(線性佈局):按照水平和垂直進行數據展現
RelativeLayout(相對佈局):以某一個元素爲參照物,來定位的佈局方式複製代碼
不經常使用的佈局:
TableLayout(表格佈局): 每個TableLayout裏面有表格行TableRow,TableRow裏面能夠具體定義每個元素(Android TV上使用)
AbsoluteLayout(絕對佈局):用X,Y座標來指定元素的位置,元素多就不適用。(機頂盒上使用)複製代碼
新增佈局:
PercentRelativeLayout(百分比相對佈局)能夠經過百分比控制控件的大小。
PercentFrameLayout(百分比幀佈局)能夠經過百分比控制控件的大小。複製代碼
方案二、使用XMPP協議(Openfire + Spark + Smack)
方案三、使用MQTT協議(更多信息見:mqtt.org/)
介紹 Android 啓動模式以前,先介紹兩個概念task和taskAffinity
4種啓動模式
首先寫一個類要繼承BroadCastReceiver
第一種:在清單文件中聲明,添加
<receive android:name=".BroadCastReceiverDemo">
<intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"> </intent-filter> </receiver>複製代碼
第二種:使用代碼進行註冊如:
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
BroadCastReceiverDemo receiver = new BroadCastReceiver();
registerReceiver(receiver, filter);複製代碼
兩種註冊類型的區別是:
a.第一種是常駐型廣播,也就是說當應用程序關閉後,若是有信息廣播來,程序也會被系統調用自動運行。
b.第二種不是常駐廣播,也就是說廣播跟隨程序的生命週期。
ANR的全稱application not responding 應用程序未響應。
在android中Activity的最長執行時間是5秒。
BroadcastReceiver的最長執行時間則是10秒。
Service的最長執行時間則是20秒。複製代碼
超出執行時間就會產生ANR。注意:ANR是系統拋出的異常,程序是捕捉不了這個異常的。
解決方法:
root指的是你有權限能夠再系統上對全部檔案有 "讀" "寫" "執行"的權力。root機器不是真正能讓你的應用程序具備root權限。它原理就跟linux下的像sudo這樣的命令。在系統的bin目錄下放個su程序並屬主是root並有suid權限。則經過su執行的命令都具備Android root權限。固然使用臨時用戶權限想把su拷貝的/system/bin目錄並改屬性並非一件容易的事情。這裏用到2個工具跟2個命令。把busybox拷貝到你有權限訪問的目錄而後給他賦予4755權限,你就能夠用它作不少事了。
顯示視圖,內置畫布,提供圖形繪製函數、觸屏事件、按鍵事件函數等,必須在UI主線程內更新畫面,速度較慢
基於view視圖進行拓展的視圖類,更適合2D遊戲的開發,是view的子類,相似使用雙緩機制,在新的線程中更新畫面因此刷新界面速度比view快
基於SurfaceView視圖再次進行拓展的視圖類,專用於3D遊戲開發的視圖,是surfaceView的子類,openGL專用
AsyncTask的三個泛型參數說明
運行在主線程的方法:
onPostExecute()
onPreExecute()
onProgressUpdate(Progress...)複製代碼
運行在子線程的方法:
doInBackground()複製代碼
控制AsyncTask中止的方法:
cancel(boolean mayInterruptIfRunning)複製代碼
AsyncTask的執行分爲四個步驟
I18n 叫作國際化。android 對i18n和L10n提供了很是好的支持。軟件在res/vales 以及 其餘帶有語言修飾符的文件夾。如: values-zh 這些文件夾中 提供語言,樣式,尺寸 xml 資源。
經過主界面進入,就是設置默認啓動的activity。在manifest.xml文件的activity標籤中,寫如下代碼
<intent- filter>
<intent android:name=「android.intent.action.MAIN」>
<intent android:name=」android:intent.category.LAUNCHER」>
</intent-filter>複製代碼
從另外一個組件跳轉到目標activity,須要經過intent進行跳轉。具體
Intent intent=new Intent(this,activity.class),startActivity(intent)複製代碼
內存溢出:當程序運行時所需的內存大於程序容許的最高內存,這時會出現內存溢出;
內存泄漏:在一些比較消耗資源的操做中,若是操做中內存一直未被釋放,就會出現內存泄漏。好比未關閉io,cursor。
sim卡就是電話卡,sim卡內有本身的操做系統,用來與手機通信的。Ef文件用來存儲數據的。
運行
暫停
中止複製代碼
設置activity的style屬性=」@android:style/Theme.Dialog」
gravity:表示組件內元素的對齊方式
layout_gravity:相對於父類容器,該視圖組件的對齊方式
結束當前activity
Finish()
killProgress()
System.exit(0)複製代碼
關閉應用程序時,結束全部的activity
能夠建立一個List集合,每新建立一個activity,將該activity的實例放進list中,程序結束時,從集合中取出循環取出activity實例,調用finish()方法結束
在onPuase方法中調用onSavedInstanceState()
Px:像素
Sp與dp也是長度單位,可是與屏幕的單位密度無關。複製代碼
這三個都是android應用頻率很是的組件。Activity與service是四大核心組件。Activity用來加載佈局,顯示窗口界面,service運行後臺,沒有界面顯示,intent是activity與service的通訊使者。
Fie:文件存儲,推薦使用sharedPreferecnces
靜態變量。複製代碼
是適配器,用來爲列表提供數據適配的。常用的adapter有baseadapter,arrayAdapter,SimpleAdapter,cursorAdapter,SpinnerAdapter等
Fragment對象有一個getActivity的方法,經過該方法與activity交互
使用framentmentManager.findFragmentByXX能夠獲取fragment對象,在activity中直接操做fragment對象複製代碼
使用adapter的notifyDataSetChanged方法
廣播接收者的生命週期很是短。當執行onRecieve方法以後,廣播就會銷燬
在廣播接受者不能進行耗時較長的操做
在廣播接收者不要建立子線程。廣播接收者完成操做後,所在進程會變成空進程,很容易被系統回收複製代碼
ContentProvider會對外隱藏內部實現,只須要關注訪問contentProvider的uri便可,contentProvider應用在應用間共享。
Sqlite操做本應用程序的數據庫。
ContentProiver能夠對本地文件進行增刪改查操做複製代碼
默認狀況下activity的狀態系統會自動保存,有些時候須要咱們手動調用保存。
當activity處於onPause,onStop以後,activity處於未活動狀態,可是activity對象卻仍然存在。當內存不足,onPause,onStop以後的activity可能會被系統摧毀。
當經過返回退出activity時,activity狀態並不會保存。
保存activity狀態須要重寫onSavedInstanceState()方法,在執行onPause,onStop以前調用onSavedInstanceState方法,onSavedInstanceState須要一個Bundle類型的參數,咱們能夠將數據保存到bundle中,經過實參傳遞給onSavedInstanceState方法。
Activity被銷燬後,從新啓動時,在onCreate方法中,接受保存的bundle參數,並將以前的數據取出。
Content與application都繼承與contextWrapper,contextWrapper繼承於Context類。
Context:表示當前上下文對象,保存的是上下文中的參數和變量,它可讓更加方便訪問到一些資源。
Context一般與activity的生命週期是同樣的,application表示整個應用程序的對象。
對於一些生命週期較長的,不要使用context,可使用application。
在activity中,儘可能使用靜態內部類,不要使用內部類。內部裏做爲外部類的成員存在,不是獨立於activity,若是內存中還有內存繼續引用到context,activity若是被銷燬,context還不會結束。
默認狀況service在main thread中執行,當service在主線程中運行,那在service中不要進行一些比較耗時的操做,好比說網絡鏈接,文件拷貝等。
默認狀況下service與activity在同一個線程,都在main Thread,或者ui線程中。
若是在清單文件中指定service的process屬性,那麼service就在另外一個進程中運行。
能夠。
能夠的,就在onstartConmand方法內執行。
ContentProvider:內容提供者,對外提供數據的操做,contentProvider.notifyChanged(uir):能夠更新數據
contentResolver:內容解析者,解析ContentProvider返回的數據
ContentObServer:內容監聽者,監聽數據的改變,contentResolver.registerContentObServer()複製代碼
ContentProvider是一個對外提供數據的接口,首先須要實現ContentProvider這個接口,而後重寫query,insert,getType,delete,update方法,最後在清單文件定義contentProvider的訪問uri
基本數據類型以及對應的數組類型
能夠傳遞bundle類型,可是bundle類型的數據須要實現Serializable或者parcelable接口複製代碼
若是存儲在內存中,推薦使用parcelable,使用serialiable在序列化的時候會產生大量的臨時變量,會引發頻繁的GC
若是存儲在硬盤上,推薦使用Serializable,雖然serializable效率較低
Serializable的實現:只須要實現Serializable接口,就會自動生成一個序列化id
Parcelable的實現:須要實現Parcelable接口,還須要Parcelable.CREATER變量
Intent是組件的通信使者,能夠在組件間傳遞消息和數據。
IntentFilter是intent的篩選器,能夠對intent的action,data,catgory,uri這些屬性進行篩選,肯定符合的目標組件。複製代碼
IntentService 是 Service 的子類,比普通的 Service 增長了額外的功能。先看 Service 自己存在兩個問題:
Service 不會專門啓動一條單獨的進程,Service 與它所在應用位於同一個進程中;
Service 也不是專門一條新線程,所以不該該在 Service 中直接處理耗時的任務;複製代碼
特徵
會建立獨立的 worker 線程來處理全部的 Intent 請求;
會建立獨立的 worker 線程來處理 onHandleIntent()方法實現的代碼,無需處理多線程問題;
全部請求處理完成後,IntentService 會自動中止,無需調用 stopSelf()方法中止 Service;
爲 Service 的 onBind()提供默認實現,返回 null;
爲 Service 的 onStartCommand 提供默認實現,將請求 Intent 添加到隊列中複製代碼
使用
讓service類繼承IntentService,重寫onStartCommand和onHandleIntent實現複製代碼
從 MVC 的角度考慮(應用程序內) 其實回答這個問題的時候還能夠這樣問,android 爲何要有那 4 大組件,如今的移動開發模型基本上也是照搬的 web 那一套 MVC 架構,只不過稍微作了修改。android 的四大組件本質上就是爲了實現移動或者說嵌入式設備上的 MVC 架構,它們之間有時候是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制能夠方便幾大組件的信息和數據交互。
程序間互通消息(例如在本身的應用程序內監聽系統來電)
效率上(參考 UDP 的廣播協議在局域網的方便性)
設計模式上(反轉控制的一種應用,相似監聽者模式)
當 convertView 爲空時,用 setTag()方法爲每一個 View 綁定一個存放控件的 ViewHolder 對象。當convertView 不爲空, 重複利用已經建立的 view 的時候, 使用 getTag()方法獲取綁定的 ViewHolder對象,這樣就避免了 findViewById 對控件的層層查詢,而是快速定位到控件。 複用 ConvertView,使用歷史的 view,提高效率 200%
自定義靜態類 ViewHolder,減小 findViewById 的次數。提高效率 50%
異步加載數據,分頁加載數據。
使用 WeakRefrence 引用 ImageView 對象
設置 ListView 的滾動監聽器:setOnScrollListener(new OnScrollListener{….})在監聽器中有兩個方法: 滾動狀態發生變化的方法(onScrollStateChanged)和 listView 被滾動時調用的方法(onScroll)
在滾動狀態發生改變的方法中,有三種狀態:手指按下移動的狀態: SCROLL_STATE_TOUCH_SCROLL:觸摸滑動,慣性滾動(滑翔(flgin)狀態): SCROLL_STATE_FLING: 滑翔,靜止狀態: SCROLL_STATE_IDLE: // 靜止,對不一樣的狀態進行處理:
分批加載數據,只關心靜止狀態:關心最後一個可見的條目,若是最後一個可見條目就是數據適配器(集合)裏的最後一個,此時可加載更多的數據。在每次加載的時候,計算出滾動的數量,當滾動的數量大於等於總數量的時候,能夠提示用戶無更多數據了。
這個固然能夠的,ListView 顯示的每一個條目都是經過 baseAdapter 的 getView(int position,View convertView, ViewGroup parent)來展現的,理論上咱們徹底可讓每一個條目都是不一樣類型的view。
好比:從服務器拿回一個標識爲 id=1,那麼當 id=1 的時候,咱們就加載類型一的條目,當 id=2的時候,加載類型二的條目。常見佈局在資訊類客戶端中能夠常常看到。
除此以外 adapter 還提供了 getViewTypeCount()和 getItemViewType(int position)兩個方法。在 getView 方法中咱們能夠根據不一樣的 viewtype 加載不一樣的佈局文件。
能夠經過 ListView 提供的 lv.setSelection(listView.getPosition())方法。
一般狀況下咱們不會在 ScrollView 中嵌套 ListView。
在 ScrollView 添加一個 ListView 會致使 listview 控件顯示不全,一般只會顯示一條,這是由於兩個控件的滾動事件衝突致使。因此須要經過 listview 中的 item 數量去計算 listview 的顯示高度,從而使其完整展現。
現階段最好的處理的方式是: 自定義 ListView,重載 onMeasure()方法,設置所有顯示。
manifest:根節點,描述了package中全部的內容。
uses-permission:請求你的package正常運做所需賦予的安全許可。
permission: 聲明瞭安全許可來限制哪些程序能你package中的組件和功能。
instrumentation:聲明瞭用來測試此package或其餘package指令組件的代碼。
application:包含package中application級別組件聲明的根節點。
activity:Activity是用來與用戶交互的主要工具。
receiver:IntentReceiver能使的application得到數據的改變或者發生的操做,即便它當前不在運行。
service:Service是能在後臺運行任意時間的組件。
provider:ContentProvider是用來管理持久化數據併發布給其餘應用程序使用的組件。複製代碼
圖片錯位問題的本質源於咱們的 listview 使用了緩存 convertView, 假設一種場景, 一個 listview一屏顯示九個 item,那麼在拉出第十個 item 的時候,事實上該 item 是重複使用了第一個 item,也就是說在第一個 item 從網絡中下載圖片並最終要顯示的時候,其實該 item 已經不在當前顯示區域內了,此時顯示的後果將可能在第十個 item 上輸出圖像,這就致使了圖片錯位的問題。因此解決辦法就是可見則顯示,不可見則不顯示。
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 方法。基於以上不一樣的特色咱們在使用的使用必定要結合着生命週期操做咱們的視圖和數據。
Fragment 的事物管理器內部維持了一個雙向鏈表結構,該結構能夠記錄咱們每次 add 的Fragment 和 replace 的 Fragment,而後當咱們點擊 back 按鈕的時候會自動幫咱們實現退棧操做。
Fragment 是 android3.0 之後引入的的概念,作局部內容更新更方便,原來爲了到達這一點要把多個佈局放到一個 activity 裏面,如今能夠用多 Fragment 來代替,只有在須要的時候才加載Fragment,提升性能。
Fragment 的好處:
Fragment 可使你可以將 activity 分離成多個可重用的組件,每一個都有它本身的生命週期和UI。
Fragment 能夠輕鬆得建立動態靈活的 UI 設計,能夠適應於不一樣的屏幕尺寸。從手機到平板電腦。
Fragment 是一個獨立的模塊,牢牢地與 activity 綁定在一塊兒。能夠運行中動態地移除、加入、交換等。
Fragment 提供一個新的方式讓你在不一樣的安卓設備上統一你的 UI。
Fragment 解決 Activity 間的切換不流暢,輕量切換。
Fragment 替代 TabActivity 作導航,性能更好。
Fragment 在 4.2.版本中新增嵌套 fragment 使用方法,可以生成更好的界面效果。複製代碼
翻看了 Android 官方 Doc,和一些組件的源代碼,發現 replace()這個方法只是在上一個 Fragment再也不須要時採用的簡便方法.
正確的切換方式是 add(),切換時 hide(),add()另外一個 Fragment;再次切換時,只需 hide()當前,show()另外一個。
這樣就能作到多個 Fragment 切換不從新實例化:
若是不考慮使用其餘第三方性能分析工具的話,咱們能夠直接使用 ddms 中的工具,其實 ddms 工具已經很是的強大了。ddms 中有 traceview、heap、allocation tracker 等工具均可以幫助咱們分析應用的方法執行時間效率和內存使用狀況。
Traceview 是 Android 平臺特有的數據採集和分析工具,它主要用於分析 Android 中應用程序的 hotspot(瓶頸)。Traceview 自己只是一個數據分析工具,而數據的採集則須要使用 AndroidSDK 中的 Debug 類或者利用 DDMS 工具。
heap 工具能夠幫助咱們檢查代碼中是否存在會形成內存泄漏的地方。
allocation tracker 是內存分配跟蹤工具
UncaughtExceptionHandler
自 定 義 一 個 Application , 比 如 叫 MyApplication 繼 承 Application 實 現UncaughtExceptionHandler。
覆寫 UncaughtExceptionHandler 的 onCreate 和 uncaughtException 方法。 注意:上面的代碼只是簡單的將異常打印出來。在 onCreate 方法中咱們給 Thread 類設置默認異常處理 handler,若是這句代碼不執行則一切都是白搭。在 uncaughtException 方法中咱們必須新開闢個線程進行咱們異常的收集工做,而後將系統給殺死。
在 AndroidManifest 中配置該 Application:<application android:name="com.example.uncatchexception.MyApplication"複製代碼
Bug 收集工具 Crashlytics
Crashlytics 是專門爲移動應用開發者提供的保存和分析應用崩潰的工具。國內主要使用的是友盟作數據統計。
Crashlytics 的好處:
1.Crashlytics 不會漏掉任何應用崩潰信息。
2.Crashlytics 能夠象 Bug 管理工具那樣,管理這些崩潰日誌。
3.Crashlytics 能夠天天和每週將崩潰信息彙總發到你的郵箱,全部信息一目瞭然。複製代碼
把這個文件放在/res/raw目錄下便可。res\raw目錄中的文件不會被壓縮,這樣能夠直接提取該目錄中的文件,會生成資源id。
IntentService 是 Service 的子類,比普通的 Service 增長了額外的功能。先看 Service 自己存在兩個問題:
Service 不會專門啓動一條單獨的進程,Service 與它所在應用位於同一個進程中;
Service 也不是專門一條新線程,所以不該該在 Service 中直接處理耗時的任務;複製代碼
IntentService 特徵
會建立獨立的 worker 線程來處理全部的 Intent 請求;
會建立獨立的 worker 線程來處理 onHandleIntent()方法實現的代碼,無需處理多線程問題;
全部請求處理完成後,IntentService 會自動中止,無需調用 stopSelf()方法中止 Service;
爲 Service 的 onBind()提供默認實現,返回 null;
爲 Service 的 onStartCommand 提供默認實現,將請求 Intent 添加到隊列中;複製代碼
NDK是一系列工具的集合.NDK提供了一系列的工具,幫助開發者快速開發C或C++的動態庫,並能自動將so和java應用一塊兒打包成apk.這些工具對開發者的幫助是巨大的.NDK集成了交叉編譯器,並提供了相應的mk文件隔離CPU,平臺,ABI等差別,開發人員只須要簡單修改 mk文件(指出"哪些文件須要編譯","編譯特性要求"等),就能夠建立出so.
NDK能夠自動地將so和Java應用一塊兒打包,極大地減輕了開發人員的打包工做.NDK提供了一份穩定,功能有限的API頭文件聲明.
Google明確聲明該API是穩定的,在後續全部版本中都穩定支持當前發佈的API.從該版本的NDK中看出,這些 API支持的功能很是有限,包含有:C標準庫(libc),標準數學庫(libm ),壓縮庫(libz),Log庫(liblog).
AsyncTask 運用的場景就是咱們須要進行一些耗時的操做,耗時操做完成後更新主線程,或者在操做過程當中對主線程的UI進行更新。
缺陷:AsyncTask中維護着一個長度爲128的線程池,同時能夠執行5個工做線程,還有一個緩衝隊列,當線程池中已有128個線程,緩衝隊列已滿時,若是 此時向線程提交任務,將會拋出RejectedExecutionException。
解決:由一個控制線程來處理AsyncTask的調用判斷線程池是否滿了,若是滿了則線程睡眠不然請求AsyncTask繼續處理。
共享內存(變量);
文件,數據庫;
Handler;
Java 裏的 wait(),notify(),notifyAll()複製代碼
apk 程序是運行在虛擬機上的,對應的是 Android 獨特的權限機制,只有體現到文件系統上時才
使用 linux 的權限設置。
linux 文件系統上的權限
-rwxr-x--x system system 4156 2010-04-30 16:13 test.apk
表明的是相應的用戶/用戶組及其餘人對此文件的訪問權限,與此文件運行起來具備的權限徹底不相關。好比上面的例子只能說明 system 用戶擁有對此文件的讀寫執行權限;system 組的用戶對此文件擁有讀、執行權限;其餘人對此文件只具備執行權限。而 test.apk 運行起來後能夠幹哪些事情,跟這個就不相關了。千萬不要看 apk 文件系統上屬於 system/system 用戶及用戶組,或者root/root 用戶及用戶組,就認爲 apk 具備 system 或 root 權限複製代碼
Android 的權限規則
Android 中的 apk 必須簽名
基於 UserID 的進程級別的安全機制
默認 apk 生成的數據對外是不可見的
AndroidManifest.xml 中的顯式權限聲明複製代碼
全部的框架都是基於反射 和 配置文件(manifest)的。
普通的狀況:
Activity 建立一個 view 是經過 ondraw 畫出來的, 畫這個 view 以前呢,還會調用 onmeasure方法來計算顯示的大小.複製代碼
特殊狀況:
Surfaceview 是直接操做硬件的,由於 或者視頻播放對幀數有要求,onDraw 效率過低,不夠使,Surfaceview 直接把數據寫到顯存。複製代碼
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 文件生成的接口)實際上是系統產生的代理對象,該代理對象既能夠跟咱們的進程通訊, 又能夠跟遠程進程通訊, 做爲一箇中間的角色實現了進程間通訊。複製代碼
AIDL 全稱 Android Interface Definition Language(AndRoid 接口描述語言) 是一種接口描述語言; 編譯器能夠經過 aidl 文件生成一段代碼,經過預先定義的接口達到兩個進程內部通訊進程跨界對象訪問的目的。須要完成兩件事情:
引入 AIDL 的相關類.;
調用 aidl 產生的 class複製代碼
理論上, 參數能夠傳遞基本數據類型和 String, 還有就是 Bundle 的派生類, 不過在 Eclipse 中,目前的 ADT 不支持 Bundle 作爲參數。
首先要在AndroidManifest.xml中增長SD卡訪問權限
Task其實是一個Activity棧,一般用戶感覺的一個Application就是一個Task。從這個定義來看,Task跟Service或者其餘Components是沒有任何聯繫的,它只是針對Activity而言的。
Activity有不一樣的啓動模式, 能夠影響到task的分配
在sqlite插入數據的時候默認一條語句就是一個事務,有多少條數據就有多少次磁盤操做 好比5000條記錄也就是要5000次讀寫磁盤操做。
添加事務處理,把多條記錄的插入或者刪除做爲一個事務
1.Touch事件傳遞的相關API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
2.Touch事件相關的類有View、ViewGroup、Activity
3.Touch事件會被封裝成MotionEvent對象,該對象封裝了手勢按下、移動、鬆開等動做
4.Touch事件一般從Activity#dispatchTouchEvent發出,只要沒有被消費,會一直往下傳遞,到最底層的View。
5.若是Touch事件傳遞到的每一個View都不消費事件,那麼Touch事件會反向向上傳遞,最終交由Activity#onTouchEvent處理.
6.onInterceptTouchEvent爲ViewGroup特有,能夠攔截事件.
7.Down事件到來時,若是一個View沒有消費該事件,那麼後續的MOVE/UP事件都不會再給它複製代碼
1)Looper: 一個線程能夠產生一個Looper對象,由它來管理此線程裏的MessageQueue(消息隊列)。
2)Handler: 你能夠構造Handler對象來與Looper溝通,以便push新消息到MessageQueue裏;或者接收Looper從Message Queue取出)所送來的消息。
3) Message Queue(消息隊列):用來存放線程放入的消息。
4)線程:UIthread 一般就是main thread,而Android啓動程序時會替它創建一個MessageQueue。複製代碼
Hander持有對UI主線程消息隊列MessageQueue和消息循環Looper的引用,子線程能夠經過Handler將消息發送到UI線程的消息隊列MessageQueue中。
自定義View的屬性 編寫attr.xml文件
在layout佈局文件中引用,同時引用命名空間
在View的構造方法中得到咱們自定義的屬性 ,在自定義控件中進行讀取(構造方法拿到attr.xml文件值)
重寫onMesure
重寫onDraw複製代碼
用 Activity 對象的 runOnUiThread 方法更新
在子線程中經過 runOnUiThread()方法更新 UI:
若是在非上下文類中(Activity),能夠經過傳遞上下文實現調用;複製代碼
用 View.post(Runnable r)方法更新 UI
不能,若是在子線程中直接 new Handler()會拋出異常 java.lang.RuntimeException: Can'tcreate handler inside thread that has not called
在沒有調用 Looper.prepare()的時候不能建立 Handler,由於在建立 Handler 的源碼中作了以下操做
Handler 的構造方法中
Frame Animation(幀動畫)主要用於播放一幀幀準備好的圖片,相似GIF圖片,優勢是使用簡單方便、缺點是須要事先準備好每一幀圖片;
Tween Animation(補間動畫)僅需定義開始與結束的關鍵幀,而變化的中間幀由系統補上,優勢是不用準備每一幀,缺點是隻改變了對象繪製,而沒有改變View自己屬性。所以若是改變了按鈕的位置,仍是須要點擊原來按鈕所在位置纔有效。
Property Animation(屬性動畫)是3.0後推出的動畫,優勢是使用簡單、下降實現的複雜度、直接更改對象的屬性、幾乎可適用於任何對象而僅非View類,主要包括ValueAnimator和ObjectAnimator
可 以 通 過 兩 種 方 式 , 一 是 通 過 定 義 Activity 的 主 題 , 二 是 通 過 覆 寫 Activity 的overridePendingTransition 方法。
經過設置主題樣式在 styles.xml 中編輯以下代碼:
添加 themes.xml 文件:
在 AndroidManifest.xml 中給指定的 Activity 指定 theme。 複製代碼
覆寫 overridePendingTransition 方法
overridePendingTransition(R.anim.fade, R.anim.hold);複製代碼
對稱加密,就是加密和解密數據都是使用同一個key,這方面的算法有DES。
非對稱加密,加密和解密是使用不一樣的key。發送數據以前要先和服務端約定生成公鑰和私鑰,使用公鑰加密的數據能夠用私鑰解密,反之。這方面的算法有RSA。ssh 和 ssl都是典型的非對稱加密。
這兩個方法都是在 View 的 dispatchTouchEvent 中調用的,onTouch 優先於 onTouchEvent執行。若是在 onTouch 方法中經過返回 true 將事件消費掉,onTouchEvent 將不會再執行。
另外須要注意的是,onTouch 可以獲得執行須要兩個前提條件,第一 mOnTouchListener 的值不能爲空,第二當前點擊的控件必須是 enable 的。所以若是你有一個控件是非 enable 的,那麼給它註冊 onTouch 事件將永遠得不到執行。對於這一類控件,若是咱們想要監聽它的 touch 事件,就必須經過在該控件中重寫 onTouchEvent 方法來實現。
補間動畫只是顯示的位置變更,View 的實際位置未改變,表現爲 View 移動到其餘地方,點擊事件仍在原處才能響應。而屬性動畫控件移動後事件相應就在控件移動後自己進行處理
pull2RefreshListView
LazyViewPager
SlidingMenu
SmoothProgressBar
自定義組合控件
ToggleButton
自定義Toast複製代碼
異常附近多打印 log 信息;
分析 log 日誌,實在不行的話進行斷點調試;
調試不出結果,上 Stack Overflow 貼上異常信息,請教大牛
再多看看代碼,或者從源代碼中查找相關信息
實在不行就 GG 了,找師傅來解決!複製代碼
頁式,段式,段頁,用到了MMU,虛擬空間等技術
EventBus(事件處理)
xUtils(網絡、圖片、ORM)
JPush(推送平臺)
友盟(統計平臺)
有米(優米)(廣告平臺)
百度地圖
bmob(服務器平臺、短信驗證、郵箱驗證、第三方支付)
阿里雲 OSS(雲存儲)
ShareSDK(分享平臺、第三方登陸)
Gson(解析 json 數據框架)
imageLoader (圖片處理框架)
zxing (二維碼掃描)
anroid-asyn-http(網絡通信)
DiskLruCache(硬盤緩存框架)
Viatimo(多媒體播放框架)
universal-image-loader(圖片緩存框架)
訊飛語音(語音識別)複製代碼
Bitmap 是 android 中常用的一個類,它表明了一個圖片資源。 Bitmap 消耗內存很嚴重,若是不注意優化代碼,常常會出現 OOM 問題,優化方式一般有這麼幾種:
使用緩存;
壓縮圖片;
及時回收;複製代碼
至於何時須要手動調用 recycle,這就看具體場景了,原則是當咱們再也不使用 Bitmap 時,須要回收之。另外,咱們須要注意,2.3 以前 Bitmap 對象與像素數據是分開存放的,Bitmap 對象存在java Heap 中而像素數據存放在 Native Memory 中, 這時頗有必要調用 recycle 回收內存。 可是 2.3以後,Bitmap 對象和像素數據都是存在 Heap 中,GC 能夠回收其內存。
AsyncTask 內部也是 Handler 機制來完成的,只不過 Android 提供了執行框架來提供線程池來執行相應地任務,由於線程池的大小問題,因此 AsyncTask 只應該用來執行耗時時間較短的任務,好比 HTTP 請求,大規模的下載和數據庫的更改不適用於 AsyncTask,由於會致使線程池堵塞,沒有線程來執行其餘的任務,致使的情形是會發生 AsyncTask 根本執行不了的問題
Intent在傳遞數據時是有大小限制的,這裏官方並未詳細說明,不過經過實驗的方法能夠測出數據應該被限制在1MB以內(1024KB),筆者採用的是傳遞Bitmap的方法,發現當圖片大小超過1024(準確地說是1020左右)的時候,程序就會出現閃退、中止運行等異常(不一樣的手機反應不一樣),所以能夠判斷Intent的傳輸容量在1MB以內。
較爲經常使用的就是單例設計模式,工廠設計模式以及觀察者設計模式,
通常須要保證對象在內存中的惟一性時就是用單例模式,例如對數據庫操做的 SqliteOpenHelper 的對象。
工廠模式主要是爲建立對象提供過渡接口,以便將建立對象的具體過程屏蔽隔離起來,達到提升靈活性的目的。
觀察者模式定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新
從服務器端獲取圖片
經過短信服務,將驗證碼發送給客戶端複製代碼
開始定位,Application 持有一個全局的公共位置對象,而後隔必定時間自動刷新位置,每次刷新成功都把新的位置信息賦值到全局的位置對象, 而後每一個須要使用位置請求的地方都使用全局的位置信息進行請求。
該方案好處:請求的時候無需再反覆定位,每次請求都使用全局的位置對象,節省時間。
該方案弊端:耗電,每隔必定時間自動刷新位置,對電量的消耗比較大。複製代碼
按需定位,每次請求前都進行定位。這樣作的好處是比較省電,並且節省資源,可是請求時間會變得相對較長。
前置條件是全部用戶相關接口都走 https,非用戶相關列表類數據走 http。
步驟
第一次登錄 getUserInfo 裏帶有一個長效 token,該長效 token 用來判斷用戶是否登錄和換取短 token
把長效 token 保存到 SharedPreferences
接口請求用長效 token 換取短token,短 token 服務端能夠根據你的接口最後一次請求做爲標示,超時時間爲一天。
全部接口都用短效 token
若是返回短效 token 失效,執行第3步,再直接當前接口
若是長效 token 失效(用戶換設備或超過一月),提示用戶登陸。複製代碼
LruCache 使用一個 LinkedHashMap 簡單的實現內存的緩存,沒有軟引用,都是強引用。
若是添加的數據大於設置的最大值,就刪除最早緩存的數據來調整內存。maxSize 是經過構造方法初始化的值,他表示這個緩存能緩存的最大值是多少。
size 在添加和移除緩存都被更新值, 他經過 safeSizeOf 這個方法更新值。 safeSizeOf 默認返回 1,但通常咱們會根據 maxSize 重寫這個方法,好比認爲 maxSize 表明是 KB 的話,那麼就以 KB 爲單位返回該項所佔的內存大小。
除異常外,首先會判斷 size 是否超過 maxSize,若是超過了就取出最早插入的緩存,若是不爲空就刪掉,並把 size 減去該項所佔的大小。這個操做將一直循環下去,直到 size 比 maxSize 小或者緩存爲空。
安裝和下載 Cygwin,下載 Android NDK。
ndk 項目中 JNI 接口的設計。
使用 C/C++實現本地方法。
JNI 生成動態連接庫.so 文件。
將動態連接庫複製到 java 工程,在 java 工程中調用,運行 java 工程便可。複製代碼
中文70(包括標點),英文160,160個字節。
使用asmark 開源框架實現的即時通信功能.該框架基於開源的 XMPP 即時通訊協議,採用 C/S 體系結構,經過 GPRS 無線網絡用 TCP 協議鏈接到服務器,以架設開源的Openfn'e 服務器做爲即時通信平臺。
客戶端基於 Android 平臺進行開發。負責初始化通訊過程,進行即時通訊時,由客戶端負責向服務器發起建立鏈接請求。系統經過 GPRS 無線網絡與 Internet 網絡創建鏈接,經過服務器實現與Android 客戶端的即時通訊腳。
服務器端則採用 Openfire 做爲服務器。 容許多個客戶端同時登陸而且併發的鏈接到一個服務器上。服務器對每一個客戶端的鏈接進行認證,對認證經過的客戶端建立會話,客戶端與服務器端之間的通訊就在該會話的上下文中進行。
對 listview 的優化。
對圖片的優化。
對內存的優化。
具體一些措施
儘可能不要使用過多的靜態類 static
數據庫使用完成後要記得關閉 cursor
廣播使用完以後要註銷複製代碼
首先來講使用http協議上傳數據,特別在android下,跟form沒什麼關係。
傳統的在web中,在form中寫文件上傳,其實瀏覽器所作的就是將咱們的數據進行解析組拼成字符串,以流的方式發送到服務器,且上傳文件用的都是POST方式,POST方式對大小沒什麼限制。
回到題目,能夠說假設每次真的只能上傳2M,那麼可能咱們只能把文件截斷,而後分別上傳了,斷點上傳。