01:Activity生命周期如失?
這幾乎是個老少咸宜,永遠不會過時的問題限嫌,而且極有可能是第一個問題靴庆。這個問題當然沒什么好講的啦,死記硬背是沒什么用的了怒医,關(guān)鍵是理解炉抒。本人就曾遇到這個問題的變種問題,問onStart(),與onResume()有什么區(qū)別稚叹?如果面試官拋出這個問題焰薄,是不是有點措手不及。今天又聽說有同學遭遇了更變態(tài)的問題:什么情況下Activity走了onCreat()扒袖,而不走onStart()蛤奥,這簡直就是腦筋急轉(zhuǎn)彎嘛。
知識點鏈接:http://www.reibang.com/p/c5604ccd40ea
02:什么情況下僚稿,Activity的onNewInstent()方法會執(zhí)行凡桥?Activity的啟動模式相關(guān)。
當此Activity的實例已經(jīng)存在蚀同,并且此時的啟動模式為SingleTask
和SingleInstance
缅刽,另外當這個實例位于棧頂,且啟動模式為SingleTop
時也會觸發(fā)onNewInstance()方法蠢络。
03:Service生命周期衰猛?
這里要注意service有兩種啟動方式:startService()和bindService()
在Service的生命周期中,常用的方法有:
4個手動調(diào)用的方法
startService() //啟動服務(wù)
stopService() //關(guān)閉服務(wù)
bindService() //綁定服務(wù)
unbindService() //解綁服務(wù)```
5個內(nèi)部自動調(diào)用的方法
onCreat() //創(chuàng)建服務(wù)
onStartCommand() //開始服務(wù)
onDestroy() //銷毀服務(wù)
onBind() //綁定服務(wù)
onUnbind() //解綁服務(wù)```
- 手動調(diào)用startService()啟動服務(wù)刹孔,自動調(diào)用內(nèi)部方法:onCreate(),onStartCommand(),如果一個Service被startService()多次啟動啡省,那么onCreate()也只會調(diào)用一次。
- 手動調(diào)用stopService()關(guān)閉服務(wù),自動調(diào)用內(nèi)部方法:onDestory()卦睹,如果一個Service被啟動且被綁定畦戒,如果在沒有解綁的前提下使用stopService()關(guān)閉服務(wù)是無法停止服務(wù)的。
- 手動調(diào)用bindService()后结序,自動調(diào)用內(nèi)部方法:onCreate()障斋、onBind()。
- 手動調(diào)用unbindService()后徐鹤,自動調(diào)用內(nèi)部方法:onUnbind()垃环、onDestory()。
- startService()和stopService()只能開啟和關(guān)閉Service返敬,無法操作Service遂庄,調(diào)用者退出后Service仍然存在;bindService()和unbindService()可以操作Service劲赠,調(diào)用者退出后涧团,Service隨著調(diào)用者銷毀。
Service知識總結(jié)
Android activity和service的生命周期對比
Service服務(wù)史上最全面解析
04:IntentService深入了解经磅?
IntentService集成與Service,用來處理異步請求钮追≡ぱ幔客服端可以通過startService(Intent intent)方法傳遞請求給IntentService。IntentService在onCreate()函數(shù)中通過HandlerThread單獨開啟一個線程來依次處理所有Intent請求對象所對應的任務(wù)(這樣以免事務(wù)處理阻塞主線程元媚,出現(xiàn)ANR異常)執(zhí)行完一個Intent請求對象所對應的工作之后轧叽,如果沒有新的Intent請求達到,則自動停止Service刊棕,否則執(zhí)行下一個Intent請求所對應的任務(wù)炭晒。
IntentService在處理事務(wù)時,還是采用的Handler方式甥角,創(chuàng)建一個名叫ServiceHandler的內(nèi)部Handler网严,并把它直接綁定到HandlerThread所對應的子線程。ServiceHandler把處理一個intent所對應的事務(wù)都封裝到叫做onHandleIntent的虛函數(shù)中嗤无;因此我們直接實現(xiàn)虛函數(shù)onHandleIntent震束,再在里面根據(jù)intent的不同進行不同的事務(wù)處理就可以了。另外当犯,IntentService默認實現(xiàn)了onBind()方法垢村,返回值為null.
使用IntentService需要實現(xiàn)的兩個方法:
-
構(gòu)造函數(shù)
IntentService的構(gòu)造函數(shù)一定是參數(shù)為空的構(gòu)造函數(shù),然后再在其中調(diào)用super("name")這種形式的構(gòu)造函數(shù)嚎卫。因為Service的實例化是系統(tǒng)來完成的嘉栓,而且系統(tǒng)是參數(shù)為空的構(gòu)造函數(shù)來實例化Service的。 -
實現(xiàn)虛函數(shù)onHandleIntent
在里面根據(jù)intent的不同進行不同的事務(wù)處理。
好處:處理異步請求的時間可以減少些代碼的工作量侵佃,比較輕松的實現(xiàn)項目的需求麻昼。
IntentService實例介紹
首先是myIntentService.java
public class myIntentService extends IntentService {
//------------------必須實現(xiàn)-----------------------------
public myIntentService() {
super("myIntentService");
// 注意構(gòu)造函數(shù)參數(shù)為空,這個字符串就是worker thread的名字
}
@Override
protected void onHandleIntent(Intent intent) {
//根據(jù)Intent的不同進行不同的事務(wù)處理
String taskName = intent.getExtras().getString("taskName");
switch (taskName) {
case "task1":
Log.i("myIntentService", "do task1");
break;
case "task2":
Log.i("myIntentService", "do task2");
break;
default:
break;
}
}
//--------------------用于打印生命周期--------------------
@Override
public void onCreate() {
Log.i("myIntentService", "onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("myIntentService", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("myIntentService", "onDestroy");
super.onDestroy();
}
}
然后記得在Manifest.xml中注冊服務(wù)
<service android:name=".myIntentService">
<intent-filter >
<action android:name="cn.scu.finch"/>
</intent-filter>
</service>```
最后在Activity中開啟服務(wù)
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//同一服務(wù)只會開啟一個worker thread趣钱,
//在onHandleIntent函數(shù)里依次處理intent請求涌献。
Intent i = new Intent("cn.scu.finch");
Bundle bundle = new Bundle();
bundle.putString("taskName", "task1");
i.putExtras(bundle);
startService(i);
Intent i2 = new Intent("cn.scu.finch");
Bundle bundle2 = new Bundle();
bundle2.putString("taskName", "task2");
i2.putExtras(bundle2);
startService(i2);
startService(i); //多次啟動
}
}```
運行結(jié)果:
總結(jié):IntentService在onCreate()函數(shù)中通過HandlerThread單獨開啟一個線程來依次處理所有Intent請求對象所對應的任務(wù)。通過onStartCommand()傳遞給服務(wù)intent被依次插入到工作隊列中首有。工作隊列又把intent逐個發(fā)送給onHandleIntent()燕垃。
注意:它只有一個工作線程,名字就是構(gòu)造函數(shù)的那個字符串井联,也就是"myIntentService"卜壕,我們知道多次開啟service,只會調(diào)用一次onCreate()方法(創(chuàng)建一個工作線程)烙常,多次onStartCommand()方法(用于傳入intent通過工作隊列再發(fā)給onHandleIntent函數(shù)做處理)轴捎。
05:IntentService與Service的區(qū)別
Service不是獨立的進程,也不是獨立的線程蚕脏,它是依賴于應用程序的主線程的侦副,不建議在Service中編寫耗時的邏輯和操作,否則會引起ANR驼鞭。
IntentService它創(chuàng)建了一個獨立的工作線程來處理所有的通過onStartCommand()傳遞給服務(wù)的intents(把intent插入到工作隊列中)秦驯。通過工作隊列把intent逐個發(fā)送到onHandleIntent()。不需要主動調(diào)用stopSelft()來結(jié)束服務(wù)挣棕。因為译隘,所有的intent被處理完畢之后,系統(tǒng)會自動關(guān)閉服務(wù)洛心。
默認實現(xiàn)的onBind()固耘,返回null。
06:理解Activity词身,View,Window三者關(guān)系
首先用一個比喻來解釋三者之間的關(guān)系:Activity像一個工匠(控制單元)厅目,Windows像窗戶(承載模型),View像窗花(顯示視圖)法严,LayoutInflater像剪刀璧瞬,Xml配置像剪窗花的圖紙。下面介紹:
1.Activity構(gòu)造的時候會初始化一個Windows渐夸,準確的說是PhoneWindow
2.這個PhoneWindow有一個“ViewRoot”嗤锉,這個“ViewRoot”是一個View或者ViewGroup,是最具初始化的根視圖墓塌。
3.“ViewRoot”通過addView方法來一個個的添加View瘟忱。比如TextView奥额,Button等
4.這些View的事件監(jiān)聽,是由WindowManagerService來接受消息访诱,并且回調(diào)Activity函數(shù)垫挨。比如:onClickListener,onKeyDown等
07:Fragment能否不依賴于Activity存在触菜?簡析一下Fragment的棧管理九榔。
Fragment不能獨立存在的,它必須嵌入到activity中涡相,而且Fragment的生命周期直接受所在的activity的影響哲泊。
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();```
transaction只是記錄了從一個狀態(tài)到另一個狀態(tài)的變化過程,既比如從FragmentA替換到FragmentB的過程催蝗,當通過函數(shù)transaction.addToBackStack(null)將這個事務(wù)添加到回退棧切威,則會記錄這個事務(wù)的狀態(tài)變化過程,如從FragmentA——>FragmentB,當用戶點擊手機回退鍵時丙号,因為transaction的狀態(tài)變化過程被保存先朦,則可以將事務(wù)的變化過程還原,既將FragmentB——>FragmentA.
**添加到回退棧的函數(shù):transaction.addToBackStack(null);**
[參考文章: http://blog.csdn.net/u011026329/article/details/47903177](http://blog.csdn.net/u011026329/article/details/47903177)
**08:對于同一個Service犬缨,在被start啟動之后還能不能被bind喳魏?**
是可以的,Service服務(wù)基本上分為兩種形式:
**啟動**
當應用組件(如Activity)通過調(diào)用startService()啟動服務(wù)時怀薛,服務(wù)既處于“啟動”狀態(tài)刺彩。一旦啟動,服務(wù)既可在后臺無限期運行乾戏,即使啟動服務(wù)的組件已被銷毀也不會受到影響。已啟動的服務(wù)通常是執(zhí)行單一操作三热,而且不會將結(jié)果返回給調(diào)用方鼓择。例如,它可以通過網(wǎng)絡(luò)下載或上傳文件就漾。操作完成后呐能,服務(wù)會自行停止運行。
**綁定**
當應用組件通過bindService()方法綁定到服務(wù)時抑堡,服務(wù)既處于“綁定”狀態(tài)摆出。綁定服務(wù)提供了一個客戶端-服務(wù)器接口,允許組件與服務(wù)器進行交互首妖、發(fā)送請求偎漫、獲取結(jié)果,甚至是利用進程間通信(IPC) 跨進程執(zhí)行這些操作有缆。僅當與另一個應用組件綁定時象踊,綁定服務(wù)才會運行温亲。多個組件可以同時綁定到該服務(wù),但全部取消綁定后杯矩,該服務(wù)既會被銷毀栈虚。
**雖然本文檔是分開概括討論這兩種服務(wù)的,但是您的服務(wù)可以同時以這兩種方式運行史隆,也就是說魂务,它既可以是啟動服務(wù)(以無限期運行),也允許綁定泌射。問題只是在于您是否實現(xiàn)一組回調(diào)方法:onStartCommand()(允許組件啟動服務(wù))和onBind()(允許綁定服務(wù))粘姜。**
**09:Android中動畫**
Android中動畫分別有:**幀動畫、補間動畫魄幕、屬性動畫(Android3.0以后)**
**幀動畫**
幀動畫是最容易實現(xiàn)的一種動畫相艇,這種動畫更多的依賴于完善的UI資源,他的原理就是講一張張單獨的圖片連貫的進行播放(類似于與動畫片的制作過程)纯陨,從視覺上產(chǎn)生一種動畫的效果坛芽;有些類似于某些軟件制作gif動畫的方式。有些代碼中翼抠,我們還會看到```android:oneshot="false"```,這個oneshot的含義就是動畫執(zhí)行一次(true)還是循環(huán)執(zhí)行多次咙轩。
定義代碼如下:
<?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(旋轉(zhuǎn))钾菊。
補間動畫的實現(xiàn),一般采用xml文件的形式偎肃;代碼會更容易書寫和閱讀煞烫,同時也更容易復用。Interpolator主要作用是可以控制動畫的變化速率累颂,就是動畫進行的快慢節(jié)奏滞详。pivot決定了當前動畫執(zhí)行的參考位置。
代碼如下:
<?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>
屬性動畫
屬性動畫紊馏,顧名思義它是對于對象屬性的動畫料饥。因此,所有補間動畫的內(nèi)容朱监,都可以通過屬性動畫實現(xiàn)岸啡。屬性動畫的運行機制是不斷地進行操作來實現(xiàn)的,而初始值和結(jié)束值之間的動畫過度就是由ValueAnimator這個類負責計算的赫编。它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡凰狞,我們只需要將初始值和結(jié)束值提供ValueAnimator篇裁,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果赡若。除此之外达布,ValueAnimator還負責管理動畫的播放次數(shù)、播放模式以及對動畫設(shè)置監(jiān)聽器等逾冬。
10:消息推送的方式
- 方案1:使用極光黍聂、友盟、信鴿身腻、個推等第三方推送平臺(優(yōu)點:方便省事产还,有較為完善的功能解決方案)
-
方案2:使用XMPP協(xié)議(Openfire + Spark + Smack)
簡介:基于XML協(xié)議的通訊協(xié)議,前身是Jabber嘀趟,目前已由IETF國際標準化組織完成了標準化工作脐区。
優(yōu)點:協(xié)議成熟、強大她按、可擴展性強牛隅、目前主要應用到許多聊天系統(tǒng)中,且已有開源的Java版的開發(fā)實例androidpn酌泰。
缺點:協(xié)議比較復雜媒佣、冗余(基于XML)、費流量陵刹、費電默伍,部署硬件成本高。 -
方案3:使用MQTT協(xié)議(更多信息見:http://mqtt.org/)
簡介:輕量級衰琐、基于代理的“發(fā)布/訂閱”模式的消息傳輸協(xié)議也糊。
優(yōu)點:協(xié)議簡潔、小巧羡宙、可擴展性強狸剃、省流量、省電辛辨,目前已經(jīng)應用到企業(yè)領(lǐng)域(參考:http://mqtt.org/software),且已有C++版的服務(wù)端組件rsmb
缺點:夠成熟捕捂、實現(xiàn)較復雜瑟枫、服務(wù)端組件rsmb不開源斗搞,部署硬件成本較高。 -
方案4:使用HTTP輪循方式
簡介:定時向HTTP服務(wù)器接口(Web Service API)獲取最新的消息慷妙。
優(yōu)點:實現(xiàn)簡單僻焚、可控制強月趟,部署硬件成本低上荡。
缺點:實時性差样悟。
11:Android的數(shù)據(jù)存儲
- 使用SharedPreferences存儲數(shù)據(jù)饱溢;它是Android提供的用來存儲一些簡單配置信息的一種機制,采用了XML格式將數(shù)據(jù)存儲到設(shè)備中狞山。只能在同一個包內(nèi)使用全闷,不能再不同的包之間使用。
- 文件存儲數(shù)據(jù)萍启;文件存儲方式是一種比較常用的方法总珠,在Android中讀取和寫入文件的方法,與Java中實現(xiàn)的I/O的程序是完全一樣的勘纯,提供了openFileInput()和openFileOutput()方法來實讀取設(shè)備上的文件局服。
- SQLite數(shù)據(jù)庫存儲數(shù)據(jù);SQLite是Android所帶的一個標準的數(shù)據(jù)庫驳遵,它支持SQL語句淫奔,它是一個輕量級的嵌入式數(shù)據(jù)庫。
- 使用ContentProvider存儲數(shù)據(jù)堤结;主要用于應用程序之間進行數(shù)據(jù)交換唆迁,從而能夠讓其他的應用保存或讀取此ContentProvider的各種數(shù)據(jù)類型。
- 網(wǎng)絡(luò)存儲數(shù)據(jù)霍殴;通過網(wǎng)絡(luò)上提供給我們的存儲空間來上傳(存儲)和下載(獲让教琛)我們存儲在網(wǎng)絡(luò)空間中的數(shù)據(jù)信息。
12:Android ANR是什么来庭?如何避免它妒蔚?
在Android上,如果你的應用程序有一段時間響應不夠靈敏月弛,系統(tǒng)會向用戶顯示一個對話框肴盏,這個對話框就稱為:應用程序無響應(ANR:Application Not Responding)對話框。
用戶可以選擇讓程序繼續(xù)進行帽衙,但是菜皂,人們在使用應用程序時,并不希望每次都要處理這個對話框厉萝。因此恍飘,在程序里對響應性能的設(shè)計很重要。這樣谴垫,系統(tǒng)才不會顯示ANR給用戶章母。不同的組件發(fā)生ANR異常的時間,也是不一樣的翩剪,如:主線程(Activity乳怎,Service)需要5秒,BroadCastReceiver需要10秒前弯。
解決方案:將所有耗時操作蚪缀,比如:訪問網(wǎng)絡(luò)秫逝、Socket通信、查詢大量SQL語句询枚、復雜邏輯計算等都放在子線程中去完成违帆,然后通過handler.sendMessage()、runUIThread()金蜀、AsyncTask()等方式更新UI前方。無論如何都要確保用戶界面操作的流暢度。如果耗時操作需要讓用戶等待廉油,那么最好在UI界面上給用戶顯示進度條惠险。
13:Android 自定義View的繪制流程
1.自定義View的屬性
2.在View的構(gòu)造方法中獲取我們自定義的屬性
[3.重寫onMesure()方法]
4.重寫onDraw()方法
注意:3用[]標出來,所以說3抒线,不一定是必須的班巩,當然了大部分的情況下還是需要重寫的。
鴻洋大神--自定義View文章匯總
14:Android 自定義View的事件分發(fā)機制
Android事件分發(fā)機制完全解析嘶炭,帶你從源碼的角度徹底理解(上)
Android事件分發(fā)機制完全解析抱慌,帶你從源碼的角度徹底理解(下)