1. 程式人生 > >android面試集錦總結二

android面試集錦總結二

android部分:
這裡的android根據面試官的水平,面試官水平高的話,會問很多原始碼級的東西,並且問的非常細,這個就沒辦法了,不過相對來說還是佔少數的,當然高大上的公司就必須做好心理準備了。現在來說一般比較常問的android技術點

首先從四大元件說起:
Activity:
生命週期:
activity三種狀態:執行(執行在最前端)、停止(不可見,完全被覆蓋)、暫停(可見,但前端還有其他activity)
生命週期相關的方法:onCreate-onStart-onResume-onPause-onStop-onDestory-onRestart
切換時如果要儲存資料, 可以重寫: onSaveInstanceState();
恢復資料時, 重寫: onRestoreInstanceState();
啟動模式:
1.standard:預設的,每次呼叫startActivity()啟動時都會建立一個新的activity放在棧頂
2.singleTop:啟動Activity時,指定Activity不在任務棧棧頂就建立,如在棧頂,則不會建立,會呼叫onNewInstance(),複用已經存在的例項。
3.singleTask:在任務棧裡面只允許一個例項,如果啟動activity不存在就建立,如果存在直接跳轉到指定Activity所在位置。
4.singleInstance:開啟一個新的任務棧來存放這個Activity的例項,此模式開啟的Activity是執行在自己單獨的任務棧中的。

2.BroadcastReceiver廣播接收者
有序廣播用過呼叫abortBroadcast()方法來中斷,接收者之間可以傳遞資料
動態註冊廣播register,取消unregister
廣播接收者開啟Activity,需要設定一下Intent.FLAG_ACTIVITY_NEW_TASK
應為廣播接收者是沒有Activity任務棧的
sendOrderBroadcast()傳送有序廣播
1)靜態註冊:在AndroidManifest.xml註冊,android不能自動銷燬廣播接收器,也就是說當應用程式關閉後,還是會接收廣播。
2)動態註冊:在程式碼中通過registerReceiver()手工註冊.當程式關閉時,該接收器也會隨之銷燬。當然,也可手工呼叫unregisterReceiver()進行銷燬。

3.Service服務
Service中的生命週期方法(Context呼叫執行):
1)startService() 如果沒建立就先onCreate()再startCommand(), 如果已建立就只執行startCommand();
2)stopService() 執行onDestroy()
3)bindService() 如果沒有建立就先onCreate()再onBind()
4)unbindService() 如果服務是在繫結時啟動的, 先執行onUnbind()再執行onDestroy(). 如果服務在繫結前已啟動, 那麼只執行onUnbind();
3、開啟服務的2種方式
2種不同開啟方式的區別:
1)startService:
開啟服務,服務一旦開啟,就長期就後臺執行,即使呼叫者退出來,服務還會長期執行;
資源不足時,被殺死,資源足夠時,又會復活;
2)bindService:
繫結服務,繫結服務的生命週期會跟呼叫者關聯起來,呼叫者退出,服務也會跟著銷燬;
通過繫結服務,可以間接的呼叫服務裡面的方法(onBind返回IBinder);
4、服務混合呼叫生命週期
一般的呼叫順序:
①、start -> stop 開啟 –> 結束
②、bind -> unbind 繫結(服務開啟) -> 解綁(服務結束)
混合呼叫:
①、start –> bind -> stop->unbind->ondestroy 通常不會使用這種模式
開啟 –> 繫結 –> 結束(服務停不了)->解除繫結(服務才可停掉)
②、start –> bind -> unbind -> stop 經常使用
開啟 –> 繫結 –> 解綁(服務繼續執行)-> stop(不用時,再停止服務)
這樣保證了服務長期後臺執行,又可以呼叫服務中的方法

4、內容提供者
這個問的非常少,但是一旦問道還是要知道怎麼回事的。
ContentProvider:
在資料庫中有對應的增刪改查的方法,如果要讓別的應用程式訪問,需要有一個路徑uri
通過content:路徑對外暴露,uri寫法:content://主機名/表名
1)ContentProvider:內容提供者
把一個應用程式的私有資料(如資料庫)資訊暴露給別的應用程式,讓別的應用程式可以訪問;
在資料庫中有對應的增刪改查的方法,如果要讓別的應用程式訪問,需要有一個路徑uri:
通過content:// 路徑對外暴露,uri寫法:content://主機名/表名
2)ContentResolver:內容解析者
根據內容提供者的路徑,對資料進行操作(crud);
3)ContentObserver:內容觀察者
可以理解成android系統包裝好的回撥,資料傳送變化時,會執行回撥中的方法;
ContentResolver傳送通知,ContentObserver監聽通知;
當A的資料發生變化的時候,A就會顯示的通知一個內容觀察者,不指定觀察者,就會發訊息給一個路徑
ContentProvider和sql的實現上的區別:
1,Contentprovider遮蔽了資料儲存的細節,內部實現對使用者完全透明,使用者只需要i、關心操作資料的uri就可以了,ContentProvider可以實現不同app之間的共享
2,Sql也有增刪改查的方法,但是sql只能查詢本應用下的資料庫。而Comtentprovider還可以去增刪改查本地檔案.xml檔案的讀取等

非同步載入網路資料(AsyncTask)
AsyncTask類,這個類中的任務是執行在後臺執行緒中的,並可以將結果放在UI執行緒中去處理
它定義了三種泛型,分別是Params、Progress和Result,分別表示請求的引數、任務的進度和獲取的結果資料
執行過程:1.onPreExecte():執行在主執行緒。這步操作是用於準備好任務的,作為任務載入的準備工作。建議在這個方法中彈出一個提示框。
2.doInBackground():執行在子執行緒中。需要將請求的引數傳遞進來,傳送給伺服器,並將獲取到的資料返回,資料回傳給下一步的onProgressUpdate()中進行進度更新。
3.onProgressUpdate():進度更新
4.onPostExectue():介面更新
實現原理:
1.執行緒池的建立:預設建立一個執行緒池ThreadPoolExecutor,並預設創建出5個執行緒放入到執行緒池中,最多可放128個執行緒,且這個執行緒池是公共的唯一一份。
2.任務的執行:執行run方法,執行完run方法後,會呼叫scheduleNext()不斷的從雙端佇列中輪詢,獲取下一個任務並繼續放到一個子執行緒中執行,直到非同步任務執行完畢。
3.訊息的處理:在AsyncTask中維護了一個InternalHandler的類,這個類是繼承Handler的,獲取的資料是通過handler進行處理和傳送的。其中handleMessage方法中,將訊息傳遞給onProgressUpdate()進行進度的更新,也可以將結果傳送到主執行緒中,進行介面的更新了。

LisView優化:
ListView如何提高其效率
1.複用ContentView
2.自定義靜態類viewholder
3.使用分頁載入
4.使用weakReference引用ImageView物件
listView可以顯示多種型別的條目:
Listview顯示的每個條目都是通過baseAdapter的getView來展示的,理論上我們完全可以讓每個條目都是不同型別的view,除此之外adapter還提供了getViewTypeCount()和getItemViewType(int position)兩個方法。在getview方法中我們可以根據不同的viewtype載入不同的佈局檔案。

ListView中的資料分批及分頁載入:
設定ListView的滾動監聽器:setOnScrollListener
1.在監聽器中有兩個方法:滾動狀態發生變化的方法onScrollStateChanged和listView被滾動時呼叫的方法
2.在滾動狀態發生改變的方法有三個狀態:觸控滑動、慣性滾動、靜止狀態
3.對不同的狀態進行處理:分批載入資料,只關心靜止狀態:如果最後一個可見條目就是資料適

配器裡的最後一個,此時可載入更多的資料。

ListView圖片優化
1.不要直接拿路徑去迴圈decodeFile();使用Option儲存圖片大小,不要載入圖片到記憶體
2.拿到圖片一定要經過邊界壓縮
3.在listView去圖片是也不要直接拿個路徑去取圖片,而是以WeakReference代替強引用
4.在getView中做圖片轉換時,產生的中間變數一定及時釋放
非同步載入圖片基本思想:
1.先從記憶體快取中獲取圖片顯示(記憶體緩衝)
2.獲取不到的話從SD卡里獲取(SD卡快取)
3.都獲取不到的話從網路下載圖片並儲存到SD卡同時加入記憶體並顯示
圖片錯位問題:
本質是因為listView使用了快取convertView。可見則顯示,不可見則不顯示。在imageLoader裡有個imageViews的map物件,用於儲存當前顯示區域影象對應的url集,在顯示前判斷處理一下即可。
記憶體緩衝機制:
首先限制記憶體圖片緩衝的堆記憶體大小,每次有圖片往快取里加時判斷是否超過限制大小,超過的話取最少使用的圖片並將其移除
二級快取:從LinkedHashMap裡移除的快取放在SoftReference裡
LinkedHashMap快取在沒有移除出去之前是不會被GC回收的,而SoftRefernce裡的圖片快取在沒有其他引用儲存時隨時都會被GC回收。
ListView的其他優化:
1.儘量避免在BaseAdapter中使用static來定義全域性靜態變數
2.儘量使用getApplicationContext
3.儘量避免在ListView介面卡中使用執行緒

ScrollView和ListView的衝突問題:
在ScrollView新增ListView會導致listView控制元件顯示不全,兩個控制元件的滾動事件衝突導致。通過listView中的item數量去計算listView的顯示高度。

熟悉XML/Json解析資料,以及資料儲存方式
資料儲存方式包括:File、SharedPreference、XML/Json、資料庫、網路
XML/Json解析資料

Handler機制和事件分發機制
Message:訊息,由MessageQueue統一列隊,終由Handler處理
Handler:處理者,負責Message傳送訊息及處理。Handler通過與Looper進行溝通,從而使用Handler時,需要實現handlerMessage方法來對特定的Message進行處理
MessageQuene:訊息佇列,用來存放Handler傳送過來的訊息,按照先入先出規則執行。
Looper:訊息泵,不斷從MessageQueue中取出Message執行。因此,一個執行緒中的MessaeQueue需要一個Looper進行管理。
耗時操作,比如網路請求、檔案處理、多媒體處理需要在子執行緒中操作,手機顯示的重新整理頻率60Hz,一秒鐘重新整理60次,沒16.7毫秒重新整理一次,為了不丟幀,主執行緒處理程式碼最好不要超過16毫秒。
Handler訊息機制
在主執行緒中 Android 預設已經呼叫了 Looper.preper()方法,呼叫該方法的目的是在 Looper 中建立MessageQueue 成員變數並把 Looper 物件繫結到當前執行緒中。當呼叫 Handler 的 sendMessage(物件)方法的時
候就將 Message 物件新增到了 Looper 建立的 MessageQueue 佇列中,同時給 Message 指定了 target 物件,其實這個 target 物件就是 Handler 物件。主執行緒預設執行了 Looper.looper()方法,該方法從 Looper 的成員變數MessageQueue 中取出 Message,然後呼叫 Message 的 target 物件的 handleMessage()方法。這樣就完成了整個訊息機制。

事件分發機制
onTouch和onTouchEvent
這兩個方法都是在View的dispathTouchEvent中呼叫的,onTouch優先於onTouchEvent執行,在onTouch中返回true將事件消費掉,onTouchEvent將不會再執行。
依次下發,下發的過程是呼叫View的dispatchTouchEvent方法實現的。簡單來說,就是viewgroup遍歷包含者的子view,呼叫每個View的dispatchTouchEvent方法,而當子view為viewgroup時,又會呼叫viewgroup的dispatchTouchEvent方法繼續呼叫內部的view的dispatchTouchEvent方法。
touch事件分發有兩個主角:viewGroup和view。
viewgroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent
view包含dispatchTouchEvent、onTouchEvent兩個
onInterceptTouchEvent有兩個作用:1.攔截down事件的分發 2.中止Up和move事件向目標view傳遞,使得目標view所在的viewgroup捕獲up和move事件
觸控事件是有action_Down、Action_Move、Action_Up組成,其中一次完整的觸
摸事件中,Down和Up都只有一個,Move有若干個,可以為0個。

自定義控制元件
1.自定義組合控制元件
宣告一個view物件,繼承相對佈局,或者線性佈局或者其他的viewGroup
在自定義的view物件裡面重寫它的構造方法,在構造方法裡面把佈局初始化
根據業務需要新增一些api方法,擴充套件自定義組合控制元件
在佈局檔案裡面可以自定義一些屬性
宣告自定義屬性的名稱空間
在res目錄下的values目錄下建立attrs.xml的檔案宣告我們寫的屬性
在佈局檔案中寫自定義的屬性
使用自定義的屬性
2.view的繪製過程
mesarue()過程:為整個view樹計算實際的大小
view : mMeasuredHeight高和mMeasureWidth()寬
viewGroup:重寫onMeasure()方法,遍歷measure()過程,通過呼叫父類ViewGroup類裡面的measureChildWithMargins()方法去實現
layout()根據子檢視的大小以及佈局引數將view樹放到合適的位置上
view: 設定該view檢視位於父檢視的座標抽即mLeft,mTop,mLeft,mBottom,回撥onLayout方法
viewGroup:遍歷每個子檢視childView,呼叫該子檢視的layout()方法去設定它的座標值
3.draw()繪製過程
viewRoot物件的performTraversals()方法呼叫draw()方法發起繪製view樹不需要全部重繪只需要繪製需要繪製的部分

這個控制元件中,父檢視使用unspecified dimensions來將它的每個子檢視都測量一次來算出它們到底需要多大尺寸,而這些子檢視沒被限制的尺寸的和太大或太小,所以會用精確數值再次呼叫measure()(也就是說,如果子檢視不滿意它們獲得的區域大小,那麼父檢視將會干涉並設定第二次測量規則)。其中measure()方法會呼叫onMeasure()方法。
程式碼中,由於把每行剩餘空間重新分配,會呼叫了requestLayout()方法,這個方法又會導致measure()和onLayout()方法的再次呼叫。
最後你會發現 onMeasure()方法呼叫了 1次*2*2=4次 onLayout()方法呼叫了 1次*2 =2次

談一談android的安全機制
1,在安卓是有檔案許可權的控制,在清單檔案宣告
2,每個android中每個應用都有自己的/data/data/包名 資料夾,該資料夾只能該應用訪問,而其他應用則無權訪問
3,Android的程式碼混淆保護了開發者的勞動成果

多執行緒斷點續傳下載
多執行緒下載的實現過程:
1,首先得到下載檔案的長度,然後設定本地檔案的長度。
HttpURLConnection.getContentLength();
RandomAccessFile file = new RandomAccessFile(“FeiQ.exe”,”rwd”);
file.setLength(filesize); //設定本地檔案的長度
2,根據檔案長度和執行緒數計算每條執行緒下載的資料長度和下載位置。
如:檔案的長度為6M,執行緒數為3,那麼,每條執行緒下載的資料長度為2M,每條執行緒開始下載的位置如圖所示。
3,使用Http的Range頭欄位指定每條執行緒從檔案的什麼位置開始下載,下載到什麼位置為止.
如:指定從檔案的2M位置開始下載,下載到位置4M為止,程式碼如下:
HttpURLConnection.setRequestProperty(“Range”, “bytes=2097152-4194303”);
4,儲存檔案
使用RandomAccessFile類指定每條執行緒從本地檔案的什麼位置開始寫入資料。
RandomAccessFile threadfile = new RandomAccessFile(“QQWubiSetup.exe “,”rwd”);
threadfile.seek(2097152); //從檔案的什麼位置開始寫入資料

資料庫操作
在Android系統,提供了一個SQLiteOpenHelper抽象類,該類用於對資料庫版本進行管理.該類中常用的方法:
onCreate 資料庫建立時執行(第一次連接獲取資料庫物件時執行)
onUpgrade 資料庫更新時執行(版本號改變時執行)
onOpen 資料庫每次開啟時執行(每次開啟資料庫時呼叫,在 onCreate,onUpgrade方法之後)
Android提供了一個名為SQLiteDatabase的類,該類封裝了一些操作資料庫的API,使用該類可以完成對資料進行新增(Create)、查詢(Retrieve)、更新(Update)和刪除(Delete)操作(這些操作簡稱為CRUD)。對SQLiteDatabase的學習,我們應該重點掌握execSQL()和rawQuery()方法。 execSQL()方法可以執行insert、delete、update和CREATE TABLE之類有更改行為的SQL語句; rawQuery()方法用於執行select語句。

aidl:介面宣告語言,跨程序通訊
bindService有一個ServiceConnec介面覆寫onServiceConnect方法,把第二個引數IBinder物件強制轉換為aidl中的介面類

- 寫服務類

    1. 定義一個介面檔案, 宣告一個方法forwardPayMoney方法, 把字尾名修改為.aidl, 並且把修飾詞去掉. 

    2. 在服務中定義一個內部類MyBinder, 繼承Stub類, 並且把抽象方法forwardPayMoney實現了.

    3. 在onBind方法中把第二部定義的內部類物件MyBinder返回.

- 另一個程式的Activity

    4. 使用隱式的方式繫結服務, 傳遞過去一個連線橋物件.

    5. 把服務程式中的aidl檔案拷貝當前工程中, 包名要保留一致.

    6. 在連線橋物件中的onServiceConnected方法中, 把IBinder物件轉換成aidl介面物件

            mAlipayRemoteService = Stub.asInterface(service);

    7. 使用aidl介面物件, 呼叫介面中的抽象方法, 實際上會呼叫到遠端服務中內部類中的forwardPayMoney方法.

android中的動畫
1.View Animation: 檢視動畫/ Frame動畫/屬性動畫:這種動畫是可擴充套件的,

圖片處理框架
imageLoader:imageLoaderEngine,cache及
imageDownloader,imageDecoder,bitmaodisplayer,bitmapProcessor五大模組
簡單來說就是imageLoader收到載入及顯示圖片的任務,並將它交給
imageLoaderEngine,ImageLoaderEngine分發任務到具體執行緒池去執行,任務通過cache及imageDownloder獲取圖片。
優點:1,支援下載監聽2,可以在view滾動中暫停圖片載入3.預設實現多種記憶體快取演算法4.支援本地快取檔名規則定義
picasso
這個庫分為dispatcher/requestHandler及Downloader,picassoDrawable等模組
picasso收到載入及顯示圖片的任務,建立Request並將他交給
Dispatcher,dispatcher分發任務到具體的requesthandler,任務memoryCache及Handler獲取圖片,圖片獲取成功後通過picassoDrawable顯示到Target中
優點:1.自帶統計監控功能2.支援優先順序處理3.支援延遲載入4.支援飛航模式、併發執行緒數根據網路型別而變

圖片快取處理:
LruCache類:主要演算法原理是把最近使用的物件用強引用儲存在在LinkedHashMap中,並且把最近最少使用的物件在快取值達到預定值之前從記憶體中移除。

記憶體溢位原因:
1.資源釋放問題
2.物件記憶體過大
3.static
4.執行緒導致記憶體溢位

圖片佔用程序的記憶體演算法簡介
android中處理圖片的基礎類是Bitmap,顧名思義,就是點陣圖。佔用記憶體的演算法如下:
圖片的width*height*Config。
如果Config設定為ARGB_8888,那麼上面的Config就是4。一張480*320的圖片佔用的記憶體就是480*320*4 byte。
在預設情況下android程序的記憶體佔用量為16M,因為Bitmap除了java中持有資料外,底層C++的 skia圖形庫還會持有一個SKBitmap物件,因此一般圖片佔用記憶體推薦大小應該不超過8M。這個可以調整,編譯原始碼時可以設定引數。

Activity的啟動與生命週期的監控
應用程式被開啟後,是需要開啟並建立Activity,載入相應的view,從而展示出應用程式
1、Activity是通過startActivity開啟起來的,startActivity是由有Context呼叫的,其具體的實現類是ContextImpl
在ContextImpl中的startActivity方法中,會呼叫ActivityThread的相關方法【mMainThread.getInstrumentation().execStartActivity()】;可以追溯到Instrumentation這個類,其中的execStartActivity()的方法中實現了startActivity的呼叫:ActivityManagerNative.getDefault().startActivity,由此可以看出是底層進行處理。
2、ActivityMonitor監控Activity
當Activity例項建立的時候,就會給Activity配置一個監視器ActivityMonitor,監控Activity的宣告週期:
在Instrumentation的execStartActivity()的方法中,上來先判斷ActivityMonitor是否為null:在第一次開啟Activity的時候,ActivityMonitor還是null的,就會呼叫ActivityManagerNative.getDefault().startActivity(…..),是在操作native底層的資訊,從而執行startActivity,再去開啟一個Activity。
簡單來說,就是通過呼叫JNI,呼叫startActivity方法,開啟Activity;建立好了之後,隨即也建立好了Activity的監視器ActivityMonitor
3、在ActivityMonitor中就有Activity各種生命週期的監控
①、在newActivity方法中:
可以通過拿到Activity的位元組碼,建立一個Activity,並將這個Activity返回
還會呼叫attach方法,傳入ActivityThread的執行緒
②、在各種生命週期的方法中,呼叫activity的各自的生命週期的方法

總結:
1、通過PackageManagerService將所有用到的資源載入進記憶體中
2、在Launcher中,將view等控制元件載入到ViewGroup中,點選每個item會有相應的操作
3、在公開的文件中是找不到具體呼叫startActivity的類的,而是由系統完成呼叫的,實現了Activity的啟動
實際就是通過Context的實現類ContextImpl進行呼叫的,一步步轉到底層(ActivityManagerNative)實現呼叫
4、另一個重要的類就是ActivityMonitor,監控Activity生命週期的;在其newActivity方法中建立了Activity,並呼叫了attach方法;
也就是說當一個Activity被建立的時候,就會繫結一個ActivityMonitor,用來監控Activity的生命週期

沉浸式狀態列實現思路
首先看下第一種方式
系統的方式沉浸式狀態列實現
步奏一
//當系統版本為4.4或者4.4以上時可以使用沉浸式狀態列
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明狀態列
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明導航欄
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
步奏二
佈局加入: android:fitsSystemWindows=”true” android:clipToPadding=”true”
我們看下activity和佈局檔案
FirstActivity.java:
/**
* 沉浸式狀態列
*/
private void initState() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明狀態列
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明導航欄
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}

activity_first.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:fitsSystemWindows="true"
        android:clipToPadding="true"
        android:layout_width="match_parent"
        android:layout_height="140dp"
        android:textSize="24dp"
        android:background="@color/mask_tags_1"
        android:text="你好,沉浸式狀態列"/>
</LinearLayout>

實現思路,新增隱藏佈局,然後我們動態的計算狀態列的高度,然後把這個高度設定成這個隱藏的佈局的高度,便可以實現
在這裡我們通過反射來獲取狀態列的高度

/**
     * 通過反射的方式獲取狀態列高度
     *
     * @return
     */
    private int getStatusBarHeight() {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

ViewFilpper類和ViewPager的區別
1.ViewFilpper類繼承於ViewAnimator類。而ViewAnimator類繼承於FrameLayout。
檢視ViewAnimator類的原始碼可以看出此類的作用主要是為其中的View切換提供動畫效果。該類有如下幾個和動畫相關的方法。
2.ViewPager用於實現多頁面的切換效果,該類存在於Google的相容包裡面,所以在引用時記得在BuilldPath中加入“Android-support-v4.jar”

單例模式:

餓漢式:
public class Singleton {
// 直接建立物件
public static Singleton instance = new Singleton();
// 私有化建構函式
private Singleton() {
}
// 返回物件例項
public static Singleton getInstance() {
return instance;
}
}
懶漢式:
public class Singleton {
// 宣告變數
private static volatile Singleton singleton = null;
// 私有建構函式
private Singleton() {
}
// 提供對外方法
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}

SQLite可以解析大部分標準SQL語句,如:
查詢語句:select * from 表名 where 條件子句 group by 分組字句 having … order by 排序子句

如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1

分頁SQL與MySQL類似,下面SQL語句獲取5條記錄,跳過前面3條記錄

select * from Account limit 5 offset 3 或者 select * from Account limit 3,5

插入語句:insert into 表名(欄位列表) values(值列表)。如: insert into person(name, age) values(‘工工’,3)
更新語句:update 表名 set 欄位名=值 where 條件子句。如:update person set name=‘工‘ where id=10
刪除語句:delete from 表名 where 條件子句。如:delete from person where id=10

支付
匯入jar
將demo裡面的alipaySdk-20160223.jar拷貝到我們工程的libs下,並新增到依賴中
配置
許可權





activity

String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
/**
 * 特別注意,這裡的簽名邏輯需要放在服務端,切勿將私鑰洩露在程式碼中!
 */
String sign = sign(orderInfo);try {
    /**
     * 僅需對sign 做URL編碼
     */
    sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
/**
 * 完整的符合支付寶引數規範的訂單資訊
 */final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();

Runnable payRunnable = new Runnable() {

    @Override
    public void run() {
        // 構造PayTask 物件
        PayTask alipay = new PayTask(MainActivity.this);
        // 呼叫支付介面,獲取支付結果
        String result = alipay.pay(payInfo, true);

        Message msg = new Message();
        msg.what = SDK_PAY_FLAG;
        msg.obj = result;
        mHandler.sendMessage(msg);
    }
};
// 必須非同步呼叫
Thread payThread = new Thread(payRunnable);
payThread.start();

處理支付結果

@SuppressLint("HandlerLeak")private Handler mHandler = new Handler() {
    @SuppressWarnings("unused")
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) msg.obj);
                /**
                 * 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/
                 * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
                 * docType=1) 建議商戶依賴非同步通知
                 */
                String resultInfo = payResult.getResult();// 同步返回需要驗證的資訊

                String resultStatus = payResult.getResultStatus();
                // 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考介面文件
                if (TextUtils.equals(resultStatus, "9000")) {
                    Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                } else {
                    // 判斷resultStatus 為非"9000"則代表可能支付失敗
                    // "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端非同步通知為準(小概率狀態)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(MainActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show();

                    } else {
                        // 其他值就可以判斷為支付失敗,包括使用者主動取消支付,或者系統返回的錯誤
                        Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();

                    }
                }
                break;
            }
            default:
                break;
        }
    }

};

這裡支付成功了,只是提示使用者,還得從伺服器確認是否正在支付了,我這裡只寫了本地,其他如果在服務端實現是一樣的,你把這程式碼直接發給後端就行了(如果後端是Java開發),可以看到我們已經成功調起支付寶服務了

JSON解析
android的json解析部分都在包org.json下,主要有以下幾個類:
JSONObject:可以看作是一個json物件,這是系統中有關JSON定義的基本單元,其包含一對兒(Key/Value)數值。它對外部(External: 應用toString()方法輸出的數值)呼叫的響應體現為一個標準的字串(例如:{“JSON”: “Hello, World”},最外被大括號包裹,其中的Key和Value被冒號”:”分隔)。其對於內部(Internal)行為的操作格式略微,例如:初始化一個JSONObject例項,引用內部的put()方法新增數值:new JSONObject().put(“JSON”, “Hello, World!”),在Key和Value之間是以逗號”,”分隔。Value的型別包括:Boolean、JSONArray、JSONObject、Number、String或者預設值JSONObject.NULL object 。
JSONStringer:json文字構建類 ,根據官方的解釋,這個類可以幫助快速和便捷的建立JSON text。其最大的優點在於可以減少由於 格式的錯誤導致程式異常,引用這個類可以自動嚴格按照JSON語法規則(syntax rules)建立JSON text。每個JSONStringer實體只能對應建立一個JSON text。。其最大的優點在於可以減少由於格式的錯誤導致程式異常,引用這個類可以自動嚴格按照JSON語法規則(syntax rules)建立JSON text。每個JSONStringer實體只能對應建立一個JSON text。
JSONArray:它代表一組有序的數值。將其轉換為String輸出(toString)所表現的形式是用方括號包裹,數值以逗號”,”分隔(例如: [value1,value2,value3],大家可以親自利用簡短的程式碼更加直觀的瞭解其格式)。這個類的內部同樣具有查詢行為, get()和opt()兩種方法都可以通過index索引返回指定的數值,put()方法用來新增或者替換數值。同樣這個類的value型別可以包括:Boolean、JSONArray、JSONObject、Number、String或者預設值JSONObject.NULL object。
JSONTokener:json解析類
JSONException:json中用到的異常

android中裡的HTML網頁裡點選某一按鈕或某一位置直接跳轉某一Activty裡去
廢話不多說,這次教程的目標如下
1.android 中的java程式碼呼叫webview裡面的js指令碼
2.webview中的js指令碼呼叫本地的java程式碼
3.java呼叫js並傳遞引數
4.js呼叫java並傳遞引數
2、建立Activty,在Activty的onCreate裡實現三個步驟:
· //第一步:webview支援script指令碼
· WebSettings webSetting = mWebHtml.getSettings();
· webSetting.setJavaScriptEnabled(true);
· //第二步:定義互動類與方法
· final class ServiceJavaScriptInterface {
· ServiceJavaScriptInterface() {
· }
· public void startGridViewHttp() {
· //跳轉到介面
· startActivity(new Intent(WebHtml.this, Gridmview.class));
· }
}
· //第三步:新增script介面
mWebHtml.addJavascriptInterface(
new ServiceJavaScriptInterface(),”musicServiceInterfaceName”);
}
3、在head裡寫一個取名yun(任意取)的方法名:
function yun(){
window.musicServiceInterfaceName.startGridViewHttp();
}
4.這時必須在HTML裡設定點選監聽:

<img src="./img/index_yaoqinghan.png" onclick="yun()"/> 

Eventbus
。EventBus是一款針對Android優化的釋出/訂閱事件匯流排。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,執行緒之間傳遞訊息.優點是開銷小,程式碼更優雅。以及將傳送者和接收者解耦。
2、基本使用
(1)自定義一個類,可以是空類,比如:
(2)在要接收訊息的頁面註冊:
(3)傳送訊息
(4)接受訊息的頁面實現(共有四個函式,各功能不同,這是其中之一,可以選擇性的實現,這裡先實現一個):
1、onEvent
2、onEventMainThread
3、onEventBackgroundThread
4、onEventAsync
(5)解除註冊

Rxjava
RxJava 的非同步實現,是通過一種擴充套件的觀察者模式來實現的。
RxJava 的觀察者模式
它就是一個實現非同步操作的庫
RxJava 有四個基本概念:Observable (可觀察者,即被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件。Observable 和Observer 通過 subscribe() 方法實現訂閱關係,從而 Observable 可以在需要的時候發出事件來通知 Observer。
與傳統觀察者模式不同, RxJava 的事件回撥方法除了普通事件 onNext() (相當於 onClick() / onEvent())之外,還定義了兩個特殊的事件:onCompleted() 和 onError()。
onCompleted(): 事件佇列完結。RxJava 不僅把每個事件單獨處理,還會把它們看做一個佇列。RxJava 規定,當不會再有新的onNext() 發出時,需要觸發 onCompleted() 方法作為標誌。
onError(): 事件佇列異常。在事件處理過程中出異常時,onError() 會被觸發,同時佇列自動終止,不允許再有事件發出。
在一個正確執行的事件序列中, onCompleted() 和 onError() 有且只有一個,並且是事件序列中的最後一個。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在佇列中呼叫了其中一個,就不應該再呼叫另一個。
2. 基本實現
基於以上的概念, RxJava 的基本實現主要有三點:
1) 建立 Observer
Observer 即觀察者,它決定事件觸發的時候將有怎樣的行為
2) 建立 Observable
Observable 即被觀察者,它決定什麼時候觸發事件以及觸發怎樣的事件
3) Subscribe (訂閱)
建立了 Observable 和 Observer 之後,再用 subscribe() 方法將它們聯結起來,整條鏈子就可以工作了。

MVC模式
View:對應於佈局檔案
Model:業務邏輯和實體模型
Controllor:對應於Activity
MVP模式
View 對應於Activity,負責View的繪製以及與使用者互動
Model 依然是業務邏輯和實體模型
Presenter 負責完成View於Model間的互動

RecyclerView可以通過匯入support-v7對其進行使用。
據官方的介紹,該控制元件用於在有限的視窗中展示大量資料集
通過設定它提供的不同LayoutManager,ItemDecoration , ItemAnimator
你想要控制其顯示的方式,請通過佈局管理器LayoutManager
你想要控制Item間的間隔(可繪製),請通過ItemDecoration
你想要控制Item增刪的動畫,請通過ItemAnimator
你想要控制點選、長按事件,請自己寫(擦,這點尼瑪。)
系統沒有提供ClickListener和LongClickListener。
實現的方式比較多,你可以通過mRecyclerView.addOnItemTouchListener去監聽然後去判斷手勢,
當然你也可以通過adapter中自己去提供回撥

還有很多技術點,再有時間補充,暫時就這些。

相關推薦

android面試集錦總結

android部分: 這裡的android根據面試官的水平,面試官水平高的話,會問很多原始碼級的東西,並且問的非常細,這個就沒辦法了,不過相對來說還是佔少數的,當然高大上的公司就必須做好心理準備了。現在來說一般比較常問的android技術點 首先從四大元件說

js面試試題總結

任務 緩存 穩定 session state cal 後臺 前端 list js 實現 ajax 請求 var Ajax={ get: function(url, fn) { var obj = new XMLHttpRequest(); // X

面試問題總結(技術能力-PHP)----Ⅲ

man var_dump 創建索引 獲得 target 簡單 也不能 兩個 錯誤 42、什麽是單點登錄? 答:單點登錄 SSO(Single Sign On)說得簡單點就是在一個多系統共存的環境下,用戶在一處登錄後,就不用在其他系統中登錄,也就是用戶的一次登錄能得到其他所有

Android面試集錦之Activity(知識整理)

面試集錦是參考了慕課網BAT某大神的視訊。 本文分為四個部分: 1.Activity生命週期 2.Activity任務棧 3.Activity啟動模式 4.scheme跳轉協議 一、Activity的生命週期 什麼是Activity? android與使用者進行互動的時候,

Android面試集錦之Service(知識整理)

本文主要講解兩個部分: 一、service的應用場景,以及和Thread的區別 二、開啟service的兩種方式以及區別 第一部分又可以分為: Service基礎: 1.Service是什麼? Service是一種可以在後臺執行長時間執行操作而沒有使用者介面的應用元件。 可

Android面試集錦之Fragment(知識整理)

一、Fragment為什麼被稱為第五大元件 使用頻率高,ui切換效果好,更節省記憶體,因為其有自己的生命週期,所以也算不到四大元件裡取;fragment必須依附於activity存在。 二、Fragment載入到activity中的兩個方式 靜態載入,動態載入,(太基礎了不說了) 三

Android 面試經歷總結

準備工作主要是明確自己想要加入的公司,並開始做技術準備。目標公司是BAT,我需要到更大的平臺和更優秀的人做更好的專案,正常來說加入BAT以後可以讓自己的實力和眼界得到提升,並且有一線大廠的光環對以後都是蠻重要的。有人說去哪裡都一樣,去了大廠也是個螺絲釘,我想說我寧願做航空母艦

Android問題集錦十八:You need to use a Theme.AppCompat theme (or descendant) with this activity.

錯誤描述為:java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.起因:我想在Manifest中設定我的activ

Eclipse除錯Android工具集錦-DDMS

本文章的前提:已經安裝了Eclipse和ADT。android SDK也下載完畢。Eclipse裡面已經設定好了andro本文章的前id SDK。 本文章將系統的介紹Android除錯的各個工具。講的會比較細,希望對大家有所幫助。 DDMS Android SDK單獨

Android常見問題總結

時長 加載 col gen try pla 下載 pro 屬性 1、布局文件LinearLayout線性布局添加內容報錯。解決方法:線性布局LinearLayout中包裹的元素多余1個需要添加android:orientation屬性。 2、android 的應用APP怎麽

Android面試收集錄16 Android動畫總結

ont 定義 其中 自定義動畫 替代 通過 1.0 日誌 action 一、Android 動畫分類 總的來說,Android動畫可以分為兩類,最初的傳統動畫和Android3.0 之後出現的屬性動畫; 傳統動畫又包括 幀動畫(Frame Animation)和補

java 面試基礎總結)---多線程

future sync 一個 副本 void all call ava task 1、實現多線程的三種方法 1.繼成Thread 類,覆蓋run()方法即可 2.implements Runnable接口 3.implements Callale接口,執行時通過Future

Android TV開發總結)構建一個TV Metro界面(仿泰捷視頻TV版)

alt 軟件 XML 的區別 微信 Edito pretty web 效果 原文:Android TV開發總結(二)構建一個TV Metro界面(仿泰捷視頻TV版) 版權聲明:我已委托“維權騎士”(rightknights.com)為我的文章

今年Android面試的經歷總結

此文希望能給那些想跳槽的朋友一些參考。 隨著工作時間的增加和技術經驗的積累。原先的公司不一定能提供給你想要的發展空間與前景。說直接點,家裡還有老婆孩子還有老父母,我們需要更高的薪酬讓他們過上更好的生活。所以跳槽是個不錯的選擇。 夏末的時候我就有了跳槽的想法。然後就是不斷的跑了很多家公司面試。前後花了將近兩

今年Android面試經歷的一些總結

此文希望能給想跳槽的朋友一些參考。 我們隨著工作時間的增加和技術經驗的積累。原先的公司不一定能技術提供給你想要的發展空間與前景。說直白點,家裡還有老婆孩子還有老父母,我們需要更高的薪酬讓他們過上更好的日子。所以跳槽是個不錯的選擇。 夏末的時候我就有了跳槽的想法。然後就是不斷的跑了很多家公司面

今年Android面試的一些經歷總結

此文希望能給那些想跳槽的朋友一些參考。 我們隨著工作時間的增加和技術經驗的積累。原先的公司不一定能提供給你想要的發展空間與前景。說直接點,家裡還有老婆孩子還有老父母,我們需要更高的薪酬來讓他們過上更好的生活。所以跳槽是個不錯的選擇。 夏末的時候我就有了跳槽的想法。然後就是不斷的跑了很多家公司面試。前後

Java阿里面試:一面+面+三面+HR四面,我的覆盤經驗總結

阿里中介軟體團隊一面: 第一步先自我介紹? 介紹自己的專案經驗和個人的擅長點,面試官主要考察你的表達能力和語言精簡能力。 第二步:專案中做了什麼,難點在哪裡? 主要是想了解參與過技術難度最大的專案難點,技術難點在哪裡,你是怎麼來解決的,考察專案經驗(技術難度)。 第三步:開始切入

面試總結--()

  說說我的第二次面試經歷吧,過程沒什麼多大的波折,這次的公司是直接拿你的簡歷直接技術面。有點搞笑的是面試官拿出手機網上搜問題來問我,不過看他樣子是一個技術人員。他看我是計算機專業,就說問你關於計算機專業方面的兩個問題,每個問題給你5秒鐘回答。第一個是7的二進位

Android面試總結--Android

Activity生命週期 圖中需要注意一下幾點: 1.Activity例項是由系統自動建立,並在不同的狀態期間回撥相應的方法。一個最簡單的完整的Activity生命週期會按照如下順序回撥:onCreate -> onStart -> onResum

Android問題集錦之三十 Failure INSTALL FAILED NO MATCHING ABIS

                     這個問題出現在模擬器上的概率更大些,原因是某些應用使用了原生庫(NDK,Native Lib),這些庫的編譯目標通常是arm架構的cpu,在x86上執行就會報這樣的錯誤。 比如我看了一下報錯的應用,果然有很多so在lib下。$ ls lib/armeabi/libap