哎呀呀 ,馬上就要面臨找工作了,媛媛心里緊張呀.
? ? ? 作為一個即將畢業(yè)的Android程序媛,開始面臨找工作了,本媛媛還是有點小緊張,于是收集了一些Android面試的題目.希望能夠用上.如果大家有Android面試的經(jīng)驗,希望能給我一些建議呀.不多廢話,直接上題扬虚。
1. 什么是Activity?
四大組件之一,一般的,一個用戶交互界面對應(yīng)一個activity
setContentView() ,// 要顯示的布局
button.setOnclickLinstener{
}
, activity 是Context的子類,同時實現(xiàn)了window.callback和keyevent.callback, 可以處理與窗體用戶交互的事件.
我開發(fā)常用的的有FragmentActivitiy,ListActivity ?,PreferenceActivity ,
TabAcitivty等…
如果界面有共同的特點或者功能的時候,還會自己定義一個BaseActivity.
進度對話框的顯示與銷毀, 聯(lián)網(wǎng), 退出.
2. 請描述一下Activity 生命周期股毫。
生命周期描述的是一個類從創(chuàng)建(new出來)到死亡(垃圾回收)的過程中會執(zhí)行的方法..
在這個過程中會針對不同的生命階段會調(diào)用不同的方法
Activity從創(chuàng)建到銷毀有多種狀態(tài)援岩,從一種狀態(tài)到另一種狀態(tài)時會激發(fā)相應(yīng)的回調(diào)方法羊初,這些回調(diào)方法包括:oncreate ondestroy onstop onstart onresume onpause
其實這些方法都是兩兩對應(yīng)的,onCreate創(chuàng)建與onDestroy銷毀衡瓶;
onStart可見與onStop不可見优质;onResume可編輯(即焦點)與onPause舌劳;
這6個方法是相對應(yīng)的帚湘,那么就只剩下一個onRestart方法了,這個方法在什么時候調(diào)用呢甚淡?
答案就是:在Activity被onStop后大诸,但是沒有被onDestroy,在再次啟動此Activity時就調(diào)用onRestart(而不再調(diào)用onCreate)方法;
如果被onDestroy了资柔,則是調(diào)用onCreate方法焙贷。
最后講自己項目中的經(jīng)驗,比如說手機衛(wèi)士每次進入某個界面的時候都要看到最新的數(shù)據(jù),這個刷新列表的操作 就放在onStart()的方法里面.這樣保證每次用戶看到的數(shù)據(jù)都是最新的.
多媒體播放, 播放來電話. onStop() 視頻, 視頻聲音設(shè)置為0 , 記錄視頻播放的位置 mediaplayer.pause();
onStart() 根據(jù)保存的狀態(tài)恢復(fù)現(xiàn)場. mediaplayer.start();
在讀文檔的時候還發(fā)現(xiàn)activity還有兩個方法 onPostResume() 和 OnPostCreate()這兩個生命周期的方法,不過開發(fā)的時候沒有用到過.
3. 兩個Activity之間跳轉(zhuǎn)時必然會執(zhí)行的是哪幾個方法。
一般情況比如說有兩個activity,分別叫A,B ,當(dāng)在A里面激活B組件的時候, A 會調(diào)用 onPause()方法,然后B 調(diào)用onCreate() ,onStart(), OnResume() ,
這個時候B覆蓋了窗體, A會調(diào)用onStop()方法. ?如果B呢 是個透明的,或者是對話框的樣式, 就不會調(diào)用onStop()方法
4. 橫豎屏切換時候Activity的生命周期贿堰。
這個生命周期跟清單文件里的配置有關(guān)系
1辙芍、不設(shè)置Activity的android:configChanges時,切屏?xí)匦抡{(diào)用各個生命周期
默認(rèn)首先銷毀當(dāng)前activity,然后重新加載
2羹与、設(shè)置Activity的android:configChanges="orientation|keyboardHidden|screenSize"時故硅,切屏不會重新調(diào)用各個生命周期,只會執(zhí)行onConfigurationChanged方法
游戲開發(fā)中, 屏幕的朝向都是寫死的.
5. 如何將一個Activity設(shè)置成窗口的樣式纵搁。
可以自定義一個activity的樣式
android:theme="@android:style/Theme.Dialog"
6. 你后臺的Activity被系統(tǒng) 回收怎么辦吃衅?如果后臺的Activity由于某原因被系統(tǒng)回收可了,如何在被系統(tǒng)回收之前保存當(dāng)前狀態(tài)腾誉?
除了在棧頂?shù)腶ctivity,其他的activity都有可能在內(nèi)存不足的時候被系統(tǒng)回收,一個activity越處于棧底,被回收的可能性越大.
protectedvoidonSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
publicvoidonCreate(Bundle savedInstanceState) {
//判斷 savedInstanceState是不是空.
//如果不為空就取出來
super.onCreate(savedInstanceState);
}
也可以每隔一段時間保存一次, 保存到本地, 下次啟動時恢復(fù).
7. 如何退出Activity徘层?如何安全退出已調(diào)用多個Activity的Application?
退出activity 直接調(diào)用 finish () 方法 . //用戶點擊back鍵 就是退出一個activity
退出activity 會執(zhí)行 onDestroy()方法 .
1利职、拋異常強制退出:
該方法通過拋異常趣效,使程序Force Close。
驗證可以眼耀,但是,需要解決的問題是佩憾,如何使程序結(jié)束掉哮伟,而不彈出Force Close的窗口。
100/0
//安全結(jié)束進程android.os.Process.killProcess(android.os.Process.myPid());
2妄帘、記錄打開的Activity:
每打開一個Activity楞黄,就記錄下來。在需要退出時抡驼,關(guān)閉每一個Activity即可鬼廓。
List lists ;在application 全集的環(huán)境里面
lists = new ArrayList();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
ondestory
lists.remove(this);
3、發(fā)送特定廣播:
在需要結(jié)束應(yīng)用時致盟,發(fā)送一個特定的廣播碎税,每個Activity收到廣播后,關(guān)閉即可馏锡。
//給某個activity 注冊接受接受廣播的意圖
registerReceiver(receiver, filter)
//如果過接受到的是 關(guān)閉activity的廣播 ?就調(diào)用finish()方法 把當(dāng)前的activity finish()掉
4雷蹂、遞歸退出
在打開新的Activity時使用startActivityForResult,然后自己加標(biāo)志杯道,在onActivityResult中處理匪煌,遞歸關(guān)閉。
上面是網(wǎng)上的一些做法.
還可以通過intent的flag 來實現(xiàn).. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活一個新的activity,然后在新的activity的oncreate方法里面 finish掉, 但是一個應(yīng)用可以有多個任務(wù)棧, 這樣可能會有問題.
講一講你對activity的理解
把上面的幾點用自己的心得寫出來
8. service是否在main thread中執(zhí)行, service里面是否能執(zhí)行耗時的操作?
默認(rèn)情況,如果沒有顯示的指定service所運行的進程,Service和activity是運行在當(dāng)前app所在進程的main thread(UI主線程)里面
service里面不能執(zhí)行耗時的操作(網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫,大文件 )
在子線程中執(zhí)行new Thread(){}.start();
Thread.currentThread().getName();
特殊情況,可以在清單文件配置 service 執(zhí)行所在的進程 ,讓service在另外的進程中執(zhí)行
ActivityManagerService
9. 兩個Activity之間怎么傳遞數(shù)據(jù)?
基本數(shù)據(jù)類型可以通過.Intent 傳遞數(shù)據(jù)
extras.putDouble(key,value)
intent.putExtra(name, value)
//通過intent putExtra方法 基本數(shù)據(jù)類型 都傳遞
intent.getStringExtra("key","value");
intent.getBooleanExtra("key","value")
Bundlebundle= new ?Bundle();
bumdle.putShort(key, value);
intent.putExtras(bumdle);
intent.putExtras(bundle)
Application 全局里面存放 對象 ,自己去實現(xiàn)自己的application的這個類,基礎(chǔ)系統(tǒng)的application , 每個activity都可以取到
讓對象實現(xiàn)implementsSerializable接口把對象存放到文件上.
讓類實現(xiàn)Serializable接口,然后可以通過ObjectOutputStream//對象輸出流
File file = new File("c:\1.obj");
FileOutputStream fos ?= new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student stu = new Student();
oos.writeObject(stu);
//從文件中把對象讀出來
ObjectInputStream ois = new ObjectInputStream(arg0);
Student stu1 = (Student) ois.readObject();
Paceable:存入內(nèi)存
文件/網(wǎng)絡(luò)
intent.setData(Uri)
Uri.fromFile(); ?//大圖片的傳遞
10. 怎么讓在啟動一個Activity是就啟動一個service萎庭?
在activity的onCreate()方法里面 startService();
11.同一個程序霜医,但不同的Activity是否可以放在不同的Task任務(wù)棧中?
Singleinstance ?運行在另外的單獨的任務(wù)棧里面
比方說在激活一個新的activity時候, 給intent設(shè)置flag
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);
12. Activity怎么和service綁定驳规,怎么在activity中啟動自己對應(yīng)的service肴敛?*
startService() 一旦被創(chuàng)建 ?調(diào)用者無關(guān)沒法使用service里面的方法
bindService () 把service 與調(diào)用者綁定 ,如果調(diào)用者被銷毀, service會銷毀
bindService() 我們可以使用service 里面的方法
bindService(). ?讓activity能夠訪問到 service里面的方法
構(gòu)建一個intent對象,
Intent service = new Intent(this,MyService.class);
通過bindService的方法去啟動一個服務(wù),
bindService(intent, new MyConn(), BIND_AUTO_CREATE);
ServiceConnection對象(重寫onServiceConnected和OnServiceDisconnected方法) 和BIND_AUTO_CREATE.
private class myconn implements ServiceConnection
{
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//可以通過IBinder的對象 去使用service里面的方法
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
13 .什么是Service以及描述下它的生命周期。Service有哪些啟動方法,有什么區(qū)別婴梧,怎樣停用Service洛波?
在Service的生命周期中,被回調(diào)的方法比Activity少一些昨登,只有onCreate, onStart, onDestroy,onBind和onUnbind。
通常有兩種方式啟動一個Service,他們對Service生命周期的影響是不一樣的贯底。
1 通過startService
Service會經(jīng)歷 onCreate 到onStart丰辣,然后處于運行狀態(tài),stopService的時候調(diào)用onDestroy方法禽捆。
如果是調(diào)用者自己直接退出而沒有調(diào)用stopService的話笙什,Service會一直在后臺運行。
2 通過bindService
Service會運行onCreate胚想,然后是調(diào)用onBind琐凭, 這個時候調(diào)用者和Service綁定在一起。調(diào)用者退出了浊服,Srevice就會調(diào)用onUnbind->onDestroyed方法统屈。
所謂綁定在一起就共存亡了。調(diào)用者也可以通過調(diào)用unbindService方法來停止服務(wù)牙躺,這時候Srevice就會調(diào)用onUnbind->onDestroyed方法愁憔。
需要注意的是如果這幾個方法交織在一起的話,會出現(xiàn)什么情況呢孽拷?
一個原則是Service的onCreate的方法只會被調(diào)用一次吨掌,就是你無論多少次的startService又bindService,Service只被創(chuàng)建一次脓恕。
如果先是bind了膜宋,那么start的時候就直接運行Service的onStart方法,如果先是start炼幔,那么bind的時候就直接運行onBind方法激蹲。
如果service運行期間調(diào)用了bindService,這時候再調(diào)用stopService的話江掩,service是不會調(diào)用onDestroy方法的学辱,service就stop不掉了乘瓤,只能調(diào)用UnbindService, service就會被銷毀
如果一個service通過startService 被start之后,多次調(diào)用startService 的話策泣,service會多次調(diào)用onStart方法衙傀。多次調(diào)用stopService的話,service只會調(diào)用一次onDestroyed方法萨咕。
如果一個service通過bindService被start之后统抬,多次調(diào)用bindService的話,service只會調(diào)用一次onBind方法危队。
多次調(diào)用unbindService的話會拋出異常聪建。
14. 不用service,B頁面為音樂播放茫陆,從A跳轉(zhuǎn)到B金麸,再返回,如何使音樂繼續(xù)播放簿盅?
遇到問題, 可以隨機應(yīng)變,靈活發(fā)揮,多考慮些細(xì)節(jié),比如說這個題就可以這樣說,說說你對startActivityForResult的理解()
A開啟B的時候,用startActivityForResult()方法, B返回的時候把播放的狀態(tài)信息返回給A ,A繼續(xù)播放音樂.
15. 什么是IntentService挥下?有何優(yōu)點?
普通的service ,默認(rèn)運行在ui main 主線程
Sdk給我們提供的方便的,帶有異步處理的service類,
必須有無參構(gòu)造方法
OnHandleIntent() 處理耗時的操作
16.什么時候使用Service桨醋?
擁有service的進程具有較高的優(yōu)先級
官方文檔告訴我們棚瘟,Android系統(tǒng)會盡量保持擁有service的進程運行,只要在該service已經(jīng)被啟動(start)或者客戶端連接(bindService)到它喜最。當(dāng)內(nèi)存不足時偎蘸,需要保持,擁有service的進程具有較高的優(yōu)先級瞬内。
前臺, 可見, 服務(wù), 后臺, 空
1. 如果service正在調(diào)用onCreate, ?onStartCommand或者onDestory方法迷雪,那么用于當(dāng)前service的進程相當(dāng)于前臺進程以避免被killed。
2. 如果當(dāng)前service已經(jīng)被啟動(start)遂鹊,擁有它的進程則比那些用戶可見的進程優(yōu)先級低一些振乏,但是比那些不可見的進程更重要蔗包,這就意味著service一般不會被killed.
3. 如果客戶端已經(jīng)連接到service (bindService),那么擁有Service的進程則擁有最高的優(yōu)先級秉扑,可以認(rèn)為service是可見的。
4.Service長期在后臺運行, 時間長了可能被系統(tǒng)殺死,可以使用startForeground(int, Notification)方法來將service設(shè)置為前臺狀態(tài)调限,那么系統(tǒng)就認(rèn)為是對用戶可見的舟陆,并不會在內(nèi)存不足時killed。
如果有其他的應(yīng)用組件作為Service,Activity等運行在相同的進程中耻矮,那么將會增加該進程的重要性秦躯。
1.Service的特點可以讓他在后臺一直運行,可以在service里面創(chuàng)建線程去完成耗時的操作.
2.Broadcast receiver捕獲到一個事件之后,可以起一個service來完成一個耗時的操作.
3.遠(yuǎn)程的service如果被啟動起來,可以被多次bind, 但不會重新create. ?索愛手機X10i的人臉識別的service可以被圖庫使用,可以被攝像機,照相機等程序使用.
17. 請描述一下Intent 和 Intent Filter。
Android 中通過 Intent 對象來表示一條消息裆装,一個 Intent 對象不僅包含有這個消息的目的地踱承,還可以包含消息的內(nèi)容倡缠,這好比一封 Email,其中不僅應(yīng)該包含收件地址茎活,還可以包含具體的內(nèi)容昙沦。對于一個 Intent 對象,消息“目的地”是必須的载荔,而內(nèi)容則是可選項盾饮。
通過Intent 可以實現(xiàn)各種系統(tǒng)組件的調(diào)用與激活.
data/system/package.xml
Intent filter: 可以理解為郵局或者是一個信箋的分揀系統(tǒng)…
這個分揀系統(tǒng)通過3個參數(shù)來識別
Action: 動作 ? ?view
Data: 數(shù)據(jù)uri ? uri
Category : 而外的附加信息
Action 匹配
Action 是一個用戶定義的字符串,用于描述一個 Android 應(yīng)用程序組件懒熙,一個 Intent Filter 可以包含多個 Action丘损。在 AndroidManifest.xml 的 Activity 定義時可以在其 節(jié)點指定一個 Action 列表用于標(biāo)示 Activity 所能接受的“動作”,例如:
……
如果我們在啟動一個Activity時使用這樣的Intent對象:
Intent intent =new Intent();
intent.setAction("cn.itcast.action");
那么所有的Action列表中包含了“cn.itcast”的Activity都將會匹配成功工扎。
Android預(yù)定義了一系列的Action分別表示特定的系統(tǒng)動作徘钥。這些Action通過常量的方式定義在android.content. Intent中,以“ACTION_”開頭定庵。我們可以在Android 提供的文檔中找到它們的詳細(xì)說明吏饿。
URI 數(shù)據(jù)匹配
一個Intent 可以通過 URI 攜帶外部數(shù)據(jù)給目標(biāo)組件。在 節(jié)點中蔬浙,通過 節(jié)點匹配外部數(shù)據(jù)猪落。
mimeType 屬性指定攜帶外部數(shù)據(jù)的數(shù)據(jù)類型,scheme 指定協(xié)議畴博,host笨忌、port、path 指定數(shù)據(jù)的位置俱病、端口官疲、和路徑。如下:
android:host="host" android:port="port" android:path="path"/>
電話的uri ? tel: 12345
http://www.baidu.com
自己定義的uri ?itcast://cn.itcast/person/10
如果在Intent Filter 中指定了這些屬性亮隙,那么只有所有的屬性都匹配成功時 URI 數(shù)據(jù)匹配才會成功途凫。
Category 類別匹配
節(jié)點中可以為組件定義一個 Category 類別列表,當(dāng) Intent 中包含這個列表的所有項目時 Category 類別匹配才會成功溢吻。
默認(rèn)是DEFAULT
18. Intent傳遞數(shù)據(jù)時维费,可以傳遞哪些類型數(shù)據(jù)?
1.一般的基本數(shù)據(jù)類型 ?Intent .putextra() intent.getextra();
2.數(shù)據(jù)的uri, intent.setData() intent.getData();
19. 說說Activity促王,Intent犀盟,Service是什么關(guān)系 。
麥當(dāng)勞和麥當(dāng)娜的關(guān)系是什么關(guān)系?
這種問題,就講下activity,講一下service,說一下 通過intent去激活組件,傳遞數(shù)據(jù).
說自己項目中有這樣一個網(wǎng)絡(luò)更新的功能,顯示界面就用的activity, 后臺有個service每隔半小時都去訪問下服務(wù)器獲取更新的數(shù)據(jù)…
開啟服務(wù)用的是intent來開啟
20. 請描述一下Broadcast Receiver蝇狼。
有很多廣播接收者,系統(tǒng)已經(jīng)實現(xiàn)了.
廣播分兩種有序廣播
無序廣播
指定接收者的廣播. ?是不可以被攔截掉的
abortBroadcast();
用于接收系統(tǒng)的廣播通知, 系統(tǒng)會有很多sd卡掛載,手機重啟,廣播通知,低電量,來電,來短信等….有些應(yīng)用通過這些廣播啟動后臺服務(wù), 避免被殺死
電量改變廣播, 必須動態(tài)注冊
來獲取短信到來的廣播, 根據(jù)黑名單來判斷是否攔截該短信.
畫畫板生成圖片后,發(fā)送一個sd掛載的通知,通知系統(tǒng)的gallery去獲取到新的圖片.
Intent intent =newIntent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
可以作為組件間通信工具. EventBus
21. 在manifest和代碼中如何注冊和使 用 broadcast receiver 阅畴。
設(shè)置廣播接收者的優(yōu)先級,設(shè)置廣播接受者的action名字 等…
詳細(xì)見工程代碼.
22. 請介紹下Android的數(shù)據(jù)存儲方式。
文件訪問權(quán)限. ?sdcard /
數(shù)據(jù)庫sqlite
SharedPreference ?//shared_preps
網(wǎng)絡(luò)socket tcp udp , http httpurlconnection
23. 請介紹下ContentProvider是如何實現(xiàn)數(shù)據(jù)共享的迅耘。
把自己的數(shù)據(jù)通過uri的形式共享出去
android ?系統(tǒng)下 不同程序 數(shù)據(jù)默認(rèn)是不能共享訪問
需要去實現(xiàn)一個類去繼承ContentProvider
public class PersonContentProvider extends ContentProvider{
Static{ }
public boolean onCreate(){
//..SqliteOpenHelper
}
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])
}
24. 為什么要用ContentProvider贱枣?它和sql的實現(xiàn)上有什么差別监署?
屏蔽數(shù)據(jù)存儲的細(xì)節(jié),對用戶透明,用戶只需要關(guān)心操作數(shù)據(jù)的uri就可以了
不同app之間共享,操作數(shù)據(jù)
Sql也有增刪改查的方法.
但是contentprovider 還可以去增刪改查本地文件. xml文件的讀取,更改,
網(wǎng)絡(luò)數(shù)據(jù)讀取更改
25. 請介紹下Android中常用的五種布局。
FrameLayout(幀布局)纽哥,LinearLayout (線性布局)焦匈,AbsoluteLayout(絕對布局),RelativeLayout(相對布局)昵仅,TableLayout(表格布局)
FrameLayout
從屏幕的左上角開始布局,疊加顯示, 實際應(yīng)用 播放器的暫停按鈕.
LinearLayout
線性布局缓熟,這個東西,從外框上可以理解為一個div摔笤,他首先是一個一個從上往下羅列在屏幕上够滑。每一個LinearLayout里面又可分為垂直布局
(android:orientation="vertical")和水平布局(android:orientation="horizontal"
)。當(dāng)垂直布局時吕世,每一行就只有一個元素彰触,多個元素依次垂直往下;水平布局時命辖,只有一行况毅,每一個元素依次向右排列。
AbsoluteLayout
絕對布局猶如div指定了absolute屬性尔艇,用X,Y坐標(biāo)來指定元素的位置android:layout_x="20px"
android:layout_y="12px"
qq斗地主 qq游戲大廳 800*480 800*480.apk ?fwvga ?854*480
指定平板機型的游戲開發(fā)中經(jīng)常用到絕對布局widget 絕對布局
指定機型的平板游戲開發(fā)機頂盒開發(fā)尔许。. 2.3 3.0
1.界面布局任務(wù)管理器gridview
2.手機任務(wù)管理listview
RelativeLayout
相對布局可以理解為某一個元素為參照物,來定位的布局方式终娃。主要屬性有:
相對于某一個元素
android:layout_below="@id/aaa" 該元素在 id為aaa的下面
android:layout_toLeftOf="@id/bbb" 改元素的左邊是bbb
相對于父元素的地方
android:layout_alignParentLeft="true" ?在父元素左對齊
android:layout_alignParentRight="true" 在父元素右對齊
TableLayout
表格布局類似Html里面的Table味廊。每一個TableLayout里面有表格行TableRow,TableRow里面可以具體定義每一個元素棠耕,設(shè)定他的對齊方式 android:gravity="" 余佛。
每一個布局都有自己適合的方式,另外窍荧,這五個布局元素可以相互嵌套應(yīng)用辉巡,做出美觀的界面。
oa ?自動化 生成報表 ,圖標(biāo) 表示
可以說一下屏幕適配
PercentRelativeLayout蕊退、PercentFrameLayout
26. 談?wù)刄I中郊楣, Padding和Margin有什么區(qū)別?
Padding 文字對邊框, margin是控件對父窗體.android:layout_xxx, android:xxx
27. widget相對位置的完成在activity的哪個生命周期階段實現(xiàn)咕痛。
widget可以理解成桌面小控件,
也可以理解成某個button, imageview這樣的控件…
onCreate, onStart, onResume,都得不到
1.在onWindowFocusChanged 可以得到
2.
mTv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
System.out.println("onGlobalLayout: "+mTv.getHeight());
mTv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
3.
mTv.post(new Runnable() {
@Override
public void run() {
System.out.println("run: "+mTv.getHeight());
}
});
onmeasure() // 計算控件的寬高, 只要這個方法執(zhí)行完, 控件的寬高就有了
某個view 要顯示在界面 ?ondraw 被顯示到界面上的 .
onSizeChanged
28. 請解釋下在單線程模型中Message痢甘、Handler喇嘱、MessageQueue茉贡、Looper之間的關(guān)系。
29. AIDL的全稱是什么者铜?如何工作腔丧?
Android interface definition language (android接口定義語言) , 用來跨進程的訪問方法,
訪問遠(yuǎn)程的服務(wù)的方法. 如何工作 day7 queryStudent .
手機衛(wèi)士Itelephony 接口掛斷電話.
30. 請解釋下Android程序運行時權(quán)限與文件系統(tǒng)權(quán)限的區(qū)別放椰。
Android程序執(zhí)行需要讀取到安全敏感項必需在androidmanifest.xml中聲明相關(guān)權(quán)限請求, 打電話,訪問網(wǎng)絡(luò),獲取坐標(biāo),讀寫sd卡,讀寫聯(lián)系人等..安裝的時候會提示用戶…
drwx
文件系統(tǒng)的權(quán)限是linux權(quán)限. 比如說sharedpreference里面的Context.Mode.private ?Context.Mode.world_read_able ? Context.Mode_world_writeable
777自己 同組 其他rwxrwxrwx
31. 系統(tǒng)上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面愉粤?
找到對應(yīng)的瀏覽器的意圖(Action),傳遞數(shù)據(jù)URI , 激活這個意圖
Intent intent =newIntent();
intent.setClassName(packageName,className);
intent.seturi()
32. 對android主線程的運用和理解砾医。
主ui線程不能執(zhí)行耗時的操作,main方法, 死循環(huán)
33. 對android虛擬機的理解,包括內(nèi)存管理機制垃圾回收機制衣厘。
虛擬機很小,空間很小,談?wù)勔苿釉O(shè)備的虛擬機的大小限制 16M ,很多ROM都修改了, 小米3,128MB
談?wù)劶虞d圖片的時候怎么處理大圖片的,d
垃圾回收,沒有引用的對象,在某個時刻會被系統(tǒng)gc掉.
手動調(diào)用System.gc()有用嗎? 有用!但是會導(dǎo)致界面卡, 放在合適的位置.
34. Framework工作方式及原理如蚜,Activity是如何生成一個view的,機制是什么影暴。
反射, 配置文件
可以講下activity的源碼,比如說 每個activity里面都有window.callback和keyevent.callback,一些回調(diào)的接口或者函數(shù)吧. 框架把activity創(chuàng)建出來就會調(diào)用里面的這些回調(diào)方法,會調(diào)用activity生命周期相關(guān)的方法.
Activity創(chuàng)建一個view是通過 ondraw 畫出來的, 畫這個view之前呢,還會調(diào)用onmeasure方法來計算顯示的大小.
35. ?android本身的一些限制错邦,比如apk包大小限制,讀取大文件時的時間限型宙。
這個問題問的有問題, apk包大小限制不好說,
極品飛車有100M 還是能裝到手機上,
世面google market 上大程序 ?主程序 很小 5~10M ? ?下載sdcard
15分鐘之內(nèi) 申請退款
apk包,精簡包, 素材存放在服務(wù)器. 游戲程序.
讀大文件的時間限制應(yīng)該是main線程里面的時間限制吧.
Activity 不要超過5秒.
Service 不要超過20秒
36. 如何加載的音樂信息撬呢,如何改善其效率。
Android提供mediascanner,mediaStore等接口, 音樂文件的信息都會存放到系統(tǒng)的數(shù)據(jù)庫表中,可以通過content provider獲取,
顯示出來,改善效率,是個常見問題, 可以從以下幾個方面作答,
分批加載數(shù)據(jù), 延時加載數(shù)據(jù), 合理使用緩存等...
37. ListView如何提高其效率妆兑?
復(fù)用convertview , 歷史的view對象
減少子孩子查詢的次數(shù)viewholder
異步加載數(shù)據(jù), 分頁加載數(shù)據(jù),
使用靜態(tài)的view對象 避免創(chuàng)建過多的view.
setTag, 局部刷新.
38.啟動應(yīng)用后魂拦,改變系統(tǒng)語言,應(yīng)用的語言會改變么搁嗓?
2.3有bug, 不會, 后面版本可以.
39. 啟動一個程序芯勘,可以主界面點擊圖標(biāo)進入,也可以從一個程序中跳轉(zhuǎn)過去腺逛,二者有什么區(qū)別借尿?
區(qū)別是根據(jù)activity在manifest里面的配置,這個activity可能會放在不同的task棧里面.intent設(shè)置的flag ?flag_new_task
40. Android程序與Java程序的區(qū)別?
Android程序用android sdk開發(fā),java程序用javasdk開發(fā).
Android SDK引用了大部分的Java SDK屉来,少數(shù)部分被Android SDK拋棄路翻,比如說界面部分,java.awt ?swing ?package除了java.awt.font被引用外茄靠,其他都被拋棄茂契,在Android平臺開發(fā)中不能使用。 android sdk 添加工具jar httpclient , pull ?opengl
將Java 游戲或者j2me程序移植到Android平臺的過程中慨绳,
Android ?SDK 與Java SDK的區(qū)別是很需要注意的地方掉冶。
sampledataadpter()
41. Android中Task任務(wù)棧的分配。
首先我們來看下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是沒有任何聯(lián)系的璧亚,它只是針對Activity而言的。
Activity有不同的啟動模式, 可以影響到task的分配
Task脂信,簡單的說癣蟋,就是一組以棧的模式聚集在一起的Activity組件集合透硝。它們有潛在的前后驅(qū)關(guān)聯(lián),新加入的Activity組件疯搅,位于棧頂濒生,并僅有在棧頂?shù)腁ctivity,才會有機會與用戶進行交互幔欧。而當(dāng)棧頂?shù)腁ctivity完成使命退出的時候罪治,Task會將其退棧,并讓下一個將跑到棧頂?shù)腁ctivity來于用戶面對面礁蔗,直至棧中再無更多Activity规阀,Task結(jié)束。
如上表所示瘦麸,是一個實例谁撼。從用戶從進入郵箱開始,到回復(fù)完成滋饲,退出應(yīng)用整個過程的Task棧變化厉碟。這是一個標(biāo)準(zhǔn)的棧模式,對于大部分的狀況屠缭,這樣的Task模型箍鼓,足以應(yīng)付,但是呵曹,涉及到實際的性能款咖、開銷等問題,就會變得殘酷許多奄喂。
比如铐殃,啟動一個瀏覽器,在Android中是一個比較沉重的過程跨新,它需要做很多初始化的工作富腊,并且會有不小的內(nèi)存開銷。但與此同時域帐,用瀏覽器打開一些內(nèi)容赘被,又是一般應(yīng)用都會有的一個需求。設(shè)想一下肖揣,如果同時有十個運行著的應(yīng)用(就會對應(yīng)著是多個Task)民假,都需要啟動瀏覽器,這將是一個多么殘酷的場面龙优,十個Task棧都堆積著很雷同的瀏覽器Activity羊异,
是多么華麗的一種浪費啊。
于是你會有這樣一種設(shè)想,瀏覽器Activity球化,可不可以作為一個單獨的Task而存在,不管是來自那個Task的請求瓦糟,瀏覽器的Task筒愚,都不會歸并過去。這樣菩浙,雖然瀏覽器Activity本身需要維系的狀態(tài)更多了巢掺,但整體的開銷將大大的減少,這種舍小家為大家的行為劲蜻,還是很值得歌頌的
standard", "singleTop", "singleTask", "singleInstance"陆淀。
standard模式, 是默認(rèn)的也是標(biāo)準(zhǔn)的Task模式先嬉,在沒有其他因素的影響下轧苫,使用此模式的Activity,會構(gòu)造一個Activity的實例疫蔓,加入到調(diào)用者的Task棧中去含懊,對于使用頻度一般開銷一般什么都一般的Activity而言,standard模式無疑是最合適的衅胀,因為它邏輯簡單條理清晰岔乔,所以是默認(rèn)的選擇。
而singleTop模式滚躯,基本上于standard一致雏门,僅在請求的Activity正好位于棧頂時,有所區(qū)別掸掏。此時茁影,配置成singleTop的Activity,不再會構(gòu)造新的實例加入到Task棧中丧凤,而是將新來的Intent發(fā)送到棧頂Activity中呼胚,棧頂?shù)腁ctivity可以通過重載onNewIntent來處理新的Intent(當(dāng)然,也可以無視...)息裸。這個模式蝇更,降低了位于棧頂時的一些重復(fù)開銷,更避免了一些奇異的行為(想象一下呼盆,如果在棧頂連續(xù)幾個都是同樣的Activity年扩,再一級級退出的時候,這是怎么樣的用戶體驗...)访圃,很適合一些會有更新的列表Activity展示厨幻。一個活生生的實例是,在Android默認(rèn)提供的應(yīng)用中,瀏覽器(Browser)的書簽Activity(BrowserBookmarkPage)况脆,就用的是singleTop饭宾。
singleTask,和singleInstance格了,則都采取的另辟Task的蹊徑看铆。
標(biāo)志為singleTask的Activity,最多僅有一個實例存在盛末,并且弹惦,位于以它為根的Task中。所有對該Activity的請求悄但,都會跳到該Activity的Task中展開進行棠隐。singleTask,很象概念中的單件模式檐嚣,所有的修改都是基于一個實例助泽,這通常用在構(gòu)造成本很大,但切換成本較小的Activity中嚎京。最典型的例子报咳,還是瀏覽器應(yīng)用的主Activity(名為Browser...),它是展示當(dāng)前tab挖藏,當(dāng)前頁面內(nèi)容的窗口暑刃。它的構(gòu)造成本大,但頁面的切換還是較快的膜眠,于singleTask相配岩臣,還是挺天作之合的。
singleInstance顯得更為極端一些宵膨。在大部分時候singleInstance與singleTask完全一致架谎,唯一的不同在于,singleInstance的Activity辟躏,是它所在棧中僅有的一個Activity谷扣,如果涉及到的其他Activity,都移交到其他Task中進行捎琐。這使得singleInstance的Activity会涎,像一座孤島,徹底的黑盒瑞凑,它不關(guān)注請求來自何方末秃,也不計較后續(xù)由誰執(zhí)行。在Android默認(rèn)的各個應(yīng)用中籽御,很少有這樣的Activity练慕,在我個人的工程實踐中惰匙,曾嘗試在有道詞典的快速取詞Activity中采用過,
是因為我覺得快速取詞入口足夠方便(從notification中點選進入)铃将,并且會在各個場合使用项鬼,應(yīng)該做得完全獨立。
默認(rèn)任務(wù)棧名字為包名, 可以自己配置
Activity的android:affinity屬性
1.配置后當(dāng)啟動這個activity時就先去找有沒有activity的親和力屬性相同有就加入這個activity所在的任務(wù)中沒有就新開任務(wù)棧
2.affinity起作用需要的條件二者具備一個:
1.intent包含F(xiàn)LAG_ACTIVITY_NEW_TASK標(biāo)記
2.activity元素啟用了allowTaskReparenting屬性.
42. 在Android中劲阎,怎么節(jié)省內(nèi)存的使用绘盟,怎么主動回收內(nèi)存?
回收已經(jīng)使用的資源,
合理的使用緩存
合理設(shè)置變量的作用范圍…application 對象
//未來的某一段時間執(zhí)行
System.gc();
43. 不同工程中的方法是否可以相互調(diào)用哪工?
可以,列舉aidl訪問遠(yuǎn)程服務(wù)的例子.
44.在Android中是如何實現(xiàn)判斷區(qū)分電話的狀態(tài)奥此,去電弧哎,來電雁比、未接來電?
去電有廣播, 來電沒有, TelephonyManager, PhoneStateListener
45. dvm的進程和Linux的進程, 應(yīng)用程序的進程是否為同一個概念
Dvm的進程是dalivk虛擬機進程,每個android程序都運行在自己的進程里面,
每個android程序系統(tǒng)都會給他分配一個單獨的liunx ?uid(user id),
每個dvm都是linux里面的一個進程.所以說這兩個進程是一個進程.
46. 如何判斷是否有SD卡撤嫩?
配置文件中有sd卡的權(quán)限, 通過environment的靜態(tài)方法,
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
47. 一條最長的短信息約占多少byte?
中文70(包括標(biāo)點)偎捎,英文160,160個字節(jié) 這個說法不準(zhǔn)確,
要跟手機制式運營商等信息有關(guān).
做實驗,看源碼
ArrayList msgs = sms.divideMessage(message);
for (String msg : msgs) {
sms.sendTextMessage(phoneNumber, null, msg, pi, null);
}
48. 談?wù)剬ndroid NDK的理解序攘。
native develop kit ? 只是一個交叉編譯的工具 ?.so
1.什么時候用ndk, ?實時性要求高,游戲,圖形渲染, ?opencv (人臉識別) , ffmpeg , rmvb ?mp5 avi 高清解碼. ffmpeg, opencore.
2.為什么用ndk,ndk的優(yōu)點 ,缺點 ,
我們項目中那些地方用到了ndk,秘鑰
49. 談?wù)凙ndroid的優(yōu)點和不足之處茴她。
1、開放性,開源 ophone ?阿里云( 完全兼容android)
2程奠、掙脫運營商束縛
3丈牢、豐富的硬件選擇 mtk android
4、不受任何限制的開發(fā)商
5雹锣、無縫結(jié)合的Google應(yīng)用
缺點:
1威恼、安全問題传蹈、隱私問題
2、碎片化
3申尼、過分依賴開發(fā)商,缺乏標(biāo)準(zhǔn)配置
50. Android系統(tǒng)中GC什么情況下會出現(xiàn)內(nèi)存泄露呢垫桂? ?視頻編解碼/內(nèi)存泄露
檢測內(nèi)存泄露工具
mat
C:\Users\lenovo\Desktop\prof>hprof-conv com.example.testmat.hprof convert-com.ex
ample.testmat.hprof
導(dǎo)致內(nèi)存泄漏主要的原因是师幕,先前申請了內(nèi)存空間而忘記了釋放。如果程序中存在對無用對象的引用诬滩,那么這些對象就會駐留內(nèi)存霹粥,消耗內(nèi)存,因為無法讓垃圾回收器GC驗證這些對象是否不再需要疼鸟。如果存在對象的引用蒙挑,這個對象就被定義為"有效的活動",同時不會被釋放愚臀。要確定對象所占內(nèi)存將被回收忆蚀,我們就要務(wù)必確認(rèn)該對象不再會被使用矾利。典型的做法就是把對象數(shù)據(jù)成員設(shè)為null或者從集合中移除該對象。但當(dāng)局部變量不需要時馋袜,不需明顯的設(shè)為null男旗,因為一個方法執(zhí)行完畢時,這些引用會自動被清理欣鳖。
Java帶垃圾回收的機制,為什么還會內(nèi)存泄露呢?
Vector v = new Vector(10);
for (int i = 1; i < 100; i++) ? ? ?{
Object o = new Object();
v.add(o);
o = null;
}//此時察皇,所有的Object對象都沒有被釋放,因為變量v引用這些對象泽台。
觀察者模式解除注冊
Java 內(nèi)存泄露的根本原因就是保存了不可能再被訪問的變量類型的引用
51. Android UI中的View如何刷新什荣。
在主線程中拿到view調(diào)用invalide()方法
在子線程里面可以通過postInvalide()方法;
requestLayout
52. 簡單描述下Android 數(shù)字簽名。
Android 數(shù)字簽名
在Android系統(tǒng)中怀酷,所有安裝到系統(tǒng)的應(yīng)用程序都必有一個數(shù)字證書稻爬,此數(shù)字證書用于標(biāo)識應(yīng)用程序的作者和在應(yīng)用程序之間建立信任關(guān)系
Android系統(tǒng)要求每一個安裝進系統(tǒng)的應(yīng)用程序都是經(jīng)過數(shù)字證書簽名的,數(shù)字證書的私鑰則保存在程序開發(fā)者的手中蜕依。Android將數(shù)字證書用來標(biāo)識應(yīng)用程序的作者和在應(yīng)用程序之間建立信任關(guān)系桅锄,不是用來決定最終用戶可以安裝哪些應(yīng)用程序。
這個數(shù)字證書并不需要權(quán)威的數(shù)字證書簽名機構(gòu)認(rèn)證(CA)样眠,它只是用來讓應(yīng)用程序包自我認(rèn)證的友瘤。
同一個開發(fā)者的多個程序盡可能使用同一個數(shù)字證書,這可以帶來以下好處檐束。
(1)有利于程序升級辫秧,當(dāng)新版程序和舊版程序的數(shù)字證書相同時,Android系統(tǒng)才會認(rèn)為這兩個程序是同一個程序的不同版本被丧。如果新版程序和舊版程序的數(shù)字證書不相同盟戏,則Android系統(tǒng)認(rèn)為他們是不同的程序,并產(chǎn)生沖突晚碾,會要求新程序更改包名抓半。
(2)有利于程序的模塊化設(shè)計和開發(fā)。Android系統(tǒng)允許擁有同一個數(shù)字簽名的程序運行在一個進程中格嘁,Android程序會將他們視為同一個程序笛求。所以開發(fā)者可以將自己的程序分模塊開發(fā),而用戶只需要在需要的時候下載適當(dāng)?shù)哪K糕簿。
在簽名時探入,需要考慮數(shù)字證書的有效期:
(1)數(shù)字證書的有效期要包含程序的預(yù)計生命周期,一旦數(shù)字證書失效懂诗,持有改數(shù)字證書的程序?qū)⒉荒苷I墶?/p>
(2)如果多個程序使用同一個數(shù)字證書蜂嗽,則該數(shù)字證書的有效期要包含所有程序的預(yù)計生命周期。
(3)Android Market強制要求所有應(yīng)用程序數(shù)字證書的有效期要持續(xù)到2033年10月22日以后殃恒。
Android數(shù)字證書包含以下幾個要點:
(1)所有的應(yīng)用程序都必須有數(shù)字證書植旧,Android系統(tǒng)不會安裝一個沒有數(shù)字證書的應(yīng)用程序
(2)Android程序包使用的數(shù)字證書可以是自簽名的辱揭,不需要一個權(quán)威的數(shù)字證書機構(gòu)簽名認(rèn)證
(3)如果要正式發(fā)布一個Android ,必須使用一個合適的私鑰生成的數(shù)字證書來給程序簽名病附,而不能使用adt插件或者ant工具生成的調(diào)試證書來發(fā)布问窃。
(4)數(shù)字證書都是有有效期的,Android只是在應(yīng)用程序安裝的時候才會檢查證書的有效期完沪。如果程序已經(jīng)安裝在系統(tǒng)中域庇,即使證書過期也不會影響程序的正常功能。
53. 什么是ANR 如何避免它覆积?
在Android上听皿,如果你的應(yīng)用程序有一段時間響應(yīng)不夠靈敏,系統(tǒng)會向用戶顯示一個對話框宽档,這個對話框稱作應(yīng)用程序無響應(yīng)(ANR:Application Not Responding)對話框尉姨。用戶可以選擇讓程序繼續(xù)運行,但是雌贱,他們在使用你的應(yīng)用程序時啊送,并不希望每次都要處理這個對話框偿短。因此欣孤,在程序里對響應(yīng)性能的設(shè)計很重要,這樣昔逗,系統(tǒng)不會顯示ANR給用戶降传。
Activity 5秒 ?broadcast10秒, service20秒
耗時的操作worker thread里面完成, handler message…AsynTask , intentservice.等…
Data/anr/traces.txt
54. android中的動畫有哪幾類,它們的特點和區(qū)別是什么勾怒?
兩種婆排,一種是Tween動畫、還有一種是Frame動畫笔链。
Tween動畫段只,這種實現(xiàn)方式可以使視圖組件移動、放大鉴扫、縮小以及產(chǎn)生透明度的變化赞枕;
可以通過布局文件,可以通過代碼
1、控制View的動畫
a)alpha(AlphaAnimation)
漸變透明
b)scale(ScaleAnimation)
漸變尺寸伸縮
c)translate(TranslateAnimation)
畫面轉(zhuǎn)換坪创、位置移動
d)rotate(RotateAnimation)
畫面轉(zhuǎn)移炕婶,旋轉(zhuǎn)動畫
2、控制一個Layout里面子View的動畫效果
a)layoutAnimation(LayoutAnimationController)
b)gridAnimation(GridLayoutAnimationController)
另一種Frame動畫莱预,傳統(tǒng)的動畫方法柠掂,通過順序的播放排列好的圖片來實現(xiàn),類似電影依沮。
屬性動畫ObjectAnimator, ValueAnimator, TypeEvaluator
Nineoldandroids.jar, 和真正的屬性動畫還是不一樣.
scrollTo/scrollBy
55. 說說mvc模式的原理涯贞,它在android中的運用枪狂。
MVC英文即Model-View-Controller,即把一個應(yīng)用的輸入宋渔、處理摘完、輸出流程按照Model、View傻谁、Controller的方式進行分離孝治,這樣一個應(yīng)用被分成三個層——模型層、視圖層审磁、控制層谈飒。
Android中界面部分也采用了當(dāng)前比較流行的MVC框架,在Android中M就是應(yīng)用程序中二進制的數(shù)據(jù)态蒂,V就是用戶的界面杭措。Android的界面直接采用XML文件保存的,界面開發(fā)變的很方便钾恢。在Android中C也是很簡單的手素,一個Activity可以有多個界面,只需要將視圖的ID傳遞到setContentView()瘩蚪,就指定了以哪個視圖模型顯示數(shù)據(jù)泉懦。
在Android SDK中的數(shù)據(jù)綁定,也都是采用了與MVC框架類似的方法來顯示數(shù)據(jù)疹瘦。在控制層上將數(shù)據(jù)按照視圖模型的要求(也就是Android SDK中的Adapter)封裝就可以直接在視圖模型上顯示了崩哩,從而實現(xiàn)了數(shù)據(jù)綁定。比如顯示Cursor中所有數(shù)據(jù)的ListActivity言沐,其視圖層就是一個ListView邓嘹,將數(shù)據(jù)封裝為ListAdapter,并傳遞給ListView险胰,數(shù)據(jù)就在ListView中顯示汹押。
MVP
MVVM
56. 通過點擊一個網(wǎng)頁上的url 就可以完成程序的自動安裝,描述下原理
Day11 AddJavascriptInterface, Java/JS互相調(diào)用
new Object{
callphone();
installapk();
}
http://1.vduntest.sinaapp.com/webview/WebView%E8%AF%A6%E8%A7%A3.html
57,Service和Activity在同一個線程嗎
默認(rèn)情況同一線程main主線程 ui線程
58,java中的soft reference是個什么東西
StrongReference 是 Java 的默認(rèn)引用實現(xiàn), 它會盡可能長時間的存活于 JVM 內(nèi), 當(dāng)沒有任何對象指向它時 GC 執(zhí)行后將會被回收
SoftReference 會盡可能長的保留引用直到 JVM 內(nèi)存不足時才會被回收(虛擬機保證), 這一特性使得 SoftReference 非常適合緩存
應(yīng)用詳細(xì)見客戶端圖片的緩存
LruCache
59,udp連接和TCP的不同之處
Tcp三次握手. ? 面向連接 流
udp 不關(guān)心數(shù)據(jù)是否達到,是否阻塞 ? 面向無連接
畫面優(yōu)先. tcp
流暢優(yōu)先udp
http基于tcp
60, android開發(fā)中怎么去調(diào)試bug
邏輯錯誤
1.斷點 debug
2. logcat
界面布局,ActivityManager,hierarchyview
61.service里面可以彈土司么
可以, 對于對話框, 需要加權(quán)限
AlertDialog dialog = new AlertDialog.Builder(this).setTitle("標(biāo)題").setMessage("內(nèi)容").setPositiveButton("確定", null).create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
Stk
顯示懸浮窗
62.寫10個簡單的linux命令
cat ls ps psw wc mv rm cd ping tracert find grep tail vi gcc make ifconfig
startup dhcp
63,JNI調(diào)用常用的兩個參數(shù)
JNIEnv *env, jobject javaThis
64. 書寫出android工程的目錄結(jié)構(gòu)
src
android. jar
asset
res
gen
manifest
65. ddms 和traceview的區(qū)別.
daivilk debug manager system
1.在應(yīng)用的主activity的onCreate方法中加入Debug.startMethodTracing("要生成的traceview文件的名字");
2.同樣在主activity的onStop方法中加入Debug.stopMethodTracing();
3.同時要在AndroidManifest.xml文件中配置權(quán)限
3.重新編譯起便,安裝棚贾,啟動服務(wù),測試完成取對應(yīng)的traceview文件(adb pull /sdcard/xxxx.trace)缨睡。
4.直接在命令行輸入traceview xxxxtrace鸟悴,彈出traceview窗口,分析對應(yīng)的應(yīng)用即可奖年。
traceview 分析程序執(zhí)行時間和效率
KPI : key performance information : 關(guān)鍵性能指標(biāo):
splash界面不能超過5秒
從splash 界面加載mainactivity 不能超過0.7秒
66. 利用mvc的模式重構(gòu)代碼
1)重構(gòu)前的代碼Bmi.java:
packagecom.demo.android.bmi;
importjava.text.DecimalFormat;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.EditText;
importandroid.widget.TextView;
publicclassBmiextendsActivity {
/** Called when the activity is first created. */
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Listen for button clicks
Button button = (Button) findViewById(R.id.submit);
button.setOnClickListener(calcBMI);
}
privateOnClickListenercalcBMI=newOnClickListener() {
@Override
publicvoidonClick(View v) {
DecimalFormat nf =newDecimalFormat("0.00");
EditText fieldheight = (EditText) findViewById(R.id.height);
EditText fieldweight = (EditText) findViewById(R.id.weight);
doubleheight = Double.parseDouble(fieldheight.getText().toString()) / 100;
doubleweight = Double.parseDouble(fieldweight.getText().toString());
doubleBMI = weight / (height * height);
TextView result = (TextView) findViewById(R.id.result);
result.setText("Your BMI is "+ nf.format(BMI));
// Give health advice
TextView fieldsuggest = (TextView) findViewById(R.id.suggest);
if(BMI > 25) {
fieldsuggest.setText(R.string.advice_heavy);
}elseif(BMI < 20) {
fieldsuggest.setText(R.string.advice_light);
}else{
fieldsuggest.setText(R.string.advice_average);
}
}
};
}
Step1:抽取所有界面元件的聲明和定義细诸,整合到單獨一個函數(shù)findViews()中;
//聲明view
privateButtonbutton_calc;
privateEditTextfield_height;
privateEditTextfield_weight;
privateTextViewview_result;
privateTextViewview_suggest;
//定義
privatevoidfindViews() {
button_calc= (Button) findViewById(R.id.submit);
field_height= (EditText) findViewById(R.id.height);
field_weight= (EditText) findViewById(R.id.weight);
view_result= (TextView) findViewById(R.id.result);
view_suggest= (TextView) findViewById(R.id.suggest);
}
此部分即是MVC中的V:View視圖陋守。
Step2:抽取程序的邏輯(即界面元件的處理邏輯)震贵,整合到函數(shù)setListensers()中利赋;
//Listen for button clicks
privatevoidsetListensers() {
button_calc.setOnClickListener(calcBMI);
}
此部分即是MVC中的C:Controller控制器。
接著猩系,onCreate()就顯得非常簡潔媚送、明了了:
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
setListensers();
}
Step3:修改按鈕監(jiān)聽器calcBMI中相應(yīng)的部分(主要是變量已經(jīng)在視圖部分定義了);
privateOnClickListenercalcBMI=newOnClickListener() {
@Override
publicvoidonClick(View v) {
DecimalFormat nf =newDecimalFormat("0.00");
doubleheight = Double.parseDouble(field_height.getText().toString()) / 100;
doubleweight = Double.parseDouble(field_weight.getText().toString());
doubleBMI = weight / (height * height);
// Present result
view_result.setText("Your BMI is "+ nf.format(BMI));
// Give health advice
if(BMI > 25) {
view_suggest.setText(R.string.advice_heavy);
}elseif(BMI < 20) {
view_suggest.setText(R.string.advice_light);
}else{
view_suggest.setText(R.string.advice_average);
}
}
};
總之寇甸,此重構(gòu)的目的無非是使程序的脈絡(luò)更加清晰塘偎,即讓人一眼望去,就能很容易地分辨出界面(View)應(yīng)該寫在哪里拿霉,程序邏輯(Controller)應(yīng)該寫在哪里吟秩,最終使維護和擴展代碼變得更加容易!
其實绽淘,重構(gòu)很簡單涵防,通讀代碼,感覺哪邊不太爽沪铭,就改那邊吧W吵亍(我目前的感受)
一個良好的代碼應(yīng)該是能讓人感到舒服的!
2)重構(gòu)后的代碼Bmi.java:
packagecom.demo.android.bmi;
importjava.text.DecimalFormat;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.EditText;
importandroid.widget.TextView;
publicclassBmiextendsActivity {
privateButtonbutton_calc;
privateEditTextfield_height;
privateEditTextfield_weight;
privateTextViewview_result;
privateTextViewview_suggest;
/** Called when the activity is first created. */
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
setListensers();
}
//定義
privatevoidfindViews() {
button_calc= (Button) findViewById(R.id.submit);
field_height= (EditText) findViewById(R.id.height);
field_weight= (EditText) findViewById(R.id.weight);
view_result= (TextView) findViewById(R.id.result);
view_suggest= (TextView) findViewById(R.id.suggest);
}
// Listen for button clicks
privatevoidsetListeners() {
calcbutton.setOnClickListener(calcBMI);
}
privateButton.OnClickListenercalcBMI=newButton.OnClickListener() {
publicvoidonClick(View v) {
DecimalFormat nf =newDecimalFormat("0.0");
doubleheight = Double.parseDouble(field_height.getText().toString()) / 100;
doubleweight = Double.parseDouble(field_weight.getText().toString());
doubleBMI = weight / (height * height);
// Present result
view_result.setText(getText(R.string.bmi_result) + nf.format(BMI));
// Give health advice
if(BMI > 25) {
view_suggest.setText(R.string.advice_heavy);
}elseif(BMI < 20) {
view_suggest.setText(R.string.advice_light);
}else{
view_suggest.setText(R.string.advice_average);
}
}
};
}
總結(jié):
關(guān)于項目
在就是你項目經(jīng)驗杀怠,一定要突出你遇到什么難點椰憋,然后是怎么解決的!把問題引導(dǎo)到你熟悉的領(lǐng)域,或者知識點上,盡量將每個技術(shù)點細(xì)節(jié)凸顯出來驮肉,