Java基礎
- 什么是重載,什么是重寫?有什么區別?
重載(Overload):
(1)Overloading是一個類中多態性的一種表現,讓類以統一的方式處理不同類型數據的一種手段。多個同名函數同時存在,具有不同的參數個數/類型。
(2)重載的時候,方法名要一樣,但是參數類型和個數不一樣,返回值類型可以相同,也可以不相同。無法以返回型別作為重載函數的區分標準。
重寫(Override):
(1) 父類與子類之間的多態性,對父類的函數進行重新定義。即在子類中定義某方法與其父類有相同的名稱和參數。
(2)若子類中的方法與父類中的某一方法具有相同的方法名、返回類型和參數表,則新方法將覆蓋原有的方法。如需父類中原有的方法,可使用super關鍵字,該關鍵字引用了當前類的父類。 - 泛型T和?有什么區別?
a)先看個方法的代碼
public <T>T getT(T arg){
return arg;
}
public List<?> getT(List<?> arg){
return new ArrayList<String>();
}
b) 通過兩個方法可以看到,T和?都可以用于聲明泛型, 但是T可以用來約束函數的返回值類型,而?不會約束返回值類型。在工作里面使用T是更安全的。 - 使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?
使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。
例如,對于如下語句:
final StringBuffer a=new StringBuffer("immutable");
執行如下語句將報告編譯期錯誤:
a=new StringBuffer("");
但是,執行如下語句則可以通過編譯:
a.append(" broken!"); - String s = "Hello";s = s + " world!";這兩行代碼執行后,原始的String對象中的內容到底變了沒有?
沒有。
因為String被設計成不可變(immutable)類,所以它的所有對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是 "Hello",然后我們對s進行了+操作,那么s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個 String對象,內容為"Hello world!",原來那個對象還存在于內存之中,只是s這個引用變量不再指向它了。 - "=="和equals方法究竟有什么區別?
==:操作符專門用來比較兩個變量的值是否相等,也就是用于比較變量所對應的內存中所存儲的數值是否相同,要比較兩個基本類型的數據或兩個引用變量是否相等,只能用==操作符。
equals:方法是用于比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。
例如,對于下面的代碼:
String a=new String("foo");
String b=new String("foo");
兩條new語句創建了兩個對象,然后用a/b這兩個變量分別指向了其中一個對象,這是兩個不同的對象,它們的首地址是不同的,即a和b中存儲的數值是不相同的,所以,表達式a==b將返回false,而這兩個對象中的內容是相同的,所以,表達式a.equals(b)將返回true。
在實際開發中,我們經常要比較傳遞進行來的字符串內容是否等,字符串的比較基本上都是使用equals方法。 - 什么是Activity?
四大組件之一,用于顯示和用戶交互的界面
setContentView() ,// 要顯示的布局
findViewById(R.id.textview);// 查找界面上的控件
button.setOnclickLinstener{
}
我開發常用的的有 FragmentActivitiy,ListActivity , PreferenceActivity 等…
如果多個界面有共同的特點或者功能的時候,還會自己定義一個BaseActivity.
- 請描述一下Activity 生命周期。
a、生命周期描述的是一個類 從創建(new出來)到死亡(垃圾回收)的過程中會執行的方法.在這個過程中 會針對不同的生命階段會調用不同的方法
b、Activity從創建到銷毀有多種狀態,從一種狀態到另一種狀態時會激發相應的回調方法,這些回調方法包括:onCreate onDestroy onStart onStop onResume onPause
c、其實這些方法都是兩兩對應的,onCreate創建與onDestroy銷毀;
onStart可見與onStop不可見;onResume可編輯(即獲取焦點)與onPause;
d、另外還有一個onRestart方法,在Activity被onStop后,但是沒有被onDestroy,在再次啟動此Activity時就調用onRestart(而不再調用onCreate)方法;
e、最后講在項目中的使用。比如說每次進入某個界面的時候都要看到最新的數據,這個刷新列表的操作 就放在onStart()的方法里面.這樣保證每次用戶看到的數據都是最新的.
多媒體播放, 播放的時候來電話.在 onStop() 時停止視頻, 將視頻聲音設置為0 , 記錄視頻播放的位置;在 onStart() 時根據保存的狀態恢復現場. - 兩個Activity之間跳轉時必然會執行的是哪幾個方法。
a、一般情況比如說有兩個activity,分別叫A,B ,當在A里面激活B組件的時候, A 會調用 onPause()方法,然后B 調用onCreate() ,onStart(), OnResume() ,這個時候B覆蓋了窗體, A會調用onStop()方法.
b、如果B是個透明的界面,或者是對話框的樣式, 就不會調用onStop()方法。 - 橫豎屏切換時候Activity的生命周期。
這個生命周期跟清單文件里的配置有關系
不設置Activity的android:configChanges時,切屏會銷毀當前Activity,然后重新加載,重新調用各個生命周期。
設置Activity的android:configChanges="orientation|keyboardHidden|screenSize"時,切屏不會重新調用各個生命周期,只會執行 onConfigurationChanged 方法
(橫豎屏切換的時候,如果有彈窗會被銷毀。-- 如果要在旋轉屏幕后保留對話框應該怎么辦?)
- 如何將一個Activity設置成窗口的樣式。
可以設置activity的樣式為對話框
android:theme="@android:style/Theme.Dialog" - 如果后臺的Activity由于某原因被系統回收了,如何在被系統回收之前保存當前狀態?
除了在棧頂的activity,其他的activity都有可能在內存不足的時候被系統回收,一個activity越處于棧底,被回收的可能性越大.
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
public void onCreate(Bundle savedInstanceState) {
// 判斷 savedInstanceState是不是空.
// 如果不為空就取出來
super.onCreate(savedInstanceState);
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
}
備用方案:切換到后臺的時候就先把數據保存,在切換到前臺的時候重新獲取數據恢復界面
- 兩個Activity之間傳遞數據,除了intent,廣播接收者,content provider還有啥?
1)利用static靜態數據,public static成員變量
2)利用外部存儲的傳輸,
例如 File 文件存儲
SharedPreferences首選項
Sqlite 數據庫
(Activity間哪些方式傳遞數據?) - 如何退出Activity?如何安全退出已調用多個Activity的Application
a、通常情況用戶退出一個Activity只需按返回鍵,我們寫代碼想退出activity直接調用finish()方法就行。
b、記錄打開的Activity:
每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
c、發送特定廣播:
在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播后,關閉即可。
d、遞歸退出
在打開新的Activity時使用startActivityForResult,然后自己加標志,在onActivityResult中處理,遞歸關閉。
e、通過 intent的flag 來實現intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一個新的activity。此時如果該任務棧中已經有該Activity,那么系統會把這個Activity上面的所有Activity干掉。其實相當于給Activity配置的啟動模式為SingleTop。
service是否在main thread中執行, service里面是否能執行耗時的操作?
a、默認情況, Service和activity是運行在當前app所在進程的main thread(UI主線程)里面,service里面不能執行耗時的操作(網絡請求,拷貝數據庫,大文件 ) . 如果要執行耗時操作,需要開啟子線程執行
Thread.currentThread().getName();
b、特殊情況 ,可以在清單文件配置 service 執行所在的進程 ,讓service在另外的進程中執行。獨立進程和當前應用主線程無關,可以做任意的耗時操作。怎么在啟動一個Activity時就啟動一個service?
在activity的onCreate()方法里面 startService();同一個程序,但不同的Activity是否可以放在不同的Task任務棧中?
a、Singleinstance 運行在另外的單獨的任務棧里面
b、在激活一個新的activity時候, 給Intent的flag添加FLAG_ACTIVITY_NEW_TASK,這個被激活的activity就會在新的task棧里面
Intent intent = new Intent(A.this,B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);怎么在activity中啟動service?
啟動service有兩種方式
a、startService() 一旦被創建 調用著無關 沒法使用service里面的方法
b、bindService () 把service 與調用者綁定 ,如果調用者被銷毀, service會銷毀。bindService()方式啟動服務讓activity能夠訪問到 service里面的方法描述下Service的生命周期。
Service有綁定模式和非綁定模式,以及這兩種模式的混合使用方式。不同的使用方法生命周期方法也不同。
a、非綁定模式:當第一次調用startService的時候執行的方法依次為onCreate()、onStartCommand(),當Service關閉的時候調用onDestory方法。
b、綁定模式:第一次bindService()的時候,執行的方法為onCreate()、onBind()解除綁定的時候會執行onUnbind()、onDestory()。
上面的兩種生命周期是在相對單純的模式下的情形。我們在開發的過程中還必須注意Service實例只會有一個,也就是說如果當前要啟動的Service已經存在了那么就不會再次創建該Service,當然也不會調用onCreate()方法。
c、一個Service可以被多個客戶進行綁定,只有所有的綁定對象都執行了onBind()方法后該Service才會銷毀,不過如果有一個客戶執行了onStart()方法,那么這個時候如果所有的bind客戶都執行了unBind()該Service也不會銷毀。(播放音樂時,播放界面要控制Service的音樂播放--bindService特性,退出音樂界面后音樂還要繼續播放--startService特性)子線程不能代替service嗎?
a、不能替代
b、 首先要確認一件事,Service作為四大組件之一,是運行在主線程的,可以直接顯示吐司,修改View等。如果要運行耗時操作,服務需要自己開啟子線程。
c、 只作為后臺來理解的話,相比于線程,服務具備完善的生命周期,更方便隨時釋放資源。
d、 服務自己就有上下文(Context)對象,可以保證上下文是正??捎玫?。線程需要從外部獲取上下文對象,在運行時無法保證該對象沒有被系統銷毀。
e、在沒有界面存在的時候;只有子線程運行的進程是空進程,隨時可能被回收;只有服務運行的進程是服務進程,比較難被回收。什么是IntentService?有何優點?
a、普通的service,默認運行在ui main 主線程
b、IntentService是Sdk給我們提供的方便的,帶有異步處理的service類, 它的OnHandleIntent() 方法在子線程運行,方便處理耗時的操作什么時候使用Service?
a、Service的特點可以讓他在后臺一直運行,可以創建線程去完成耗時的操作.
b、Broadcast receiver生命周期較短,捕獲到一個事件之后,可以起一個service來完成一個耗時的操作.
c、Service如果被啟動起來,可以被多次bind, 但不會重新create.在多個應用間共用一段代碼,節約系統資源。比如索愛手機X10i的人臉識別的service可以被圖庫使用,可以被攝像機,照相機等程序使用.
d、所有界面都已經關閉,需要在后臺監控數據的時候。
e、擁有service的進程具有較高的優先級,可以保護應用資源不會被回收。
官方文檔告訴我們,Android系統會盡量保持擁有service的進程運行,只要在該service已經被啟動(start)或者客戶端連接(bindService)到它。當內存不足時,需要保持,擁有service的進程具有較高的優先級。
1. 如果service正在調用onCreate, onStartCommand或者onDestory方法,那么用于當前service的進程相當于前臺進程以避免被killed。
2. 如果當前service已經被啟動(start),擁有它的進程則比那些用戶可見的進程優先級低一些,但是比那些不可見的進程更重要,這就意味著service一般不會被killed.
3. 如果客戶端已經連接到service (bindService),那么擁有Service的進程則擁有最高的優先級,可以認為service是可見的。
4. 如果service可以使用startForeground(int, Notification)方法來將service設置為前臺狀態,那么系統就認為是對用戶可見的,并不會在內存不足時killed。
如果有其他的應用組件作為Service,Activity等運行在相同的進程中,那么將會增加該進程的重要性。請描述一下Intent 和 Intent Filter。
Android 中通過Intent 和IntentFilter可以實現四大組件的調用與激活。
Intent可以比作一封郵件,包含收件地址和具體的內容。其中消息“目的地”是必須的,而內容則是可選項。
Intent filter: 可以理解為郵箱…
這個分揀系統通過3個參數來識別
Action: 動作 view
Category :額外的附加信息
Data: 數據uri或mimetyppe uri
如果我們在啟動一個 Activity 時使用這樣的 Intent 對象:
Intent intent =new Intent();
intent.setAction("cn.itcast.action");
那么所有的 Action 列表中包含了“cn.itcast.action”的 Activity 都將會匹配成功。
一個 Intent 可以通過 URI 攜帶外部數據給目標組件。在 <intent-filter >節點中,通過 <data/>節點匹配外部數據。mimeType 屬性指定攜帶外部數據的數據類型,scheme 指定協議,host、port、path 指定數據的位置、端口、和路徑。
如果在 Intent Filter 中指定了這些屬性,那么只有所有的屬性都匹配成功時 URI 數據匹配才會成功。比如注冊了 http協議的 Audio/Mp3 類型文件,那就不會有其他的調用喚起當前Activity。
- 系統上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?
啟動一個界面有隱式意圖和顯式意圖兩種方式。
隱式意圖可以啟動一個類型的界面,顯示意圖可以啟動指定應用的指定界面。
這里使用顯示意圖就可以。
Intent intent = new Intent();
intent.setClassName(packageName, className);
intent.seturi() - Intent傳遞數據時,可以傳遞哪些類型數據?
a、 數據的uri, intent.setData() intent.getData();
數據的type,intent.setType(), intent.getType();
b、八大基本數據類型 Intent .putextra() intent.getextra();
c、可序列化對象。
(傳遞序列化對象時要生成新的對象,傳遞圖片的時候應該傳遞uri,不要直接傳遞bitmap對象。) - Serializable和Parcelable的區別
性能:
a、Serializable在序列化的時候需要把對象先寫到磁盤上,導致性能較低。Parcelable序列化在內存里處理,性能較高。谷歌推薦使用Parcelable類。
b、Parcelable不能使用在要將數據存儲在磁盤上的情況。盡管Serializable效率低點,但在這種情況下,只能使用Serializable 。
實現:
a、Serializable 的實現,只需要繼承Serializable 即可。這只是給對象打了一個標記,系統會自動將其序列化。
b、Parcelabel 的實現,需要在類中添加一個靜態成員變量 CREATOR,這個變量需要繼承 Parcelable.Creator 接口。
請描述一下Broadcast Receiver。
a、手機使用時有很多事件無法確定什么時候會發生,比如電量變化,收到短信等,這個時候可以通過注冊一個廣播接收者,等待系統發送廣播就可以。
b、廣播分兩種 有序廣播 無序廣播
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
abortBroadcast();
c、具體使用有:
接收系統的廣播通知, 系統自帶了很多廣播,sd卡掛載,手機重啟,低電量,來電,來短信等….
關閉所有的Activity
畫畫板生成圖片后,發送一個sd掛載的通知,通知系統的gallery去獲取到新的圖片.
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()));
sendBroadcast(intent);BroadCastReceiver的生命周期
a、 廣播接收者的生命周期非常短暫的,在接收到廣播的時候創建,onReceive()方法結束之后銷毀;
b、廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話框;
c、最好也不要在廣播接收者中創建子線程做耗時的工作,因為廣播接收者被銷毀后進程就成為了空進程,很容易被系統殺掉;
d、耗時的較長的工作最好放在服務中完成;請介紹下Android的數據存儲方式。
a、文件 訪問權限. sdcard <data>/<data>。存儲圖片、序列化對象等
b、SharedPreference <data>/<data>/shared_preps 。存儲設置信息。
c、數據庫 sqlite 。存儲大量的結構化數據。
d、網絡 socket tcp udp , http httpurlconnection。為什么要用ContentProvider?它和sql的實現上有什么差別?
a、android 系統下 不同程序 數據 在data目錄的不同子文件下,默認是不能共享訪問
b、ContentProvider 是Android 提供的一個共享數據的類,而Sql 是一種操作數據庫的語言。
c、僅針對操作數據而言,ContentProvider屏蔽數據存儲的細節,對用戶透明,用戶只需要關心操作數據的uri就可以了
d、ContentProvider可以實現不同app之間共享,操作數據
e、Sql也有增刪改查的方法. 但是sql只能查詢本應用下的數據庫。而contentprovider 還可以去增刪改查本地文件. xml文件、網絡數據讀取更改請介紹下ContentProvider是如何實現數據共享的。
a、創建一個MyProvider類繼承ContentProvider,并實現增刪改查方法
b、在清單文件里注冊MyProvider類,注冊能夠響應的Uri
<provider
android:authorities="com.itheima.newlist"
android:name=".MyProvider"/>
c、調用者獲取ContentResolver,并使用約定的uri執行增刪改查操作
ContentResolver resolver = getContentResolver();
resolver.query(uri, projection, selection, selectionArgs, sortOrder);}
d、系統會自動找到MyProvider,并調用它的增刪改查方法說說ContentProvider ContentResolver ContentObserver之間的關系
a、ContentProvider 內容提供者,用于封裝數據操作
b、ContentResolver 內容解析者,用于調用ContentProvider 處理數據
c、ContentObserver 內容監聽器,可以監聽數據的狀態改變
d、可以通過ContentResolver.registerContentObserver(uri,observer)監聽指定uri的消息。
e、使用ContentResolver.notifyChange(uri)發出消息,則正在監聽該uri的observer的onchange方法會被調用。描述一下Fragment的生命周期
Fragment和Activity之間的交互, Fragment和Fragment之間的交互
a、強耦合的方式:Activity本身就持有Fragment對象,可以直接調用Fragment的函數。Fragment調用Activity的函數則麻煩一些,谷歌官方推薦在Fragment里定義一個接口,然后Activity實現該接口。那么在Fragment里獲取到的Activity可以強轉為接口對象,Fragment調用接口里的函數則可以和Activity的交互。
b、弱耦合的方式:使用廣播接收者,在Activity和Fragment里分別注冊廣播接收者,互相發送消息即可,這種方式不需要Activity和Fragment互相持有引用。
c、弱耦合的方式2:使用EventBus可以達到和廣播相同的效果,同時由于廣播的響應范圍是整個系統,而EventBus的作用范圍是應用內,所以效能更高。注意:回答這種方式的話需要了解EventBus的使用。請介紹下Android中常用的五種布局。
a、五大布局是:FrameLayout(幀布局),LinearLayout (線性布局),AbsoluteLayout(絕對布局),RelativeLayout(相對布局),TableLayout(表格布局)
b、FrameLayout
從屏幕的左上角開始布局,疊加顯示, 實際應用 播放器的暫停按鈕.
c、LinearLayout
線性布局,這個東西,從外框上可以理解為一個div,他首先是一個一個從上往下羅列在屏幕上。每一個LinearLayout里面又可分為垂直布局和水平布局)。
d、AbsoluteLayout
絕對布局用X,Y坐標來指定元素的位置
android:layout_x="20px" android:layout_y="12px"
指定平板機型的游戲開發、機頂盒開發中經常用到絕對布局。
e、RelativeLayout
相對布局可以使用另一個控件或者父窗體為參照物,來確定控件在界面上的位置。這種布局可以處理復雜的界面,比線性布局的嵌套結構更節約內存和CPU。
f、TableLayout
表格布局類似Html里面的Table。每一個TableLayout里面有表格行TableRow,TableRow里面可以具體定義每一個元素,設定他的對齊方式 android:gravity="" ??梢杂糜趏a 自動化 生成報表。目前基本被廢棄了。談談UI中, Padding和Margin有什么區別?
Padding 是對控件的內容, margin是控件對父窗體.描述JSON數據的Header和Body功能
a、JSON本身只是規定了數據格式,并沒有Header和Body的約定。此題考察的是面試者是否有工作經驗。
b、在正式的項目中,傳輸的JSON字符串會約定好傳遞一個header代表請求的異常狀態,此時body存放才是正真的bean數據。類似下面的格式:
說明JSON和XML兩者的特性
a、都是傳遞數據使用的格式化字符串
b、Json的格式比較精簡,XML的格式比較復雜,在移動領域里為了節約流量,大多是使用json
c、Xml有更強的擴展性,在一些特殊需求里只能使用xml請解析下面的JSON數組
a、 字符串可以亂寫,json數組不能亂拼。這個數組的格式是錯誤的,item的數據格式不一致,根本就不是一個數組。
b、 工作里遇到這種情況時,應該要求服務端返回的數組內容格式統一,所有的item都包含name、uid、age。同時title應該是和數組平級的數據。
請解釋下在單線程模型中Message、Handler、Message Queuen、Looper之間的關系。
對android主線程的運用和理解。
主線程,也就是UI線程,不能執行耗時的操作。四大組件都是在主線程運行。AIDL的全稱是什么?如何工作?
Android interface definition language (android接口定義語言) , 用來跨進程的訪問方法,
手機衛士 Itelephony 接口掛斷電話.請解釋下Android程序運行時權限與文件系統權限的區別。
a、Android程序執行需要讀取到安全敏感項,比如耗電或者花錢。必需在androidmanifest.xml中聲明相關權限請求, 打電話,訪問網絡,獲取坐標,讀寫sd卡,讀寫聯系人等..安裝的時候會提示用戶。主要是給用戶看的。
b、文件系統的權限是linux權限. 也就是文件的可讀可寫可執行權限。主要是給程序員看的。(如果理解比較多,可以拓展說一下:777自己 同組 其他)Framework工作方式及原理,Activity是如何生成一個view的,機制是什么。
a、 使用反射, 解析配置文件來獲取要使用的類和初始化屬性
b、 四大組件都有自己的生命周期,Framework通過調用不同的生命周期方法,管理四大組件的資源。
c、Activity創建一個view是通過 ondraw 畫出來的, 畫這個view之前,調用onmeasure方法來計算顯示的大小.如何加載音樂、圖片、視頻信息,如何改善其效率。
a、Android提供mediascanner,mediaStore等類,掃描儲存卡里的數據, 音樂文件的信息都會存放到系統的數據庫表中,可以通過MediaProvider獲取,
b、改善顯示效率是個常見問題, 可以從以下幾個方面作答,
分批加載數據, 延時加載數據, 合理使用緩存等.要做一個盡可能流暢的ListView,你平時在工作中如何進行優化的?
a、復用convertView ,節約內存
b、使用ViewHolder ,節約cpu
c、Item布局最好使用相對布局,層級越少越好,節約內存和Cpu。(使用hierarchyview工具查看優化。 )
d、item中有圖片時,異步加載 。避免阻塞主線程。
e、快速滑動時,不加載圖片。避免解析出來Bitmap卻不使用,浪費內存和CPU資源。
f、item中有圖片時,應對圖片進行適當壓縮 。節約內存。
g、實現數據的分頁加載。降低CPU和內存負載峰值。如何在ScrollView中如何嵌入ListView
比如微博詳情界面,微博正文+評論列表。
a、通常情況下我們不會在ScrollView中嵌套ListView,但是如果面試官非讓我嵌套的話也是可以的。
b、在ScrollView添加一個ListView會導致listview控件顯示不全,通常只會顯示一條,這是因為兩個控件的滾動事件沖突導致。所以需要通過listview中的item高度 * count去計算listview的顯示高度,從而使其完整展示。
C、這時listview的所有item都被創建出來,不存在convertview復用,占用內存極高。工作里不建議使用,一般是把微博正文放在listview的headerView里,評論做為列表部分。如何實現讓ListView的條目顯示不一樣的布局?
a、 重寫BaseAdapter的getViewTypeCount()方法返回有幾種條目類型
b、 重寫BaseAdapter的getItemViewType(int position)方法,返回值指定position的條目是什么類型的
c、在BaseAdapter的getView方法中根據當前position的條目類型去加載不同的View啟動應用后,改變系統語言,應用的語言會改變么?
a、已經做了多國語言的話,會變
b、但是設置了android:configChanges="locale",則不會
在項目里增加zh測試修改語言??梢钥吹叫薷恼Z言實際上是界面重啟,重新加載資源。啟動一個程序,可以主界面點擊圖標進入,也可以從一個程序中跳轉過去,二者有什么區別?
a、區別是根據activity在manifest里面的配置,這個activity可能會放在不同的task棧里面。intent設置的flag flag_new_task 也會有影響。
b、比如,步驟一,在文件管理器里打開一個文本或者圖片,按home鍵退出;步驟二,從桌面打開圖片app,可以看到圖片app有自己的堆棧;步驟三,打開文件管理器??梢钥吹綀D片預覽界面在文件管理器的堆棧里。Android程序與Java程序的區別?
a、 Android SDK引用了大部分的Java SDK,少數部分被Android SDK拋棄,比如說界面部分,java.awt swing package除了java.awt.font被引用外,其他都被拋棄,在Android平臺開發中不能使用。
b、 android sdk 添加工具jar ,比如httpclient , pull ,opengl
c、將Java 游戲或者j2me程序移植到Android平臺的過程中,后臺邏輯不需要修改,只要修改前臺的界面就可以。Android中Task任務棧的分配。
a、首先我們來看下Task的定義,Google是這樣定義Task的:a task is what the user experiences as an "application." It's a group of related activities, arranged in a stack. A task is a stack of activities, not a class or an element in the manifest file. 這意思就是說Task實際上是一個Activity棧,通常用戶感受的一個Application就是一個Task。從這個定義來看,Task跟Service或者其他Components是沒有任何聯系的,它只是針對Activity而言的。
b、Activity有不同的啟動模式, 可以影響到task的分配
c、standard: 標準模式,一調用 startActivity()方法就會產生一個新的實例。
d、singleTop: 如果已經有一個實例位于 Activity 棧的頂部時, 就不產生新的實例, 而只是調用Activity 中的 newInstance()方法。如果不位于棧頂,會產生一個新的實例。
e、singleTask: 會在一個新的 task 中產生這個實例,以后每次調用都會使用這個,不會去產生 新的實例了。
f、singleInstance: 這個跟 singleTask 基本上是一樣, 只有一個區別: 在這個模式下的 Activity實例所處的 task 中,只能有這個 activity實例,不能有其他的實例。dvm的進程和Linux的進程, 應用程序的進程是否為同一個概念
a、每個dvm虛擬機都是linux里面的一個進程.
b、dvm的進程是dalivk虛擬機進程,每個android程序都運行在自己的進程里面,
c、三個進程不是一個概念,但是在使用中由于一個dvm虛擬機就是一個linux進程,同時一個虛擬機只運行一個應用,所以也默認三者是同一個可以統一使用。如何判斷是否有SD卡?
配置文件中有sd卡的權限, 通過environment的靜態方法判斷
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED )嵌入式操作系統內存管理有哪幾種, 各有何特性。
頁式,段式,段頁,等 …什么是嵌入式實時操作系統, Android 操作系統屬于實時操作系統嗎?
實時操作系統是指當外界事件或數據產生時,能夠接受并以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,并控制所有實時任務協調一致運行的嵌入式操作系統。
主要用于工業控制、軍事設備、航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬實時兩種,而android是基于linux內核的,因此屬于軟實時。談談對Android NDK的理解。
a、native develop kit 是一個交叉編譯的工具,可以編譯c語言代碼,生成在手機上運行的.so文件,供java語言調用
b、一般在實時性要求高的應用里使用ndk,比如游戲, 圖形渲染, opencv (人臉識別) ,高清解碼等
c、反編譯C語言比Java困難,需要對核心源碼進行保密的時候也可以使用NDK處理
d、我們項目中那些地方用到了ndk, 比如手機影音、百度地圖Android系統中GC什么情況下會出現內存泄露呢? 內存溢出(OOM)
a、Java 內存泄露的根本原因就是 保存了不可能再被訪問的變量類型的引用
b、如果程序中存在對無用對象的引用,那么這些對象就會駐留內存,消耗內存,因為無法讓垃圾回收器GC驗證這些對象是否不再需要。如果存在對象的引用,這個對象就被定義為"有效的活動",同時不會被釋放。
c、要確定對象所占內存將被回收,我們就要務必確認該對象不再會被使用。典型的做法就是把對象數據成員設為null或者從集合中移除該對象。
d、當局部變量不需要時,不需明顯的設為null,因為一個方法執行完畢時,這些引用會自動被清理。
e、如果出現大量的內存泄露,導致有內存被對象占用不能釋放,最終導致內存耗盡無法創建新的對象,就會出現內存溢出(OOM)
Java帶垃圾回收的機制,為什么還會內存泄露呢?
Vector v = new Vector(10);
for (int i = 1; i < 100; i++) {
Object o = new Object();
v.add(o);
o = null;
}//此時,所有的Object對象都沒有被釋放,因為變量v引用這些對象。
Handler h = new Handler();
- java中的soft reference是個什么東西
a、StrongReference 是 Java 的默認引用實現, 它會盡可能長時間的存活于 JVM 內, 當沒有任何對象指向它時 GC 執行后將會被回收
b、SoftReference 會盡可能長的保留引用直到 JVM 內存不足時才會被回收(虛擬機保證), 這一特性使得 SoftReference 非常適合緩存
c、WeekReference 在每次GC時都被回收
d、在以前的開發里,圖片的緩存多數使用軟引用,保證內存不足時圖片能夠及時被回收。在Android2.3版本之后軟引用的功能被修改為弱引用一樣,導致圖片總是要不斷重新加載,性能很差。新的圖片緩存實現都是LruCache機制。 - 說說LruCache底層原理
a、LruCache使用一個LinkedHashMap簡單的實現內存的緩存,沒有軟引用,都是強引用。如果添加的數據大于設置的最大值,就刪除最先緩存的數據來調整內存。
b、通過構造方法初始化的maxSize值,它表示這個緩存的最大值是多少。一般都是可用的內存大小的八分之一, Runtime.getRuntime().maxMemory() / 8,
c、插入圖片時首先會判斷插入后的size大小是否超過maxSize,如果超過了,就刪除最長時間未使用的緩存。這個操作將一直循環下去,直到size比maxSize小或者緩存為空。 - 如何避免oom異常
OOM內存溢出,想要避免OOM異常首先我們要知道什么情況下會導致OOM異常。
a. 圖片過大導致OOM
Android 中用bitmap時很容易內存溢出,比如報如下錯誤:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget。
解決方法:
方法1: 等比例縮小圖片
以上代碼可以優化內存溢出,但它只是改變圖片大小,并不能徹底解決內存溢出。
方法2:使用LruCache機制管理圖片。限制圖片的內存上限,并及時地進行recyle()操作
方法3:使用加載圖片框架處理圖片,如專業處理加載圖片的ImageLoader圖片加載框架。還有我們學的XUtils的BitMapUtils來做處理。
b.界面切換導致oom
一般情況下,開發中都會禁止橫屏的。因為如果是來回切換話,activity的生命周期會重新銷毀然后創建。
有時候我們會發現這樣的問題,橫豎屏切換N次后 OOM了。
這種問題沒有固定的解決方法,但是我們可以從以下幾個方面下手分析。
1、看看頁面布局當中有沒有大的圖片,比如背景圖之類的。
去除xml中相關設置,改在程序中設置背景圖(放在onCreate()方法中):
在Activity destory時注意,drawable.setCallback(null); 防止Activity得不到及時的釋放。
2、跟上面方法相似,直接把xml配置文件加載成view 再放到一個容器里,然后直接調用 this.setContentView(View view);方法,避免xml的重復加載。
3、 在頁面切換時盡可能少地重復執行一些代碼
比如:重復調用數據庫,反復使用某些對象等等......
c.查詢數據庫沒有關閉cursor
程序中經常會進行查詢數據庫的操作,但是經常會有使用完畢Cursor后沒有關閉的情況。如果我們的查詢結果集比較小,對內存的消耗不容易被發現,只有在常時間大量操作的情況下才會出現內存問題,這樣就會給以后的測試和問題排查帶來困難和風險。
d.構造Adapter沒有使用convertview
在使用ListView的時候通常會使用Adapter,那么我們應該盡可能的使用ConvertView。
e、為變量設置合適的作用范圍
盡量小的變量作用范圍可以保證變量盡快被回收,節約內存。
- 根據自己的理解描述下Android數字簽名。
a、所有的應用程序都必須有數字證書,Android系統不會安裝一個沒有數字證書的應用程序
b、Android程序包使用的數字證書可以是自簽名的,不需要一個權威的數字證書機構簽名認證 (對于網站而言,如果要證明自己是可信的,他們需要使用權威證書網站的證書)
c、如果要正式發布一個Android ,必須使用一個合適的私鑰生成的數字證書來給程序簽名,而不能使用adt插件或者ant工具生成的調試證書來發布。
d、數字證書都是有有效期的,Android只是在應用程序安裝的時候才會檢查證書的有效期。如果程序已經安裝在系統中,即使證書過期也不會影響程序的正常功能 - 什么是ANR 如何避免它?
a、在Android上,主線程使用來更新UI的,如果你的應用程序在主線程做耗時的操作,導致有一段時間響應不夠靈敏,系統會向用戶顯示一個對話框,這個對話框稱作應用程序無響應(ANR:Application Not Responding)對話框。
b、要避免這個問題可以把耗時的操作放在子線程里面完成, handler message,AsynTask , intentservice.等 - android中的動畫有哪幾類,它們的特點和區別是什么?
幀動畫, 補間動畫, 屬性動畫;
? 幀動畫(Frame Animation)一般用于圖片的切換,實現生成連續的gif圖效果
? 補間動畫(Tween Animation)分為平移(Translate)、旋轉(Rotate)、縮放(Scale)、不透明度(Alpha);補間動畫只是改變了View的顯示效果
? 屬性動畫(Property Animation),Android3.0 (API11)及以后出現的功能,3.0之前的版本可使用github第三方開源庫nineoldandroids.jar進行支持。支持對所有View能更新的屬性的動畫,如translationX水平平移, translationY豎直平移,alpha透明度, left左邊位置, rotation旋轉角度, scale縮放等,
? 屬性動畫不僅能實現補間動畫的所有效果,而且是對view或任意對象的屬性的不斷進行的值操作。比如一個Button的位移,補間動畫只是重繪了view,并沒有真正的去改變Button的位置,點擊事件還是停留在原來的位置,而屬性動畫就是在真正改變Button的位置; - 如何屏幕適配
Android的屏幕適配主要有五種方式:
a、layout適配,根據不同的屏幕大小加載不同文件夾下的布局文件圖片適配.
b、權重適配,設置顯示比例。
c、根據不同屏幕大小使用不同文件夾下的圖片。使用9Patch圖片。
d、dimens.xml文件適配,根據不同的手機的密度加載不同文件夾下的dimens.xml
e、java代碼適配 - Emoji表情實現
a、使用SpannableString可以把TextView或EditText的一部分文本替換為圖片。
b、Span不僅可以在Textview、Edittext中把一部分內容設置為圖片,還可以設置一部分內容的樣式,如:字體、顏色、點擊事件等。
SpannableString spannableString = new SpannableString("0123456789");
Drawable icon = getResources().getDrawable(R.drawable.ic_launcher);
ImageSpan span = new ImageSpan(icon);
spannableString.setSpan(span,2,3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
自定義控件常用的方法
a、onMeasure方法:測量控件的大小
b、onLayout方法:對子View進行排版
c、onDraw方法:把控件畫出來
d、onTouch方法:處理觸摸事件Android中touch事件的傳遞機制是怎樣的?
a、Touch事件傳遞的相關API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
b、Touch事件相關的類有View、ViewGroup、Activity
c、Touch事件會被封裝成MotionEvent對象,該對象封裝了手勢按下、移動、松開等動作
d、Touch事件通常從Activity#dispatchTouchEvent發出,只要沒有被消費,會一直按布局層次往下傳遞,到最底層的View。
e、如果Touch事件傳遞到的每個View都不消費事件,那么Touch事件會反向向上傳遞,最終交由Activity#onTouchEvent處理.
f、onInterceptTouchEvent為ViewGroup特有,可以攔截事件.
g、Down事件到來時,如果一個View沒有消費該事件,那么后續的MOVE/UP事件都不會再給它說說mvc模式的原理,它在android中的運用。
a、MVC英文即Model-View-Controller,即把一個應用的輸入、處理、輸出流程按照Model、View、Controller的方式進行分離,這樣一個應用被分成三個層——模型層、視圖層、控制層。
b、Android里MVC模式的使用隨處都可以見到。最基本的就是控件對象,xml布局文件,Activity類。以及數據集合,ListView,Adapter。udp連接和TCP的不同之處,Socket是什么?
a、tcp確保數據安全,建立連接時有三次握手過程。面向連接流
b、udp 不關心數據是否達到,是否阻塞。面向無連接
c、畫面優先. tcp 流暢優先 udp
d、協議只是一個文檔約定,Socket是Java語言里對TCP/IP協議的實現
描述下這三次TCP對話的簡單過程:
主機A向主機B發出連接請求數據包:“我想給你發數據,可以嗎?”,這是第一次對話;
主機B向主機A發送同意連接和要求同步(同步就是兩臺主機一個在發送,一個在接收,協調工作)的數據包:“可以,你什么時候發?”,這是第二次對話;
主機A再發出一個數據包確認主機B的要求同步:“我現在就發,你接著吧!”,這是第三次對話。
三次“對話”的目的是使數據包的發送和接收同步,經過三次“對話”之后,主機A才向主機B正式發送數據。手寫一個單例模式,能不能保證使用時對象的唯一性
a、餓漢式和懶漢式的單例模式代碼到處都有,請自行查找學習
b、這兩種方法都不能保證使用時對象的唯一性。比如,當對象是可序列化的,保存對象到本地后,每次反序列化都是生成了一個新的對象。
c、最好的實現單例模式的方案為,編寫一個包含單個元素的枚舉。程序員無法自己new出枚舉對象,保證了只能有一個對象。同時枚舉的序列化機制也不會在反序列化時創建出新的對象,保證對象的唯一性。你知道推送的原理嗎?調用哪個方法可以接收消息,傳遞哪些參數呢?
a、傳統獲取服務器數據使用的是pull模式,是客戶端向服務器請求數據。從客戶端發起連接請求,獲取到服務器數據后就關閉連接。當連接斷開后,服務器就會失去客戶端的地址,因此無法主動向客戶端發送消息。
b、推送(push)是服務主動向客戶端發送數據。它的原理是保持一個長連接,當客戶端和服務器建立連接后不再斷開,這樣服務器隨時有新消息都可以發送給客戶端。
c、至于如何獲取推送消息。由于服務端傳來推送消息的時間是不確定的,這里只能等待推送SDK的回調,比如通過注冊監聽或者廣播接收者。不同的廠商的推送SDK可能會有不同的處理方案,以百度推送SDK來說,是通過廣播接收者獲取推送數據。開發中都使用到哪些框架、平臺
EventBus(事件處理)
JPush(推送平臺)
友盟(統計平臺)
有米(優米)(廣告平臺)
百度地圖
bmob(服務器平臺、短信驗證、郵箱驗證、第三方支付)
阿里云OSS(云存儲)
ShareSDK(分享平臺、第三方登錄)
Gson(解析json數據框架)
imageLoader (圖片處理框架)
zxing (二維碼掃描)開發過程中使用到哪些自定義控件
pull2RefreshListView 下拉刷新
LazyViewPager 只加載當前頁
SlidingMenu 側欄菜單
ToggleButton 滑動的開關android開發中怎么去調試bug
a、logcat
b、斷點 debug
c、從版本控制系統檢出代碼,查找出錯的提交。比如一個月前沒有的問題,突然出現,可以將代碼回退到一個月前,使用二分法檢查是哪一次提交的代碼導致出現問題。寫10個簡單的linux命令
文件管理:ls mv rm cd mkdir
網絡管理:ping ifconfig
文件搜索、編輯:find grep vi cat
查看系統資源占用:du df ps topJNI調用常用的兩個參數
JNIEnv *env, jobject javaThisddms 和traceview的區別.
a、 DDMS全稱daivilk debug manager system,是Android自帶的debug界面
b、TraceView是Android的性能分析工具,是DDMS組成的一部分
1.在應用的主activity的onCreate方法中加入Debug.startMethodTracing("要生成的traceview文件的名字");
2.同樣在主activity的onStop方法中加入Debug.stopMethodTracing();
3.同時要在AndroidManifest.xml文件中配置權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
3.重新編譯,安裝,啟動服務,測試完成取對應的traceview文件(adb pull /sdcard/xxxx.trace)。
4.直接在命令行輸入traceview xxxxtrace,彈出traceview窗口,分析對應的應用即可。
- 手寫算法
a、一般面試考察的都是計算機入門的基本算法,比如排序和查找,并且會要求在紙上手寫Java代碼或偽代碼。
b、排序最基礎的是冒泡排序。如果可以使用快速排序,可以認為學習能力優秀。
c、查找最基礎的算法是有序數組的折半查找。
d、對于復雜的測試,比如讓現場寫一個自定義控件,可以分析一下實現思路。 - 項目如何向低版本兼容
a、樣式兼容:
(1)使用兼容包中的樣式,如v7\v4 中的Compat 相關樣式。
(2)定義多個不同value文件夾,不同版本指定不同樣式。
b、布局兼容:
定義多個不同layout-verson(verson為版本數字) 的文件夾,不同版本指定不同的布局文件。
c、高版本代碼兼容方式:
(1)盡量使用兼容包中的API,如getSupportActionBar, getSupportFragmentManager() 等。
(2)使用系統Version 來判斷,使低版本系統不能執行高版本代碼。同時使用 @TargetApi 來消除eclipse、AS 等工具報錯。 - 介紹一下你的項目架構
架構是程序的骨架,確定了總體的接口,要求具體的子類實現細節處理。并不是非要用到反射、注解等高級技術才能叫架構。
a、界面架構 BaseActivity,BaseFragmen。拆解onCreate過程為initView、initListener、initData
b、網絡架構 三級網絡封裝
c、圖片、文件、數據庫等數據數據管理架構