(一)Android面試題(一)Activity、Intent
Android四大組件分別是哪些?各自有什么作用和特點(diǎn)?
答:
活動(dòng)(Activity):Activity是Android程序與用戶(hù)交互的窗口,是Android構(gòu)造中最基本的一種,它需要為保持各界面的狀態(tài),做很多持久化的事情,妥善管理生命周期以及一些跳轉(zhuǎn)邏輯。
服務(wù)(Service):后臺(tái)服務(wù)于Activity,封裝有一個(gè)完整的功能邏輯實(shí)現(xiàn),接受上層指令,完成相關(guān)的事務(wù),定義好需要接受的Intent提供同步和異步接口。
內(nèi)容提供者(Content Provider):是Android提供的第三方應(yīng)用數(shù)據(jù)的訪(fǎng)問(wèn)方案,可以派生Content Provider類(lèi),對(duì)外提供數(shù)據(jù),可以像數(shù)據(jù)庫(kù)一樣進(jìn)行選擇排序,屏蔽內(nèi)部數(shù)據(jù)的存儲(chǔ)細(xì)節(jié),向外提供統(tǒng)一的接口模型,大大簡(jiǎn)化上層應(yīng)用,對(duì)數(shù)據(jù)的整合提供了更方便的途徑。
廣播接收器(BroadCast Receiver):接受一種或者多種Intent作觸發(fā)時(shí)間,接受相關(guān)消息,做一些簡(jiǎn)單處理,轉(zhuǎn)換成一條Notification,統(tǒng)一了Android的事件廣播模型。(如接受系統(tǒng)通知,向通知欄發(fā)送消息)Activity的生命周期函數(shù)有哪些?點(diǎn)擊HOME鍵、BACK鍵等操作時(shí),生命周期函數(shù)如何遷移?
答:
onCreate // 創(chuàng)建Act實(shí)例時(shí)調(diào)用。通常進(jìn)行一些數(shù)據(jù)的初始化,比如獲取控件、申請(qǐng)數(shù)組或集合的內(nèi)存、變量賦值
onRestart // Act停留在onStop但是沒(méi)有onDestory
onStart // 該方法在onCreate或者onRestart之后調(diào)用,調(diào)用之后,Act進(jìn)入可視生命周期
onResume // onStart之后調(diào)用,調(diào)用該方法后Act進(jìn)入活動(dòng)(運(yùn)行、前臺(tái))狀態(tài),可以和用戶(hù)進(jìn)行交互,比如響應(yīng)用戶(hù)的輸入、點(diǎn)擊、觸摸等操作
onPause // 在onResume之后,調(diào)用該方法,此Act就不能繼續(xù)和用戶(hù)交互,用戶(hù)自定義的一些數(shù)據(jù)可以在此方法中進(jìn)行保存
onStop // onPause之后進(jìn)行調(diào)用,一旦調(diào)用onStop,Act就退出了可視狀態(tài),但是Act實(shí)例并沒(méi)有銷(xiāo)毀
onDestroy // 此方法是在銷(xiāo)毀Act的時(shí)候調(diào)用,一旦調(diào)用表明該Act實(shí)例的生命周期就結(jié)束了,通常會(huì)在此方法做一些釋放資源的操作,比如將引用變量值置為nullActivity的四種加載(啟動(dòng))模式分別是?各自有什么特點(diǎn)?
答:
standard:特點(diǎn)是每一次啟動(dòng)該Act時(shí),會(huì)重建一個(gè)新的該Act實(shí)例
singleTop:特點(diǎn)是每一次該Act時(shí),檢查棧頂是否存在該Act的實(shí)例
存在:則直接重用該Act實(shí)例
不存在:則需要新建一個(gè)該Act的實(shí)例
singleTask:特點(diǎn)是每一次啟動(dòng)該Act時(shí),需要在棧中去檢查棧中是否存在該Act的實(shí)例
存在:
在棧頂:直接復(fù)用該Act的實(shí)例
不在棧頂:首先要把其上的Act實(shí)例移除掉,使該Act的實(shí)例回到棧頂去,然后再?gòu)?fù)用該Act的實(shí)例
不存在:新建一個(gè)該Act的實(shí)例
singleInstance:看進(jìn)程中是否有該Act實(shí)例
存在:直接從該獨(dú)享?xiàng)V腥〕鲈揂ct的實(shí)例復(fù)用
不存在:新建一個(gè)棧,然后新建一個(gè)該Act的實(shí)例,放入該棧中
注意:如果把程序入口MainAct的Act設(shè)置為singleInstance時(shí),通過(guò)該Act啟動(dòng)了別的Act(SecondAct),再由其他 (SecondAct)啟動(dòng)ThirdAct,在ThirdAct中啟動(dòng)MainAct,由MainAct再去啟動(dòng)SecondAct時(shí),不會(huì)產(chǎn)生第四個(gè)實(shí)例只是把MainAct所在的棧切換到SecondAct所在的棧,把棧頂?shù)腁ct實(shí)例展示出來(lái)Activity意外退出時(shí),如何進(jìn)行數(shù)據(jù)保存和恢復(fù)?
答:
開(kāi)發(fā)者提前可以復(fù)寫(xiě)onSaveInstanceState方法,創(chuàng)建一個(gè)Bundle類(lèi)型的參數(shù),把數(shù)據(jù)存儲(chǔ)在這個(gè)Bundle對(duì)象中,這樣即使Activity意外退出,Activity被系統(tǒng)摧毀,當(dāng)重新啟動(dòng)這個(gè)Activity而調(diào)用onCreate方法時(shí),上述Bundle對(duì)象會(huì)作為參數(shù)傳遞給onCreate方法,開(kāi)發(fā)者可以從Bundle對(duì)象中取出保存的數(shù)據(jù),利用這些數(shù)據(jù)將Activity恢復(fù)到被摧毀之前的狀態(tài)。Intent是什么?有什么用處?
答:
Intent(意圖):作用是調(diào)用某個(gè)組件去做一個(gè)事情,它既能充當(dāng)橋梁的角色,也能傳遞數(shù)據(jù)。Intent如何傳值?Bundle是什么,有什么用?
答:Intent的傳值:通過(guò)Intent類(lèi)提供的setData和putExtra方法傳遞。
Bundle(捆):
兩個(gè)Activity之間的通訊可以通過(guò)bundle類(lèi)來(lái)實(shí)現(xiàn),把要傳遞的數(shù)據(jù)通過(guò)key-value的形式加入數(shù)據(jù),另外一個(gè)Activity里面取出數(shù)據(jù)時(shí),用key找出對(duì)應(yīng)的valueonCreate(Bundle savedInstanceState)中savedInstanceState有什么用,什么情況下為null?
答:
savedInstanceState:是用來(lái)保存實(shí)例狀態(tài)的。在Activity中有一個(gè)onSaveInstanceStata方法,可以用來(lái)存放數(shù)據(jù),避免Activity意外退出時(shí)保存需要的數(shù)據(jù),通過(guò)onCreate中savedInstanceState取出保存的數(shù)據(jù),默認(rèn)不重寫(xiě)時(shí)為null如何實(shí)現(xiàn)使用Intent來(lái)傳遞自定義對(duì)象?
答:
序列化要傳遞的自定義的對(duì)象,再通過(guò)Bundle來(lái)傳值。
(序列化:將對(duì)象的狀態(tài)轉(zhuǎn)換為可保持或傳輸?shù)母袷降倪^(guò)程)
與序列化相對(duì)的是反序列化,它將流轉(zhuǎn)換為對(duì)象。
通過(guò)序列化和反序列化就可以實(shí)現(xiàn)存儲(chǔ)和傳輸數(shù)據(jù)。
(二)Android面試題(二)OOM、ANR
什么是OOM?如何避免OOM?
OOM概念:內(nèi)存溢出(OutOfMemor),內(nèi)存占有量超過(guò)了JVM分配的最大內(nèi)存。
避免OOM:
<1.避免對(duì)activity的超過(guò)生命周期的引用(盡量使用application代替activity)。
因?yàn)槌绦蛞话闶怯珊芏鄠€(gè)Activity構(gòu)成的,從一個(gè)Activity跳轉(zhuǎn)了以后,
系統(tǒng)就有可能回收這個(gè)Activity的各種內(nèi)存占用??墒谴藭r(shí)如果你的一些不可回收變量(比如靜態(tài)變量)保持了對(duì)此Activity對(duì)象的引用,
那么GC就不會(huì)對(duì)此Activity進(jìn)行回收,無(wú)故占用了大量的內(nèi)存。這種情況最好的辦法就是用application代替activity。
用Context.getApplicationContext() 或者 Activity.getApplication()可以很方便的得到application對(duì)象。
<2.在展示高分辨率圖片時(shí),先將圖片進(jìn)行壓縮到與空間大小相近。
<3.及時(shí)釋放不使用的Bitmap,動(dòng)態(tài)回收內(nèi)存,方法:bitmap.recycle()。
<4.對(duì)適配器視圖進(jìn)行優(yōu)化處理,避免過(guò)多加載數(shù)據(jù)和對(duì)象的生成。什么是ANR?產(chǎn)生ANR的原因是什么?如何避免ANR的發(fā)生?
ANR概念:
應(yīng)用程序無(wú)響應(yīng)(application not response)。
原因:
主線(xiàn)程中做了非常耗時(shí)的操作。
解決辦法:
<1.運(yùn)行在主線(xiàn)程里的任何方法都盡可能少做事情,盡量用Handler來(lái)處理UIthread和別的thread之間的交互;
<2.應(yīng)用程序應(yīng)該避免在BroadcastReceiver里做耗時(shí)的操作或計(jì)算;
<3.避免在Intent Receiver里啟動(dòng)一個(gè)Activity,因?yàn)樗鼤?huì)創(chuàng)建一個(gè)新的畫(huà)面,并從當(dāng)前用戶(hù)正在運(yùn)行的程序上搶奪焦點(diǎn);
<4.在主線(xiàn)程中更新UI。
(三)Android面試題(三)四大組件
什么是Service?Service和Activity有什么區(qū)別?
答:Service是提供服務(wù)的代碼,這些代碼最終體現(xiàn)為一個(gè)個(gè)的接口函數(shù),所以,Service就是實(shí)現(xiàn)一組函數(shù)的對(duì)象,通常也稱(chēng)為組件。
區(qū)別:
①?gòu)脑O(shè)計(jì)的角度來(lái)講:
Android的Activity的設(shè)計(jì)與Web頁(yè)面非常類(lèi)似,從頁(yè)面的跳轉(zhuǎn)通過(guò)連接,以及從頁(yè)面的定位通過(guò)URL,從每個(gè)頁(yè)面的獨(dú)立封裝等方面都可以看出來(lái),它主要負(fù)責(zé)與用戶(hù)進(jìn)行交互。
Service則是在后臺(tái)運(yùn)行,默默地為用戶(hù)提供功能,進(jìn)行調(diào)度和統(tǒng)籌,如果一棵樹(shù)的地上部分是Activity的話(huà),它龐大的根須就是Service。Android的服務(wù)組件沒(méi)有運(yùn)行在獨(dú)立的進(jìn)程或線(xiàn)程中,它和其他的組件一樣也在應(yīng)用的主線(xiàn)程中運(yùn)行,如果服務(wù)組件執(zhí)行比較耗時(shí)的操作就會(huì)導(dǎo)致主線(xiàn)程阻塞或者假死,從而無(wú)法響應(yīng)用戶(hù)的操作。
②從使用的角度來(lái)講:
Service不僅可以給Activity建立雙向連接,為Activity提供數(shù)據(jù)和功能支持,也可以單向接受Intent的請(qǐng)求,進(jìn)行數(shù)據(jù)的分析處理和功能調(diào)度。
③從扮演的角色來(lái)講:
Activity的功能比較單一,主要就是顯示應(yīng)用所具有的一些功能,幫助用戶(hù)與應(yīng)用進(jìn)行交互,像一個(gè)人的臉。而Service可能扮演功能調(diào)度者也能扮演功能提供者,從觸發(fā)器收集信息進(jìn)行分析和處理,然后更新界面,修改數(shù)據(jù)或進(jìn)行其他操作時(shí)是一個(gè)功能調(diào)度者,從輸入法的選擇考慮Service扮演的就是一個(gè)功能提供者。View組件是Android中用戶(hù)能夠?qū)崒?shí)在在看到的部分,如按鈕,輸入框等就是繼承自這個(gè)類(lèi),View只有裝入Activity這樣的容器中才有意義,而反過(guò)來(lái)
Activity裝入了這些View后才能夠成功完成與用戶(hù)交互的任務(wù),但是Service不需要這些花哨的東西,只需要默默地等待事件發(fā)生或者聽(tīng)候差遣。Service的兩種使用方式分別是什么?它們的生命周期分別怎樣遷移?
答:
方式1:通過(guò)startService,Service會(huì)經(jīng)歷onCreate->onStart,stopService的時(shí)候直接onDestroy
方式二:通過(guò)bindService,Service只會(huì)運(yùn)行onCreate,這個(gè)時(shí)候TestServiceHolder和TestService綁定在一起,TestServiceHolder退出了,Srevice就會(huì)調(diào)用onUnbind->onDestroyed什么是AIDL?AIDL的作用是什么?它的基本使用流程是怎么樣的?
答:AIDL是一種android內(nèi)部進(jìn)程通信接口的描述語(yǔ)言,通過(guò)它我們可以定義進(jìn)程間的通信接口
作用:
1、多個(gè)應(yīng)用程序之間建立共同的服務(wù)機(jī)制;
2、通過(guò)AIDL在不同應(yīng)用程序之間達(dá)到數(shù)據(jù)的共享和數(shù)據(jù)相互操作;
3、主要是用于多應(yīng)用之間的數(shù)據(jù)交互(而 在單個(gè)應(yīng)用內(nèi)或者說(shuō)該應(yīng)用如果不需要和其它第三方應(yīng)用進(jìn)行交互則不需要實(shí)現(xiàn)aidl接口);
流程:
1、編寫(xiě)aidl文件
2、編寫(xiě)自己的Service
3、在自己的Service的onBind方法中,將aidl文件生成的類(lèi)中的Stud的子類(lèi)返回(需要繼承Stud重寫(xiě)接口方法)
4、在AndroidManifest.xml中配置你的Service類(lèi),示例 注意:service android:name="com.aidl.SerachService"中,android:name屬性必須填寫(xiě)你的Service的名字,包括包名,不能寫(xiě)aidl生成的類(lèi)的名字,因?yàn)槟遣皇莻€(gè)Servic
5、編寫(xiě)調(diào)用aidl服務(wù)的客戶(hù)端
6、把之前編寫(xiě)的aidl文件(注意不是生成的java文件)和它的包目錄拷貝到客戶(hù)端的src目錄中
7、在需要的地方用一下方法綁定,new Intent構(gòu)造器中的action填寫(xiě)的就是之前<action android:name="com.aidl.ISerachService" />中的android:name的字符串什么是BroadcastReceiver?它有什么作用?
答:BroadcastReceiver是Android四大組件之一,本質(zhì)是一種 全局的監(jiān)聽(tīng)器,用于監(jiān)聽(tīng)系統(tǒng)全局的廣播消息。因此它可以非常方便的實(shí)現(xiàn)不同組件之間的通信。
作用:通過(guò)該機(jī)制,使得消息能在各個(gè)組件間、各個(gè)進(jìn)程間傳遞,起到郵遞員的作用。什么是有序廣播?有序廣播有什么特點(diǎn)?什么是系統(tǒng)廣播?
有序廣播:是通過(guò)Context.sendOrderedBroadcast來(lái)發(fā)送。所有的receiver依次執(zhí)行。
有序廣播特點(diǎn)即從優(yōu)先級(jí)別最高的廣播接收器開(kāi)始接收,接收完了如果沒(méi)有丟棄,就下傳給下一個(gè)次高優(yōu)先級(jí)別的廣播接 收器進(jìn)行處理,依次類(lèi)推,直到最后。
系統(tǒng)廣播:當(dāng)系統(tǒng)發(fā)生事件時(shí),就會(huì)發(fā)送出廣播,通過(guò)廣播中的關(guān)鍵字段,系統(tǒng)將尋找所有關(guān)注這個(gè)廣播的應(yīng)用,并觸發(fā)他們注冊(cè)的Receiver什么是粘性廣播?它跟普通廣播有什么區(qū)別?
定義:沒(méi)有注冊(cè)的接收者,在后來(lái)注冊(cè)后也能收到廣播,進(jìn)程間通信
當(dāng)發(fā)布該廣播后它還駐留在周?chē)?,它可以讓其他接收者迅速的檢索到數(shù)據(jù),通過(guò)一個(gè)方法的(動(dòng)態(tài)注冊(cè)接收者方法)返回值 這個(gè)返回值就是意圖
粘性廣播的特點(diǎn)是Intent會(huì)一直保留到廣播事件結(jié)束,而這種廣播也沒(méi)有所謂的10秒限制,10秒限制是指普通的廣播如果onReceive方法執(zhí)行時(shí)間太長(zhǎng),超過(guò)10秒的時(shí)候系統(tǒng)會(huì)將這個(gè)廣播置為可以干掉的candidate,一旦系統(tǒng)資源不夠的時(shí)候,就會(huì)干掉這個(gè)廣播而讓它不執(zhí)行。什么是ContentProvider?如何自定義一個(gè)ContentProvider?
ContentProvider(內(nèi)容提供者)是Android中的四大組件之一。主要用于對(duì)外共享數(shù)據(jù),也就是通過(guò)ContentProvider把應(yīng)用中的數(shù)據(jù)共享給其他應(yīng)用訪(fǎng)問(wèn),其他應(yīng)用可以通過(guò)ContentProvider對(duì)指定應(yīng)用中的數(shù)據(jù)進(jìn)行操作。
1)ContentProvider為存儲(chǔ)和獲取數(shù)據(jù)提供了統(tǒng)一的接口。ContentProvide對(duì)數(shù)據(jù)進(jìn)行封裝,不用關(guān)心數(shù)據(jù)存儲(chǔ)的細(xì)節(jié)。使用表的形式來(lái)組織數(shù)據(jù)。
2)使用ContentProvider可以在不同的應(yīng)用程序之間共享數(shù)據(jù)。
總的來(lái)說(shuō)使用ContentProvider對(duì)外共享數(shù)據(jù)的好處是統(tǒng)一了數(shù)據(jù)的訪(fǎng)問(wèn)方式。
自定義ContentProvider:
編寫(xiě)一個(gè)類(lèi),必須繼承自ContentProvider類(lèi);
實(shí)現(xiàn)ContentProvider類(lèi)中的所有的抽象方法;
onCreate();getType();query();Insert();update();delete();等方法
在清單文件中聲明注冊(cè)ContentProvider
<provider android:name=".MyWordsprovider"
android:authorities="heying.provider.wordsconetenprovider"
android:exported="true"
/>
將Uri提供出去你使用過(guò)哪些系統(tǒng)的ContentProvider?
媒體庫(kù)、通訊錄等
(四)Android面試題(四)數(shù)據(jù)保存和網(wǎng)絡(luò)
常用的數(shù)據(jù)持久化(長(zhǎng)久保存數(shù)據(jù))方式有哪些?
答:
1、SharedPreference,共享參數(shù)形式,一種以Key-Value的鍵值對(duì)形式保存數(shù)據(jù)的方式,Android內(nèi)置的,一般應(yīng)用的配置信息 ,推薦使用此種方式保存,不能存文件也不適合。其存儲(chǔ)的位置在/data/data/packageName/shared_prefs文件夾下面。
2、Internal Storage:把數(shù)據(jù)存儲(chǔ)到手機(jī)內(nèi)部的存儲(chǔ)空間,主要用來(lái)保存私有數(shù)據(jù)/data/data/packageName/files文件夾下 面
3、External Storage:把數(shù)據(jù)存儲(chǔ)到手機(jī)的外部存儲(chǔ)SD卡中,主要用來(lái)保存非私有和大型數(shù)據(jù),它有應(yīng)用程序?qū)S玫奈募A ,也有所有程序公用的文件夾(這個(gè)文件夾不會(huì)隨著應(yīng)用程序的卸載而卸載),需要賦予應(yīng)用程序訪(fǎng)問(wèn)Sdcard的權(quán)限,Android的權(quán)限 控制尤為重點(diǎn),在Android程序中,如果需要做一些越界的操作,均需要對(duì)其進(jìn)行授權(quán)才可以訪(fǎng)問(wèn)。在AndroidManifest.xml中添加代碼 :<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4、SQLite Databases:以表格形式存儲(chǔ)信息的一個(gè)輕量級(jí)的小型數(shù)據(jù)庫(kù)
5、Network Connection:將數(shù)據(jù)存儲(chǔ)到網(wǎng)絡(luò)服務(wù)器上
6、ContentProvider:他提供一種方式實(shí)現(xiàn)兩個(gè)不同應(yīng)用程序之間的通訊ShareedPrefrence的讀寫(xiě)數(shù)據(jù)的基本方法?
答:它保存的數(shù)據(jù)主要是簡(jiǎn)單類(lèi)型的Key-value對(duì)。并且Value部分只能是一些基本數(shù)據(jù)類(lèi)型:boolean、float、int、long、String等 。
1、得到SharedPreference對(duì)象的方法有:
a、Context類(lèi)中的getSharedPreference(String name,int mode)方法,name :存儲(chǔ)的文件名,如果不存在會(huì)自動(dòng)創(chuàng)建一個(gè) mode:訪(fǎng)問(wèn)模式,一般有兩個(gè)參數(shù)MODE_PRIVTE(私有,只有當(dāng)前應(yīng)用程序才能進(jìn)行讀寫(xiě))和MODE_MULTI_PROCESS(多個(gè)進(jìn)程對(duì)同一個(gè)文件進(jìn)行讀寫(xiě))
b、Activity類(lèi)中的getSharedPreference(int mode)方法,自動(dòng)將當(dāng)前活動(dòng)的類(lèi)名作為文件名
c、PreferenceManager類(lèi)的getDefaultSharedPreferences(Context context)方法,這是一個(gè)靜態(tài)方法,接收Context參數(shù),會(huì)自動(dòng)將應(yīng)用程序的包名作為前綴去命名文件
2、讀常用方法:
a、boolean contains(String Key):判斷SharedPreferences是否包含特定Key的數(shù)據(jù)
b、abstract Map<String,?> getAll():獲取SharedPreferences數(shù)據(jù)里全部的Key-Value對(duì)。
c、 boolean getXxx(String key,Xxx defValue):獲取SharedPreferences數(shù)據(jù)里指定Key對(duì)應(yīng)的value。如果該Key不存在,返回默認(rèn)值defValue。
3、寫(xiě)常用方法(通過(guò)SharedPreferences的內(nèi)部接口Editor實(shí)現(xiàn),edit()方法即可得到Editor對(duì)象)
a、abstract SharedPreferences.Editor clear():清空SharedPreferences里所有的數(shù)據(jù)
b、abstract SharedPreferences.Editor putXxx(String key,xxx value):向SharedPreferences中插入指定的Key-Value對(duì)。
c、abstract SharedPreferences.Editor remove(String key):從SharedPreferences中移除指定Key的數(shù)據(jù)。
d、boolean commit():當(dāng)Editor編輯完成后,調(diào)用該方法提交修改,切記不可忘記調(diào)用此方法,否則不能儲(chǔ)存數(shù)據(jù)SQLite的基本語(yǔ)句:建表、增刪改查分別是怎么樣的?
答:
建表:
CREATE TABLE tableName(column1 INTEGER PRIMARY KEY AUTOINCREMENT,column2 VARCHAR(num),.....);
添加:
INSERT INTO tableName values(value1,value2);添加所有字段
INSERT INTO tableName(column1,column2) values(value1,value2);添加字段column1和字段column2
刪除:
DELETE TABLE tableName 刪除全部
DELETE form tableName WHERE column2 = vaule2按條件查詢(xún)(字段column2的值為vaule2的這一行,如果value2為字符串則需要用單引號(hào)括起來(lái))
更新:
UPDATE tableName SET column1 = value1, column2 = value2,...;所有數(shù)據(jù)都這樣更新
UPDATE tableName SET column1 = value1, column2 = value2 WHERE column3 = value3;更新column3 = value3這一行的column1 和column2的值
查詢(xún):
SELECT * FROM tableName;查詢(xún)所有的數(shù)據(jù)
SELECT column1,column3 FROM tableName; 查詢(xún)所有數(shù)據(jù),但是只顯示column1,column3這兩個(gè)字段的所有值
SELECT * FROM tableName WHERE column2 > someValue;查詢(xún)column2字段的值大于someValue的所有字段
SELECT * FROM tableName WHERE column1 = value1 ORDER BY column2 ASC;按條件查詢(xún)結(jié)果以column2 的升序排列
SELECT * FROM tableName WHERE column1 = value1 ORDER BY column2 DESC;按條件查詢(xún)結(jié)果以column2 的降序排列
SELECT * FROM tableName WHERE column2 LIKE '%key%' ORDER BY column2 ASC;// 模糊查找SQLiteOpenHelper的作用是什么?
答:SQLiteOpenHelper主要是用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)和表格,以及為數(shù)據(jù)庫(kù)升級(jí)的作用。在Android系統(tǒng)中,既然可以通過(guò)Context類(lèi)的 openOrCreateDatabase()函數(shù)打開(kāi)或創(chuàng)建SQLite數(shù)據(jù)庫(kù),并且可以通過(guò)其返回值(即SQLiteDatabase對(duì)像)調(diào)用execSQL()函數(shù)對(duì)數(shù)據(jù) 庫(kù)做任何的操作(CRUD),那么還需要SQLiteOpenHelper這個(gè)類(lèi)有什么意義呢?
例如:
db = openOrCreateDatabase(DB_NAME, this.MODE_PRIVATE, null);
db.execSQL("DROP TABLE IF EXISTS students");
db.execSQL("CREATE TABLE IF NOT EXISTS students (_id INTEGER PRIMARY KEY AUTOINCREMENT, name, age INTEGER)");
實(shí)際上,直接操作數(shù)據(jù)庫(kù)的語(yǔ)句和其他的語(yǔ)句混在一起,不利于程序的模塊化。而SQLiteOpenHelper是一個(gè)抽象類(lèi),通過(guò)它的名字可以 看出來(lái),是一個(gè)幫我們打開(kāi)數(shù)據(jù)庫(kù)的小助手:
1、當(dāng)new SQLiteOpenHelper子類(lèi)對(duì)象時(shí),就會(huì)通過(guò)其構(gòu)造函數(shù)創(chuàng)建數(shù)據(jù)庫(kù)文件(當(dāng)然如果數(shù)據(jù)庫(kù)如果存在,就不用創(chuàng)建了, 并且自動(dòng)調(diào)用onCreate(SQLiteDatabase db)創(chuàng)建數(shù)據(jù)表;
2、當(dāng)要對(duì)數(shù)據(jù)庫(kù)讀操作時(shí),只需調(diào)用其子類(lèi)的getReadableDatabase()返回SQLiteDatabase實(shí)例,通過(guò)該實(shí)例來(lái)執(zhí)行SQL語(yǔ)句 ;
3、當(dāng)要對(duì)數(shù)據(jù)庫(kù)寫(xiě)操作時(shí),只需調(diào)用其子類(lèi)的getWritableDatabase()返回SQLiteDatabase實(shí)例,通過(guò)該實(shí)例來(lái)執(zhí)行SQL語(yǔ)句 ;
4、當(dāng)通過(guò)構(gòu)造函數(shù)傳進(jìn)來(lái)的數(shù)據(jù)庫(kù)版本高于之前的版本時(shí),系統(tǒng)會(huì)調(diào)用onUpgrade()函數(shù)來(lái)更新數(shù)據(jù)庫(kù)。
于是,對(duì)APP而言,就屏蔽了數(shù)據(jù)庫(kù)創(chuàng)建的過(guò)程,將數(shù)據(jù)表的創(chuàng)建獨(dú)立出來(lái)了。
SQLiteOpenHelper只是一個(gè)數(shù)據(jù)庫(kù)管理的幫助類(lèi),讓使用者不直接操作數(shù)據(jù)庫(kù)而是通過(guò)操作這個(gè)類(lèi)的對(duì)象來(lái)實(shí)現(xiàn)各種數(shù)據(jù)庫(kù)操作。這個(gè) 類(lèi)就是給數(shù)據(jù)庫(kù)操作搭了個(gè)架子,使用者根據(jù)需求去填充那些架子。什么是回調(diào)CallBack,回調(diào)的作用是什么?常見(jiàn)的回調(diào)使用場(chǎng)景?
答:把接口方法的定義和調(diào)用給封裝起來(lái),然后在回調(diào)接口中的回調(diào)方法中進(jìn)行具體的操作
作用:
1、可以節(jié)省時(shí)間,充分利用了資源
2、讓工具類(lèi)的使用變得簡(jiǎn)單易用。用戶(hù)不需要關(guān)心接口方法的定義以及調(diào)用,只需要關(guān)注方法的具體實(shí)現(xiàn)功能即可。
使用場(chǎng)景:
1、事件監(jiān)聽(tīng)器,這其實(shí)就是回調(diào)最常見(jiàn)的應(yīng)用場(chǎng)景之一
2、生命周期函數(shù)
3、當(dāng)方法的具體實(shí)現(xiàn)不確定的時(shí)候可以設(shè)置回調(diào)函數(shù)讓清楚的人自己去實(shí)現(xiàn),而我們只是提供一個(gè)實(shí)現(xiàn)的接口出去,而其它的別人不需要知道的東西都封存起來(lái),這也體現(xiàn)了封裝和面向?qū)ο蟮乃枷?,你?wèn)我問(wèn)題,而我想到了答案告訴你,至于 你拿到答案后干什么,我怎么想到的答案都不需要對(duì)方知道TCP和UDP的區(qū)別是什么?
答:
TCP :傳輸控制協(xié)議。
a、面向連接,靠三次握手來(lái)完成
b、速度相對(duì)較慢,因?yàn)檫B接的過(guò)程會(huì)耗時(shí)間和資源
c、可靠的協(xié)議,數(shù)據(jù)不會(huì)丟失
d、數(shù)據(jù)大小沒(méi)有限制
e、耗用系統(tǒng)資源相對(duì)較多
UDP :用戶(hù)數(shù)據(jù)報(bào)文協(xié)議
a、面向無(wú)連接的
b、高效的、速度快
c、不可靠的協(xié)議,容易丟失數(shù)據(jù)
d、數(shù)據(jù)包大小有限制,小于64K
e、耗用系統(tǒng)資源相對(duì)較少Http的get和post方法的區(qū)別什么?
答:get方法:
原理上:
主要用來(lái)獲取或者查詢(xún)資源信息,是安全的和冪等的。就是說(shuō)不修改信息
表面上:
a、GET請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連
b、GET方式提交的數(shù)據(jù)較?。g覽器和操作系統(tǒng)對(duì)URL長(zhǎng)度的限定),一般1024字節(jié)
c、GET的安全性相對(duì)較弱,可能會(huì)造成信息泄露(信息會(huì)明文出現(xiàn)在URL上,其他人可能會(huì)通過(guò)瀏覽器的緩存查看到歷史記錄,從而得到信息)
d、服務(wù)器端用Request.QueryString獲取變量的值
e、GET請(qǐng)求用起來(lái)比比較方便
post方法:
原理上:
根據(jù)Http規(guī)范,POST表示可能修改服務(wù)器上資源的請(qǐng)求
表面上:
a、POST請(qǐng)求把要提交的數(shù)據(jù)放在HTTP包的包體中。
b、POST可以提交較大量的數(shù)據(jù)(受到服務(wù)器的處理程序的處理能力限制)
c、POST安全性較高(數(shù)據(jù)不會(huì)明文出現(xiàn)在URL上)。
d、服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)。
e、用起來(lái)相對(duì)麻煩一點(diǎn)
(五)Android面試題(五)常見(jiàn)的異步方式
常見(jiàn)的實(shí)現(xiàn)異步的方式有哪些?
AsyncTask、Thread+Handler常見(jiàn)的耗時(shí)操作如何處理?
常見(jiàn)的耗時(shí)操作有:網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)操作、比較復(fù)雜的運(yùn)算,使用AsyncTask或Thread+Handler進(jìn)行異步處理子線(xiàn)程更新UI的基本方法有哪些?
a. Thread + Handler的方式
在非UI線(xiàn)程中執(zhí)行耗時(shí)操作(網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)操作、比較復(fù)雜的運(yùn)算),在需要將操作的進(jìn)度或者結(jié)果更新到UI上時(shí),
就發(fā)送消息并攜帶數(shù)據(jù),最終由Handler的handleMessage來(lái)處理(注意:Handler對(duì)象必須是創(chuàng)建在UI線(xiàn)程中)
b. Activity提供的一個(gè)簡(jiǎn)便的方式來(lái)更新UI
runOnUiThread(Runnable r);
內(nèi)部做了判斷當(dāng)前的活動(dòng)線(xiàn)程是否是UI線(xiàn)程
是:直接調(diào)用run方法
否:將Runnable給post到UI線(xiàn)程對(duì)應(yīng)的消息隊(duì)列
c. Handler里邊也提供簡(jiǎn)便的更新UI的方式
handler.post(Runnable r);
內(nèi)部其實(shí)調(diào)用了發(fā)送消息的方法,最終也是把Runnable對(duì)象給放到了UI線(xiàn)程中執(zhí)行Handler、Looper、Message、MessageQueue是什么?它們之間有什么關(guān)聯(lián)?
Handler:基本功能兩個(gè),發(fā)送和處理消息
發(fā)消息:sendXXXX方法
a. 如果不需要通過(guò)消息來(lái)傳遞具體的數(shù)據(jù),可以發(fā)送空消息
sendEmptyMessage(what);即時(shí)消息,立即發(fā)送
sendEmptyMessageDelayed(what,time);發(fā)送一個(gè)延遲消息,在從當(dāng)前計(jì)時(shí)到指定時(shí)間長(zhǎng)度后發(fā)送
sendEmptyMessageAtTime(what, atTime);發(fā)送一個(gè)定時(shí)的消息,在指定時(shí)刻發(fā)出
b. 如果需要在線(xiàn)程間傳遞一些具體的數(shù)據(jù),需要發(fā)送帶有具體消息對(duì)象的消息
消息對(duì)象的獲取:
Message msg = new Message(); // 每一次都新創(chuàng)建一個(gè)消息對(duì)象
Message msg = handler.obtainMessage();// 每次調(diào)用時(shí)會(huì)去檢查消息池中是否有可復(fù)用的消息。有則復(fù)用,無(wú)則創(chuàng)建。
Message msg = Message.obtain(); // 每次調(diào)用時(shí)會(huì)去檢查消息池中是否有可復(fù)用的消息。有則復(fù)用,無(wú)則創(chuàng)建。
c. Message都有哪些傳遞數(shù)據(jù)的方式:
what:int,用于區(qū)分消息從哪里發(fā)出
arg1:int,可以攜帶一個(gè)int數(shù)據(jù)
arg2:int,也可以攜帶一個(gè)int數(shù)據(jù)
obj:Object,可以攜帶任何的對(duì)象
d. 帶數(shù)據(jù)的消息發(fā)送也可以有即時(shí)、延遲、定時(shí)
處理消息:handleMessage里邊實(shí)現(xiàn)接收到消息之后需要實(shí)現(xiàn)的操作,需要注意的是該方法是覆蓋父類(lèi)Handler的
Message:消息對(duì)象,用來(lái)傳遞具體的數(shù)據(jù)的。
MessageQueue:消息隊(duì)列,是一種數(shù)據(jù)結(jié)構(gòu),特點(diǎn)是符合FIFO,先進(jìn)先出,由一個(gè)或多個(gè)消息對(duì)象構(gòu)成的一個(gè)隊(duì)列
Looper:循環(huán)的意思,作用就是管理消息隊(duì)列,比如說(shuō)從隊(duì)列中取出消息交給對(duì)應(yīng)的Handler進(jìn)行處理AsyncTask中幾個(gè)回調(diào)方法運(yùn)行在哪個(gè)線(xiàn)程、DoInBackGround執(zhí)行在哪個(gè)線(xiàn)程?
4個(gè)回調(diào)方法,其中三個(gè)運(yùn)行在主線(xiàn)程(初始化,UI更新,進(jìn)度條更新),DoInBackGround運(yùn)行在子線(xiàn)程runOnUiThread為什么可以用來(lái)更新UI?
該方法內(nèi)部做了判斷當(dāng)前線(xiàn)程是否為UI線(xiàn)程的操作
不是UI線(xiàn)程則將該action添加到mHandler所在的UI線(xiàn)程的消息隊(duì)列中
是UI線(xiàn)程,則直接執(zhí)行使用Handler+Thread的方式在子線(xiàn)程更新UI時(shí),Handler對(duì)象可以在子線(xiàn)程中創(chuàng)建嗎?
不能,只能在主線(xiàn)程創(chuàng)建,再傳到子線(xiàn)程中
- Handler的post方法為什么可以用來(lái)更新UI?
該方法內(nèi)部實(shí)際上是發(fā)送一個(gè)延遲的消息給該線(xiàn)程的Handler處理,該方法內(nèi)部將消息對(duì)象加入了消息隊(duì)列,
最終也是把Runnable對(duì)象給放到了UI線(xiàn)程中執(zhí)行
如果是更新UI,則這個(gè)Handler對(duì)象必須創(chuàng)建在UI線(xiàn)程中
(六)Android面試題(六)JSON、XML、MediaPlay生命周期
JSON中有幾種數(shù)據(jù)類(lèi)型,解析對(duì)應(yīng)數(shù)據(jù)類(lèi)型分別用哪個(gè)類(lèi)?
四種類(lèi)型:
第一種類(lèi)型是標(biāo)量(scalar),也就是一個(gè)單獨(dú)的字符串(string)或數(shù)字(numbers),
比如"北京"這個(gè)單獨(dú)的詞。
第二種類(lèi)型是序列(sequence),也就是若干個(gè)相關(guān)的數(shù)據(jù)按照一定順序并列在一起,
又叫做數(shù)組(array)或列表(List),比如"北京,上海"。對(duì)應(yīng)JSONAray;
第三種類(lèi)型是映射(mapping),也就是一個(gè)名/值對(duì)(Name/value),即數(shù)據(jù)有一個(gè)名稱(chēng),
還有一個(gè)與之相對(duì)應(yīng)的值,這又稱(chēng)作散列(hash)或字典(dictionary)。對(duì)應(yīng)String;
第四種,類(lèi)似于Java中的類(lèi),對(duì)應(yīng)JSONObject。有哪些方式可以做JSON數(shù)據(jù)的解析?
兩種解析方式:
1)JSON普通解析方式,運(yùn)用
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;對(duì)象來(lái)解析;
2)運(yùn)用gson-2.1.jar包下的Gson類(lèi)和與之Json數(shù)據(jù)相對(duì)應(yīng)的Translate類(lèi)來(lái)解析:創(chuàng)建Gson對(duì)象,調(diào)用它的fromjson方法有哪些方式可以做XML數(shù)據(jù)解析?
DOM在處理XML文件時(shí),將XML文件解析成樹(shù)狀結(jié)構(gòu)并放入內(nèi)存中進(jìn)行處理。
SAX則是以事件作為解析XML文件的模式,它將XML文件轉(zhuǎn)化成一系列的事件,由不同的事件處理器來(lái)決定如何處理。
XML文件較大時(shí),選擇SAX技術(shù)是比較合理的。
XML pull通過(guò)循環(huán)驅(qū)動(dòng)事件來(lái)解析:判斷事件的類(lèi)型,獲取事件中的內(nèi)容
對(duì)于XML文檔較大但只需要文檔的一部分時(shí),XML Pull解析器則是更為有效的方法。請(qǐng)闡述一種XML解析方式的基本流程。
1. 獲取解析器對(duì)象XmlPullParser對(duì)象parser
2. 可以給parser對(duì)象設(shè)置輸入的編碼方式
3. 循環(huán)驅(qū)動(dòng)事件進(jìn)行解析
事件分為4類(lèi):
a. 開(kāi)始文檔:XmlPullParser.START_DOCUMENT值為0
b. 結(jié)束文檔:XmlPullParser.END_DOCUMENT值為1
c. 開(kāi)始標(biāo)簽:XmlPullParser.START_TAG值為2
d. 結(jié)束標(biāo)簽:XmlPullParser.END_TAG值為3
一個(gè)事件處理完畢之后,需要提供parser的next方法去驅(qū)動(dòng)下一個(gè)事件自定義View有哪幾種方式?
自繪控件、組合控件、以及繼承控件。MediaPlayer的生命周期是怎樣的?
1.Idle 狀,2.End 狀態(tài),3.Initialized 狀態(tài),4.Prepared 狀態(tài),5.Preparing 狀態(tài),6.Started 狀態(tài),7.Paused 狀態(tài),8.Stop 狀態(tài),9.PlaybackCompleted狀態(tài),10.Error狀態(tài)請(qǐng)闡述圖片加載的基本流程及優(yōu)化方案。
通過(guò)HttpURLConnection c_onn = (HttpURLConnection) url.openConnection()
取得圖片鏈接,通過(guò)InputStream in = conn.getInputStream()取得圖片圖片io流
取得Bitmap圖片。
通過(guò)LuraCache來(lái)優(yōu)化圖片緩存