1 Android activity生命周期
onCreate() ----- onStart() ----- onRestart() ----- onResume ----- onPause() ------ onStop() ----- onDestory()
onCreate(): 創建Activity時調用,設置在該方法中,還以Bundle的形式提供對以前存儲的任何狀態的訪問。
onStart(): Activity變為在屏幕上對用戶可見時調用。
onResume(): Activity開始與用戶交互時調用(無論是啟動還是重新啟動一個活動,該方法總是被調用。
onPause(): Activity被暫停或收回cpu和其他資源時調用,該方法用戶保護活動狀態的,也是保護現場。
onStop(): Activity被停止并轉為不可見階段及后續的生命周期事件時調用。
onRestart(): Activity被重新啟動時調用。該活動仍然在棧中,而不是啟動新的Activity。
1、完整生命周期: 即從一個Activity從出現到消失,對應的周期方法是從onCreate()到onDestroy()。
2、可見生命周期: 當Activity處于可以用戶看見的狀態,但不一定能與用戶交互時,將多次執行從onStart()到onStop()。
3、前景生命周期: 當Activity處于Activity棧最頂端,能夠與其他用戶進行交互時,將多次執行從onResume()到onPause()-
2 Activity 跳轉時調用的生命周期
onCreate()//在Activity生命周期開始時調用。
onRestoreInstanceState()//用來恢復UI狀態。
onRestart()//當Activity重新啟動時調用。
onStart()//當Activity對用戶即將可見時調用。
onResume()//當Activity與用戶交互時,繪制界面。
onSaveInstanceState()//即將移出棧頂保留UI狀態時調用。
onPause()//暫停當前活動Activity,提交持久數據的改變,停止動畫或其他占用GPU資源的東西,由于下一個Activity在這個方法返回之前不會resume,所以這個方法的代碼執行要快。
onStop()//Activity不再可見時調用。
onDestroy()//Activity銷毀棧時被調用的最后一個方法
3 橫豎屏切換時Activity的生命周期
1、不設置Activity的 android: configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次。
2、設置Activity的android: configChanges=“orientation”時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次。
3、設置Activity的android: configChanges=“orientation|keyboardHidden”時,切屏不會重新調用各個生命周期,只會執行onConfiguration方法
4 如何將一個Activity設置成窗口的樣式,style和theme的區別。
1.什么是Style及Theme?兩者有何區別
(1) Theme是針對窗體級別的,改變窗體樣式的,如窗口標題、邊框等。不能作用于單個View組件,是對整個應用的所有Activity或單個Activity起作用。
(2) Style是針對窗體元素級別的,改變指定控件或者Layout的樣式
使用Style
(1)創建Style
(1) 在res\values\下創建styles.xml文件
(2)添加<resources>節點(根節點)
(3)添加自定義的style及其屬性
style的寫法通常為:
<style name="MyStyle" [parent="PARENT"]>
<item name="[ATTR]">[VALUE]</item>
</style>
其中,parent屬性為其父style的名字(可選),通過設置該值,可繼承其它style的屬性。當我們需要對現有的style的屬性。當我們需要對現有的style做微小的改變
(2)為控件指定Style
<EditText android:layout_height="wrap_content"
android:text="EditText"
style="@style/Title"
android:layout_width="fill_parent"
android:id="@+id/editText1"></EditText>
Theme的使用
1.在setContentView()方法之前設置Theme:setTheme(R.style.XXX);
2.在mainfest文件中加入Theme Theme就是Style
AndroidManifest.xml中:
<application android:theme="@android:style/theme">,
<activity android:theme="@android:style/theme">,
在R.attr定義中以window開頭的一些屬性只對theme有效。
如果一個應用使用了theme,同時應用下的view也使用了style,那么當theme與樣式style發生沖突時,style的優先級高于主題。
第一種方法:
在styles.xml文件中,可以新建如下的類似Dialog的style。<style name=“Theme.FloatActivity” parent=“android:style/Theme.Dialog”> </style>。
第二種方法:
在AndroidManifest.xml中在需要顯示為窗口的Activity中添加如下屬性: android: theme=“@style/Theme.FloatActivity”即可。也可以直接添加對應需要展示為Dialog style的Activity的android: theme屬性為android: theme=“@ android: style/Theme.Dialog”
5 兩個Activity之間傳遞數據
可以在Intent對象中利用Extra來傳遞存儲數據。
在Intent的對象請求中,使用putExtra(“鍵值對的名字”,”鍵值對的值”);在另外一個Activity中將Intent中的請求數據取出來:
Intent intent = getIntent();
String value = intent.getStringExtra(“testIntent”);
6 怎么讓在啟動一個Activity是就啟動一個service?
首先定義好一個service,然后在Activity的onCreate里面進行連接并bindservice或者直接startService。
7 Activity怎么和service綁定,怎么在activity中啟動自己對應的service?
1、activity能進行綁定得益于Serviece的接口。為了支持Service的綁定,實現onBind方法。
2、Service和Activity的連接可以用ServiceConnection來實現。需要實現一個新的ServiceConnection,重現onServiceConnected和OnServiceDisconnected方法,一旦連接建立,就能得到Service實例的引用。
3、執行綁定,調用bindService方法,傳入一個選擇了要綁定的Service的Intent(顯示或隱式)和一個你實現了的ServiceConnection的實例
8 什么是Service以及描述下它的生命周期。Service有哪些啟動方法,有什么區別,怎樣停用Service?
Android Service是運行在后臺的代碼,不能與用戶交互,可以運行在自己的進程,也可以運行在其他應用程序進程的上下文里。需要通過某一個Activity或者Context對象來調用。Service有兩個啟動方法,分別是Context.startService()和Context.bindService()。如果在Service執行耗時的操作需要啟動一個新線程來執行。
Android Service只繼承了onCreate(), onStart(),onDestroy()三個方法,當我們第一次啟動Service時,先后調用onCreate(), onStart()這兩個方法,當停止Service時,則執行onDestroy()方法時。如果Service已經啟動了,當我們再次啟動Service時,不會再執行onCreate()方法,而是直接執行onStart()方法。
9 什么時候使用Service?
比如播放多媒體的時候,用戶啟動了其他Activity,這個時候程序要在后臺繼續播放,比如檢測SD卡上文件的變化,再或者在后臺記錄你的地理信息位置的改變等等。
10 描述一下Intent 和 Intent Filter。
Intent在Android中被翻譯為”意圖”,他是三種應用程序基本組件-Activity,Service和broadcast receiver之間相互激活的手段。在調用Intent名稱時使用ComponentName也就是類的全名時為顯示調用。這種方式一般用于應用程序的內部調用,因為你不一定會知道別人寫的類的全名。而Intent Filter是指意圖過濾,不出現在代碼中,而是出現在android Manifest文件中,以<intent-filter>的形式。(有一個例外是broadcast receiver的intentfilter是使用Context.registerReceiver()來動態設定的,其中intent filter也是在代碼中創建的)
一個intent有action,data,category等字段。一個隱式intent為了能夠被某個intent filter接收,必須通過3個測試,一個intent為了被某個組件接收,則必須通過它所有的inte
nt filter中的一個。
11 Intent傳遞數據時,可以傳遞哪些類型數據?
intent間傳送數據一般有兩種常用的方法: 1、extra 2、data。
extra可以用Intent.putExtra放入數據。新啟動的Activity可用Intent.getExtras取出Bundle,然后用Bundles.getLong,getInt,getBoolean,getString等函數來取放進去的值。
Data則是傳輸url。url可以是指我們熟悉的http,ftp等網絡地址,也可以指content來指向ContentProvider提供的資源。Intent.setData可以放入數據,Intent.getData可以取出數據。
12 android 中有哪幾種解析xml的類?官方推薦哪種?以及它們的原理和區別。
XML解析主要有三種方式,SAX、DOM、PULL。常規在PC上開發我們使用Dom相對輕松些,但一些性能敏感的數據庫或手機上還是主要采用SAX方式,SAX讀取是單向的,優點:不占內存空間、解析屬性方便,但缺點就是對于套嵌多個分支來說處理不是很方便。而DOM方式會把整個XML文件加載到內存中去,這里Android開發網提醒大家該方法在查找方面可以和XPath很好的結合如果數據量不是很大推薦使用,而PULL常常用在J2ME對于節點處理比較好,類似SAX方式,同樣很節省內存,在J2ME中我們經常使用的KXML庫來解析。
13 如何啟用Service,如何停用Service。
服務的開發比較簡單,如下:
第一步:繼承Service類
public classSMSService extends Service {}
第二步:在AndroidManifest.xml文件中的<application>節點里對服務進行配置:<service android:name=".SMSService" />
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。
如果打算采用Context.startService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法并不會導致多次創建服務,但會導致多次調用onStart()方法。采用startService()方法啟動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
如果打算采用Context.bindService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接著調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法并不會導致多次創建服務及綁定(也就是說onCreate()和onBind()方法并不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法。
Service常用生命周期回調方法如下:
onCreate() 該方法在服務被創建時調用,該方法只會被調用一次,無論調用多少次startService()或bindService()方法,服務也只被創建一次。
onDestroy()該方法在服務被終止時調用。
與采用Context.startService()方法啟動服務有關的生命周期方法
onStart() 只有采用Context.startService()方法啟動服務時才會回調該方法。該方法在服務開始運行時被調用。多次調用startService()方法盡管不會多次創建服務,但onStart() 方法會被多次調用。
與采用Context.bindService()方法啟動服務有關的生命周期方法
onBind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法并不會導致該方法被多次調用。
onUnbind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務解除綁定時被調用
14 final,finally,finalize的區別
final—修飾符(關鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。
finally—再異常處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執行,然后控制就會進入 finally 塊(如果有的話)。
finalize—方法名。Java技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。
15 ANR是個什么玩意
ANR,是“Application Not Responding”的縮寫,即“應用程序無響應”。系統會向用戶顯示一個對話框,用戶可以選擇“等待”而讓程序繼續運行,也可以選擇“強制關閉”。
在Android中,應用程序的響應是由Activity Manager和WindowManager系統服務監視的 。當它監測到A、B、C情況中的一個時,Android就會針對特定的應用程序顯示ANR:
A.在5秒內沒有響應輸入的事件(例如,按鍵按下,屏幕觸摸)--主要類型
B.BroadcastReceiver在10秒內沒有執行完畢
C.Service在特定時間內(20秒內)無法處理完成--小概率類型
造成ABC的原因有很多,比如在主線程中做了非常耗時的操作,如下載,io異常等。還需要注意的是產生這種ANR的前提是要有輸入事件,如果用戶沒有觸發任何輸入事件,即便是主線程阻塞了,也不會產生ANR,因為InputDispatcher沒有分發事件給應用程序,當然也不會檢測處理超時和報告ANR了。
1.如何分析ANR
ANR發生時都會在log中輸出錯誤信息,從log中可以獲得ANR的類型,CPU的使用情況,CPU使用率過高有可能是CPU饑餓導致了ANR。CPU使用率過低說明主線程被block了,如果IOwait高是因為主線程進行I/O操作造成的。
除了log輸出外,你會發現各個應用進程和系統進程的函數堆棧信息都輸出到了一個/data/anr/traces.txt的文件中,這個文件是分析ANR原因的關鍵文件.要獲取到該文件可使用adb指令進行賦權后拉出查看調用stack。通過log、trace.text、代碼結合分析ANR的成因(iowait?Memoryleak?Block?)
2.怎么避免ANR
要避免問題的產生,就要抓住問題產生的原因(ABC三種):
(1)避免在主線程上進行復雜耗時的操作,比如說發送接收網絡數據/進行大量計算/操作數據庫/讀寫文件等。這個可以通過使用AsyncTask或者使用多線程來實現。
(2)broadCastReceiver 要進行復雜操作的的時候,可以在onReceive()方法中啟動一個Service來處理
(3)在設計及代碼編寫階段避免出現出現同步/死鎖或者錯誤處理不恰當等情況。
16 接口和抽象類有什么區別
接口和抽象類的概念不一樣。接口是對動作的抽象,抽象類是對根源的抽象。
抽象類表示的是,這個對象是什么。接口表示的是,這個對象能做什么。比如,男人,女人,這兩個類(如果是類的話……),他們的抽象類是人。說明,他們都是人。
人可以吃東西,狗也可以吃東西,你可以把“吃東西”定義成一個接口,然后讓這些類去實現它.
所以,在高級語言上,一個類只能繼承一個類(抽象類)(正如人不可能同時是生物和非生物),但是可以實現多個接口(吃飯接口、走路接口)。
17 wait()和sleep()的區別
1、 這兩個方法來自不同的類分別是,sleep來自Thread類,和wait來自Object類。
sleep是Thread的靜態類方法,誰調用的誰去睡覺,即使在a線程里調用b的sleep方法,實際上還是a去睡覺,要讓b線程睡覺要在b的代碼中調用sleep。
2、 鎖: 最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
sleep不出讓系統資源;wait是進入線程等待池等待,出讓系統資源,其他線程可以占用CPU。一般wait不會加時間限制,因為如果wait線程的運行資源不夠,再出來也沒用,要等待其他線程調用notify/notifyAll喚醒等待池中的所有線程,才會進入就緒隊列等待OS分配系統資源。sleep(milliseconds)可以用時間指定使它自動喚醒過來,如果時間不到只能調用interrupt()強行打斷。
Thread.sleep(0)的作用是“觸發立刻重新進行一次CPU競爭”。
3、使用范圍:wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用。
synchronized(x){ x.notify() //或者wait() }
18 hashset()和treeset()區別
HashSet
HashSet有以下特點
1、 不能保證元素的排列順序,順序有可能發生變化
2、不是同步的
3、集合元素可以是null,但只能放入一個null
當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,然后根據 hashCode值來決定該對象在HashSet中存儲位置。簡單的說,HashSet集合判斷兩個元素相等的標準是兩個對象通過equals方法比較相等,并且兩個對象的hashCode()方法返回值相 等
注意,如果要把一個對象放入HashSet中,重寫該對象對應類的equals方法,也應該重寫其hashCode()方法。其規則是如果兩個對 象通過equals方法比較返回true時,其hashCode也應該相同。另外,對象中用作equals比較標準的屬性,都應該用來計算 hashCode的值。
TreeSet類
TreeSet是SortedSet接口的唯一實現類,TreeSet可以確保集合元素處于排序狀態。TreeSet支持兩種排序方式,自然排序 和定制排序,其中自然排序為默認的排序方式。向TreeSet中加入的應該是同一個類的對象。
TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關系,然后將元素按照升序排列。
Java提供了一個Comparable接口,該接口里定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該接口的對象就可以比較大小。
obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大于obj2,如果是 負數,則表明obj1小于obj2。
如果我們將兩個對象的equals方法總是返回true,則這兩個對象的compareTo方法返回應該返回0
定制排序
自然排序是根據集合元素的大小,以升序排列,如果要定制排序,應該使用Comparator接口,實現 int compare(T o1,T o2)方法。
最重要:
1、TreeSet 是二差樹實現的,Treeset中的數據是自動排好序的,不允許放入null值。
2、HashSet 是哈希表實現的,HashSet中的數據是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重復,就如數據庫中唯一約束。
3、HashSet要求放入的對象必須實現HashCode()方法,放入的對象,是以hashcode碼作為標識的,而具有相同內容的 String對象,hashcode是一樣,所以放入的內容不能重復。但是同一個類的對象可以放入不同的實例 。
19 array、arraylist 、list區別
[] 是針對特定類型、固定長度的。
List 是針對特定類型、任意長度的。
Array 是針對任意類型、固定長度的。
ArrayList 是針對任意類型、任意長度的。
20 public、protected、default、private作用域
java中修飾符 public protected 默認 (frinedly) private
訪問權限 作用域 當前類 同一package 子孫類 其它package public true true true true
protected true true true false
friendly true true false false
private true false false false
注:protected對友元及子孫類有作用域,在其它包的子孫類中需要用子類的對象來調用以protected修飾符修飾的方法和成員,不能用父類的對象來調用。friendly修飾符,在java中部存在,只是表示友元可以調用,即同一個包下。
以下范圍依次由嚴到寬:private :本類訪問;default :表示默認,不僅本類訪問,而且是同包可見。Protected:同包可見+不同包的子類可見Public :表示所有的地方均可見。
21 安卓view繪制機制和加載過程,寫出整個過程
基本分為measure、layout、draw 過程
22 面向對象的三個特征
1、封裝
2、繼承
3、多態
所謂封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。封裝是面向對象的特征之一,是對象和類概念的主要特性。 簡單的說,一個類就是一個封裝了數據以及操作這些數據的代碼的邏輯實體。在一個對象內部,某些代碼或某些數據可以是私有的,不能被外界訪問。通過這種方式,對象對內部數據提供了不同級別的保護,以防止程序中無關的部分意外的改變或錯誤的使用了對象的私有部分。
所謂繼承是指可以讓某個類型的對象獲得另一個類型的對象的屬性的方法。它支持按級分類的概念。繼承是指這樣一種能力:它可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。 通過繼承創建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“超類”。繼承的過程,就是從一般到特殊的過程。要實現繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來實現。繼承概念的實現方式有二類:實現繼承與接口繼承。實現繼承是指直接使用基類的屬性和方法而無需額外編碼的能力;接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現的能力;
所謂多態就是指一個類實例的相同方法在不同情形有不同表現形式。多態機制使具有不同內部結構的對象可以共享相同的外部接口。這意味著,雖然針對不同對象的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以調用
23 Java多線程安全線程
保證線程安全的三個訣竅:1、不要跨線程訪問共享變量。2、使共享變量是final類型的。3、將共享變量的操作加上同步。
24 int和Integer區別
int是基本數據類型
Integer是其包裝類,注意是一個類。
一是為了在各種類型間轉化,通過各種方法的調用。否則 你無法直接通過變量轉化。
比如,現在int要轉為String
int a=0;
String result=Integer.toString(a);
在java中包裝類,比較多的用途是用在于各種數據類型的轉化中。
25 fragment生命周期
可以看到Fragment比Activity多了幾個額外的生命周期回調方法:
onAttach(Activity)
當Fragment與Activity發生關聯時調用。
onCreateView(LayoutInflater, ViewGroup,Bundle)
創建該Fragment的視圖
onActivityCreated(Bundle)
當Activity的onCreate方法返回時調用
onDestoryView()
與onCreateView想對應,當該Fragment的視圖被移除時調用
onDetach()
與onAttach相對應,當Fragment與Activity關聯被取消時調用
注意:除了onCreateView,其他的所有方法如果你重寫了,必須調用父類對于該方法的實現
26 View的生命周期
View 的關鍵生命周期為 [改變可見性] --> 構造View --> onFinishInflate --> onAttachedToWindow --> onMeasure --> onSizeChanged --> onLayout --> onDraw --> onDetackedFromWindow
27 Activity異常銷毀狀態下的數據保存與恢復
在界面異常銷毀之前會先調用onSaveInstanceState保存數據,這個方法一般是在onPause之后調用,我們可以在這個地方保存當前界面的數據和界面狀態。當系統為我們重新創建Activity的時候,系統會調用onCreate和onRestoreInstanceState講保存的數據返回給我們,我們從中取出保存的數據來為用戶恢復到崩潰前的界面,這里有一點要注意的是,onCreate每個創建都會被調用,而onRestoreInstanceState只有在onSaveInstanceState調用之后的創建才會被調用,開發者可以根據需求自己權衡使用哪個方法來恢復數據。
28#