哎呀呀 ,馬上就要面臨找工作了,媛媛心裡緊張呀.
作為一個即將畢業的Android程式媛,開始面臨找工作了,本媛媛還是有點小緊張,於是收集了一些Android面試的題目.希望能夠用上.如果大家有Android面試的經驗,希望能給我一些建議呀.不多廢話,直接上題。
複製程式碼
- 什麼是Activity?
四大元件之一,一般的,一個使用者互動介面對應一個activity
setContentView() ,// 要顯示的佈局
button.setOnclickLinstener{
}
, activity 是Context的子類,同時實現了window.callback和keyevent.callback, 可以處理與窗體使用者互動的事件.
我開發常用的的有FragmentActivitiy,ListActivity ,PreferenceActivity ,
TabAcitivty等…
如果介面有共同的特點或者功能的時候,還會自己定義一個BaseActivity.
進度對話方塊的顯示與銷燬, 聯網, 退出.
- 請描述一下Activity 生命週期。
生命週期描述的是一個類從建立(new出來)到死亡(垃圾回收)的過程中會執行的方法..
在這個過程中會針對不同的生命階段會呼叫不同的方法
Activity從建立到銷燬有多種狀態,從一種狀態到另一種狀態時會激發相應的回撥方法,這些回撥方法包括:oncreate ondestroy onstop onstart onresume onpause
其實這些方法都是兩兩對應的,onCreate建立與onDestroy銷燬;
onStart可見與onStop不可見;onResume可編輯(即焦點)與onPause;
這6個方法是相對應的,那麼就只剩下一個onRestart方法了,這個方法在什麼時候呼叫呢?
答案就是:在Activity被onStop後,但是沒有被onDestroy,在再次啟動此Activity時就呼叫onRestart(而不再呼叫onCreate)方法;
如果被onDestroy了,則是呼叫onCreate方法。
最後講自己專案中的經驗,比如說手機衛士每次進入某個介面的時候都要看到最新的資料,這個重新整理列表的操作 就放在onStart()的方法裡面.這樣保證每次使用者看到的資料都是最新的.
多媒體播放, 播放來電話. onStop() 視訊, 視訊聲音設定為0 , 記錄視訊播放的位置 mediaplayer.pause();
onStart() 根據儲存的狀態恢復現場. mediaplayer.start();
在讀文件的時候還發現activity還有兩個方法 onPostResume() 和 OnPostCreate()這兩個生命週期的方法,不過開發的時候沒有用到過.
- 兩個Activity之間跳轉時必然會執行的是哪幾個方法。
一般情況比如說有兩個activity,分別叫A,B ,當在A裡面啟用B元件的時候, A 會呼叫 onPause()方法,然後B 呼叫onCreate() ,onStart(), OnResume() ,
這個時候B覆蓋了窗體, A會呼叫onStop()方法. 如果B呢 是個透明的,或者是對話方塊的樣式, 就不會呼叫onStop()方法
- 橫豎屏切換時候Activity的生命週期。
這個生命週期跟清單檔案裡的配置有關係
1、不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期
預設首先銷燬當前activity,然後重新載入
2、設定Activity的android:configChanges="orientation|keyboardHidden|screenSize"時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法
遊戲開發中, 螢幕的朝向都是寫死的.
- 如何將一個Activity設定成視窗的樣式。
可以自定義一個activity的樣式
android:theme="@android:style/Theme.Dialog"
- 你後臺的Activity被系統 回收怎麼辦?如果後臺的Activity由於某原因被系統回收可了,如何在被系統回收之前儲存當前狀態?
除了在棧頂的activity,其他的activity都有可能在記憶體不足的時候被系統回收,一個activity越處於棧底,被回收的可能性越大.
protectedvoidonSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
publicvoidonCreate(Bundle savedInstanceState) {
//判斷 savedInstanceState是不是空.
//如果不為空就取出來
super.onCreate(savedInstanceState);
}
也可以每隔一段時間儲存一次, 儲存到本地, 下次啟動時恢復.
- 如何退出Activity?如何安全退出已呼叫多個Activity的Application?
退出activity 直接呼叫 finish () 方法 . //使用者點選back鍵 就是退出一個activity
退出activity 會執行 onDestroy()方法 .
1、拋異常強制退出:
該方法通過拋異常,使程式Force Close。
驗證可以,但是,需要解決的問題是,如何使程式結束掉,而不彈出Force Close的視窗。
100/0
//安全結束程式android.os.Process.killProcess(android.os.Process.myPid());
2、記錄開啟的Activity:
每開啟一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
List lists ;在application 全集的環境裡面
lists = new ArrayList();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
ondestory
lists.remove(this);
3、傳送特定廣播:
在需要結束應用時,傳送一個特定的廣播,每個Activity收到廣播後,關閉即可。
//給某個activity 註冊接受接受廣播的意圖
registerReceiver(receiver, filter)
//如果過接受到的是 關閉activity的廣播 就呼叫finish()方法 把當前的activity finish()掉
4、遞迴退出
在開啟新的Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞迴關閉。
上面是網上的一些做法.
還可以通過intent的flag 來實現.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)啟用一個新的activity,然後在新的activity的oncreate方法裡面 finish掉, 但是一個應用可以有多個任務棧, 這樣可能會有問題.
講一講你對activity的理解
把上面的幾點用自己的心得寫出來
- service是否在main thread中執行, service裡面是否能執行耗時的操作?
預設情況,如果沒有顯示的指定service所執行的程式,Service和activity是執行在當前app所在程式的main thread(UI主執行緒)裡面
service裡面不能執行耗時的操作(網路請求,拷貝資料庫,大檔案 )
在子執行緒中執行new Thread(){}.start();
Thread.currentThread().getName();
特殊情況,可以在清單檔案配置 service 執行所在的程式 ,讓service在另外的程式中執行
ActivityManagerService
- 兩個Activity之間怎麼傳遞資料?
基本資料型別可以通過.Intent 傳遞資料
extras.putDouble(key,value)
intent.putExtra(name, value)
//通過intent putExtra方法 基本資料型別 都傳遞
intent.getStringExtra("key","value");
intent.getBooleanExtra("key","value")
Bundlebundle= new Bundle();
bumdle.putShort(key, value);
intent.putExtras(bumdle);
intent.putExtras(bundle)
Application 全域性裡面存放 物件 ,自己去實現自己的application的這個類,基礎系統的application , 每個activity都可以取到
讓物件實現implementsSerializable介面把物件存放到檔案上.
讓類實現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:存入記憶體
檔案/網路
intent.setData(Uri)
Uri.fromFile(); //大圖片的傳遞
- 怎麼讓在啟動一個Activity是就啟動一個service?
在activity的onCreate()方法裡面 startService();
11.同一個程式,但不同的Activity是否可以放在不同的Task任務棧中?
Singleinstance 執行在另外的單獨的任務棧裡面
比方說在啟用一個新的activity時候, 給intent設定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);
- Activity怎麼和service繫結,怎麼在activity中啟動自己對應的service?*
startService() 一旦被建立 呼叫者無關沒法使用service裡面的方法
bindService () 把service 與呼叫者繫結 ,如果呼叫者被銷燬, service會銷燬
bindService() 我們可以使用service 裡面的方法
bindService(). 讓activity能夠訪問到 service裡面的方法
構建一個intent物件,
Intent service = new Intent(this,MyService.class);
通過bindService的方法去啟動一個服務,
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有哪些啟動方法,有什麼區別,怎樣停用Service?
在Service的生命週期中,被回撥的方法比Activity少一些,只有onCreate, onStart, onDestroy,onBind和onUnbind。
通常有兩種方式啟動一個Service,他們對Service生命週期的影響是不一樣的。
1 通過startService
Service會經歷 onCreate 到onStart,然後處於執行狀態,stopService的時候呼叫onDestroy方法。
如果是呼叫者自己直接退出而沒有呼叫stopService的話,Service會一直在後臺執行。
2 通過bindService
Service會執行onCreate,然後是呼叫onBind, 這個時候呼叫者和Service繫結在一起。呼叫者退出了,Srevice就會呼叫onUnbind->onDestroyed方法。
所謂繫結在一起就共存亡了。呼叫者也可以通過呼叫unbindService方法來停止服務,這時候Srevice就會呼叫onUnbind->onDestroyed方法。
需要注意的是如果這幾個方法交織在一起的話,會出現什麼情況呢?
一個原則是Service的onCreate的方法只會被呼叫一次,就是你無論多少次的startService又bindService,Service只被建立一次。
如果先是bind了,那麼start的時候就直接執行Service的onStart方法,如果先是start,那麼bind的時候就直接執行onBind方法。
如果service執行期間呼叫了bindService,這時候再呼叫stopService的話,service是不會呼叫onDestroy方法的,service就stop不掉了,只能呼叫UnbindService, service就會被銷燬
如果一個service通過startService 被start之後,多次呼叫startService 的話,service會多次呼叫onStart方法。多次呼叫stopService的話,service只會呼叫一次onDestroyed方法。
如果一個service通過bindService被start之後,多次呼叫bindService的話,service只會呼叫一次onBind方法。
多次呼叫unbindService的話會丟擲異常。
- 不用service,B頁面為音樂播放,從A跳轉到B,再返回,如何使音樂繼續播放?
遇到問題, 可以隨機應變,靈活發揮,多考慮些細節,比如說這個題就可以這樣說,說說你對startActivityForResult的理解()
A開啟B的時候,用startActivityForResult()方法, B返回的時候把播放的狀態資訊返回給A ,A繼續播放音樂.
- 什麼是IntentService?有何優點?
普通的service ,預設執行在ui main 主執行緒
Sdk給我們提供的方便的,帶有非同步處理的service類,
必須有無參構造方法
OnHandleIntent() 處理耗時的操作
16.什麼時候使用Service?
擁有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等執行在相同的程式中,那麼將會增加該程式的重要性。
1.Service的特點可以讓他在後臺一直執行,可以在service裡面建立執行緒去完成耗時的操作.
2.Broadcast receiver捕獲到一個事件之後,可以起一個service來完成一個耗時的操作.
3.遠端的service如果被啟動起來,可以被多次bind, 但不會重新create. 索愛手機X10i的人臉識別的service可以被相簿使用,可以被攝像機,照相機等程式使用.
- 請描述一下Intent 和 Intent Filter。
Android 中通過 Intent 物件來表示一條訊息,一個 Intent 物件不僅包含有這個訊息的目的地,還可以包含訊息的內容,這好比一封 Email,其中不僅應該包含收件地址,還可以包含具體的內容。對於一個 Intent 物件,訊息“目的地”是必須的,而內容則是可選項。
通過Intent 可以實現各種系統元件的呼叫與啟用.
data/system/package.xml
Intent filter: 可以理解為郵局或者是一個信箋的分揀系統…
這個分揀系統通過3個引數來識別
Action: 動作 view
Data: 資料uri uri
Category : 而外的附加資訊
Action 匹配
Action 是一個使用者定義的字串,用於描述一個 Android 應用程式元件,一個 Intent Filter 可以包含多個 Action。在 AndroidManifest.xml 的 Activity 定義時可以在其 節點指定一個 Action 列表用於標示 Activity 所能接受的“動作”,例如:
……
如果我們在啟動一個Activity時使用這樣的Intent物件:
Intent intent =new Intent();
intent.setAction("cn.itcast.action");
那麼所有的Action列表中包含了“cn.itcast”的Activity都將會匹配成功。
Android預定義了一系列的Action分別表示特定的系統動作。這些Action通過常量的方式定義在android.content. Intent中,以“ACTION_”開頭。我們可以在Android 提供的文件中找到它們的詳細說明。
URI 資料匹配
一個Intent 可以通過 URI 攜帶外部資料給目標元件。在 節點中,通過 節點匹配外部資料。
mimeType 屬性指定攜帶外部資料的資料型別,scheme 指定協議,host、port、path 指定資料的位置、埠、和路徑。如下:
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 資料匹配才會成功。
Category 類別匹配
節點中可以為元件定義一個 Category 類別列表,當 Intent 中包含這個列表的所有專案時 Category 類別匹配才會成功。
預設是DEFAULT
- Intent傳遞資料時,可以傳遞哪些型別資料?
1.一般的基本資料型別 Intent .putextra() intent.getextra();
2.資料的uri, intent.setData() intent.getData();
- 說說Activity,Intent,Service是什麼關係 。
麥當勞和麥當娜的關係是什麼關係?
這種問題,就講下activity,講一下service,說一下 通過intent去啟用元件,傳遞資料.
說自己專案中有這樣一個網路更新的功能,顯示介面就用的activity, 後臺有個service每隔半小時都去訪問下伺服器獲取更新的資料…
開啟服務用的是intent來開啟
- 請描述一下Broadcast Receiver。
有很多廣播接收者,系統已經實現了.
廣播分兩種有序廣播
無序廣播
指定接收者的廣播. 是不可以被攔截掉的
abortBroadcast();
用於接收系統的廣播通知, 系統會有很多sd卡掛載,手機重啟,廣播通知,低電量,來電,來簡訊等….有些應用通過這些廣播啟動後臺服務, 避免被殺死
電量改變廣播, 必須動態註冊
來獲取簡訊到來的廣播, 根據黑名單來判斷是否攔截該簡訊.
畫畫板生成圖片後,傳送一個sd掛載的通知,通知系統的gallery去獲取到新的圖片.
Intent intent =newIntent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
可以作為元件間通訊工具. EventBus
- 在manifest和程式碼中如何註冊和使 用 broadcast receiver 。
設定廣播接收者的優先順序,設定廣播接受者的action名字 等…
詳細見工程程式碼.
- 請介紹下Android的資料儲存方式。
檔案訪問許可權. sdcard /
資料庫sqlite
SharedPreference //shared_preps
網路socket tcp udp , http httpurlconnection
- 請介紹下ContentProvider是如何實現資料共享的。
把自己的資料通過uri的形式共享出去
android 系統下 不同程式 資料預設是不能共享訪問
需要去實現一個類去繼承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[])
}
- 為什麼要用ContentProvider?它和sql的實現上有什麼差別?
遮蔽資料儲存的細節,對使用者透明,使用者只需要關心運算元據的uri就可以了
不同app之間共享,運算元據
Sql也有增刪改查的方法.
但是contentprovider 還可以去增刪改查本地檔案. xml檔案的讀取,更改,
網路資料讀取更改
- 請介紹下Android中常用的五種佈局。
FrameLayout(幀佈局),LinearLayout (線性佈局),AbsoluteLayout(絕對佈局),RelativeLayout(相對佈局),TableLayout(表格佈局)
FrameLayout
從螢幕的左上角開始佈局,疊加顯示, 實際應用 播放器的暫停按鈕.
LinearLayout
線性佈局,這個東西,從外框上可以理解為一個div,他首先是一個一個從上往下羅列在螢幕上。每一個LinearLayout裡面又可分為垂直佈局
(android:orientation="vertical")和水平佈局(android:orientation="horizontal"
)。當垂直佈局時,每一行就只有一個元素,多個元素依次垂直往下;水平佈局時,只有一行,每一個元素依次向右排列。
AbsoluteLayout
絕對佈局猶如div指定了absolute屬性,用X,Y座標來指定元素的位置android:layout_x="20px"
android:layout_y="12px"
qq鬥地主 qq遊戲大廳 800480 800480.apk fwvga 854*480
指定平板機型的遊戲開發中經常用到絕對佈局widget 絕對佈局
指定機型的平板遊戲開發機頂盒開發。. 2.3 3.0
1.介面佈局工作管理員gridview
2.手機任務管理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裡面可以具體定義每一個元素,設定他的對齊方式 android:gravity="" 。
每一個佈局都有自己適合的方式,另外,這五個佈局元素可以相互巢狀應用,做出美觀的介面。
oa 自動化 生成報表 ,圖示 表示
可以說一下螢幕適配
PercentRelativeLayout、PercentFrameLayout
- 談談UI中, Padding和Margin有什麼區別?
Padding 文字對邊框, margin是控制元件對父窗體.android:layout_xxx, android:xxx
- widget相對位置的完成在activity的哪個生命週期階段實現。
widget可以理解成桌面小控制元件,
也可以理解成某個button, imageview這樣的控制元件…
onCreate, onStart, onResume,都得不到
1.在onWindowFocusChanged 可以得到
mTv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
System.out.println("onGlobalLayout: "+mTv.getHeight());
mTv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
mTv.post(new Runnable() {
@Override
public void run() {
System.out.println("run: "+mTv.getHeight());
}
});
onmeasure() // 計算控制元件的寬高, 只要這個方法執行完, 控制元件的寬高就有了
某個view 要顯示在介面 ondraw 被顯示到介面上的 .
onSizeChanged
-
請解釋下在單執行緒模型中Message、Handler、MessageQueue、Looper之間的關係。
-
AIDL的全稱是什麼?如何工作?
Android interface definition language (android介面定義語言) , 用來跨程式的訪問方法,
訪問遠端的服務的方法. 如何工作 day7 queryStudent .
手機衛士Itelephony 介面結束通話電話.
- 請解釋下Android程式執行時許可權與檔案系統許可權的區別。
Android程式執行需要讀取到安全敏感項必需在androidmanifest.xml中宣告相關許可權請求, 打電話,訪問網路,獲取座標,讀寫sd卡,讀寫聯絡人等..安裝的時候會提示使用者…
drwx
檔案系統的許可權是linux許可權. 比如說sharedpreference裡面的Context.Mode.private Context.Mode.world_read_able Context.Mode_world_writeable
777自己 同組 其他rwxrwxrwx
- 系統上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?
找到對應的瀏覽器的意圖(Action),傳遞資料URI , 啟用這個意圖
Intent intent =newIntent();
intent.setClassName(packageName,className);
intent.seturi()
- 對android主執行緒的運用和理解。
主ui執行緒不能執行耗時的操作,main方法, 死迴圈
- 對android虛擬機器的理解,包括記憶體管理機制垃圾回收機制。
虛擬機器很小,空間很小,談談移動裝置的虛擬機器的大小限制 16M ,很多ROM都修改了, 小米3,128MB
談談載入圖片的時候怎麼處理大圖片的,d
垃圾回收,沒有引用的物件,在某個時刻會被系統gc掉.
手動呼叫System.gc()有用嗎? 有用!但是會導致介面卡, 放在合適的位置.
- Framework工作方式及原理,Activity是如何生成一個view的,機制是什麼。
反射, 配置檔案
可以講下activity的原始碼,比如說 每個activity裡面都有window.callback和keyevent.callback,一些回撥的介面或者函式吧. 框架把activity建立出來就會呼叫裡面的這些回撥方法,會呼叫activity生命週期相關的方法.
Activity建立一個view是通過 ondraw 畫出來的, 畫這個view之前呢,還會呼叫onmeasure方法來計算顯示的大小.
- android本身的一些限制,比如apk包大小限制,讀取大檔案時的時間限。
這個問題問的有問題, apk包大小限制不好說,
極品飛車有100M 還是能裝到手機上,
世面google market 上大程式 主程式 很小 5~10M 下載sdcard
15分鐘之內 申請退款
apk包,精簡包, 素材存放在伺服器. 遊戲程式.
讀大檔案的時間限制應該是main執行緒裡面的時間限制吧.
Activity 不要超過5秒.
Service 不要超過20秒
- 如何載入的音樂資訊,如何改善其效率。
Android提供mediascanner,mediaStore等介面, 音樂檔案的資訊都會存放到系統的資料庫表中,可以通過content provider獲取,
顯示出來,改善效率,是個常見問題, 可以從以下幾個方面作答,
分批載入資料, 延時載入資料, 合理使用快取等...
- ListView如何提高其效率?
複用convertview , 歷史的view物件
減少子孩子查詢的次數viewholder
非同步載入資料, 分頁載入資料,
使用靜態的view物件 避免建立過多的view.
setTag, 區域性重新整理.
38.啟動應用後,改變系統語言,應用的語言會改變麼?
2.3有bug, 不會, 後面版本可以.
- 啟動一個程式,可以主介面點選圖示進入,也可以從一個程式中跳轉過去,二者有什麼區別?
區別是根據activity在manifest裡面的配置,這個activity可能會放在不同的task棧裡面.intent設定的flag flag_new_task
- Android程式與Java程式的區別?
Android程式用android sdk開發,java程式用javasdk開發.
Android SDK引用了大部分的Java SDK,少數部分被Android SDK拋棄,比如說介面部分,java.awt swing package除了java.awt.font被引用外,其他都被拋棄,在Android平臺開發中不能使用。 android sdk 新增工具jar httpclient , pull opengl
將Java 遊戲或者j2me程式移植到Android平臺的過程中,
Android SDK 與Java SDK的區別是很需要注意的地方。
sampledataadpter()
- Android中Task任務棧的分配。
首先我們來看下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而言的。
Activity有不同的啟動模式, 可以影響到task的分配
Task,簡單的說,就是一組以棧的模式聚集在一起的Activity元件集合。它們有潛在的前後驅關聯,新加入的Activity元件,位於棧頂,並僅有在棧頂的Activity,才會有機會與使用者進行互動。而當棧頂的Activity完成使命退出的時候,Task會將其退棧,並讓下一個將跑到棧頂的Activity來於使用者面對面,直至棧中再無更多Activity,Task結束。
如上表所示,是一個例項。從使用者從進入郵箱開始,到回覆完成,退出應用整個過程的Task棧變化。這是一個標準的棧模式,對於大部分的狀況,這樣的Task模型,足以應付,但是,涉及到實際的效能、開銷等問題,就會變得殘酷許多。
比如,啟動一個瀏覽器,在Android中是一個比較沉重的過程,它需要做很多初始化的工作,並且會有不小的記憶體開銷。但與此同時,用瀏覽器開啟一些內容,又是一般應用都會有的一個需求。設想一下,如果同時有十個執行著的應用(就會對應著是多個Task),都需要啟動瀏覽器,這將是一個多麼殘酷的場面,十個Task棧都堆積著很雷同的瀏覽器Activity,
是多麼華麗的一種浪費啊。
於是你會有這樣一種設想,瀏覽器Activity,可不可以作為一個單獨的Task而存在,不管是來自那個Task的請求,瀏覽器的Task,都不會歸併過去。這樣,雖然瀏覽器Activity本身需要維繫的狀態更多了,但整體的開銷將大大的減少,這種舍小家為大家的行為,還是很值得歌頌的
standard", "singleTop", "singleTask", "singleInstance"。
standard模式, 是預設的也是標準的Task模式,在沒有其他因素的影響下,使用此模式的Activity,會構造一個Activity的例項,加入到呼叫者的Task棧中去,對於使用頻度一般開銷一般什麼都一般的Activity而言,standard模式無疑是最合適的,因為它邏輯簡單條理清晰,所以是預設的選擇。
而singleTop模式,基本上於standard一致,僅在請求的Activity正好位於棧頂時,有所區別。此時,配置成singleTop的Activity,不再會構造新的例項加入到Task棧中,而是將新來的Intent傳送到棧頂Activity中,棧頂的Activity可以通過過載onNewIntent來處理新的Intent(當然,也可以無視...)。這個模式,降低了位於棧頂時的一些重複開銷,更避免了一些奇異的行為(想象一下,如果在棧頂連續幾個都是同樣的Activity,再一級級退出的時候,這是怎麼樣的使用者體驗...),很適合一些會有更新的列表Activity展示。一個活生生的例項是,在Android預設提供的應用中,瀏覽器(Browser)的書籤Activity(BrowserBookmarkPage),就用的是singleTop。
singleTask,和singleInstance,則都採取的另闢Task的蹊徑。
標誌為singleTask的Activity,最多僅有一個例項存在,並且,位於以它為根的Task中。所有對該Activity的請求,都會跳到該Activity的Task中展開進行。singleTask,很象概念中的單件模式,所有的修改都是基於一個例項,這通常用在構造成本很大,但切換成本較小的Activity中。最典型的例子,還是瀏覽器應用的主Activity(名為Browser...),它是展示當前tab,當前頁面內容的視窗。它的構造成本大,但頁面的切換還是較快的,於singleTask相配,還是挺天作之合的。
singleInstance顯得更為極端一些。在大部分時候singleInstance與singleTask完全一致,唯一的不同在於,singleInstance的Activity,是它所在棧中僅有的一個Activity,如果涉及到的其他Activity,都移交到其他Task中進行。這使得singleInstance的Activity,像一座孤島,徹底的黑盒,它不關注請求來自何方,也不計較後續由誰執行。在Android預設的各個應用中,很少有這樣的Activity,在我個人的工程實踐中,曾嘗試在有道詞典的快速取詞Activity中採用過,
是因為我覺得快速取詞入口足夠方便(從notification中點選進入),並且會在各個場合使用,應該做得完全獨立。
預設任務棧名字為包名, 可以自己配置
Activity的android:affinity屬性
1.配置後當啟動這個activity時就先去找有沒有activity的親和力屬性相同有就加入這個activity所在的任務中沒有就新開任務棧
2.affinity起作用需要的條件二者具備一個:
1.intent包含FLAG_ACTIVITY_NEW_TASK標記
2.activity元素啟用了allowTaskReparenting屬性.
- 在Android中,怎麼節省記憶體的使用,怎麼主動回收記憶體?
回收已經使用的資源,
合理的使用快取
合理設定變數的作用範圍…application 物件
//未來的某一段時間執行
System.gc();
- 不同工程中的方法是否可以相互呼叫?
可以,列舉aidl訪問遠端服務的例子.
44.在Android中是如何實現判斷區分電話的狀態,去電,來電、未接來電?
去電有廣播, 來電沒有, TelephonyManager, PhoneStateListener
- dvm的程式和Linux的程式, 應用程式的程式是否為同一個概念
Dvm的程式是dalivk虛擬機器程式,每個android程式都執行在自己的程式裡面,
每個android程式系統都會給他分配一個單獨的liunx uid(user id),
每個dvm都是linux裡面的一個程式.所以說這兩個程式是一個程式.
- 如何判斷是否有SD卡?
配置檔案中有sd卡的許可權, 通過environment的靜態方法,
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- 一條最長的簡訊息約佔多少byte?
中文70(包括標點),英文160,160個位元組 這個說法不準確,
要跟手機制式運營商等資訊有關.
做實驗,看原始碼
ArrayList msgs = sms.divideMessage(message);
for (String msg : msgs) {
sms.sendTextMessage(phoneNumber, null, msg, pi, null);
}
- 談談對Android NDK的理解。
native develop kit 只是一個交叉編譯的工具 .so
1.什麼時候用ndk, 實時性要求高,遊戲,圖形渲染, opencv (人臉識別) , ffmpeg , rmvb mp5 avi 高清解碼. ffmpeg, opencore.
2.為什麼用ndk,ndk的優點 ,缺點 ,
我們專案中那些地方用到了ndk,祕鑰
- 談談Android的優點和不足之處。
1、開放性,開源 ophone 阿里雲( 完全相容android)
2、掙脫運營商束縛
3、豐富的硬體選擇 mtk android
4、不受任何限制的開發商
5、無縫結合的Google應用
缺點:
1、安全問題、隱私問題
2、碎片化
3、過分依賴開發商,缺乏標準配置
- Android系統中GC什麼情況下會出現記憶體洩露呢? 視訊編解碼/記憶體洩露
檢測記憶體洩露工具
mat
C:\Users\lenovo\Desktop\prof>hprof-conv com.example.testmat.hprof convert-com.ex
ample.testmat.hprof
導致記憶體洩漏主要的原因是,先前申請了記憶體空間而忘記了釋放。如果程式中存在對無用物件的引用,那麼這些物件就會駐留記憶體,消耗記憶體,因為無法讓垃圾回收器GC驗證這些物件是否不再需要。如果存在物件的引用,這個物件就被定義為"有效的活動",同時不會被釋放。要確定物件所佔記憶體將被回收,我們就要務必確認該物件不再會被使用。典型的做法就是把物件資料成員設為null或者從集合中移除該物件。但當區域性變數不需要時,不需明顯的設為null,因為一個方法執行完畢時,這些引用會自動被清理。
Java帶垃圾回收的機制,為什麼還會記憶體洩露呢?
Vector v = new Vector(10);
for (int i = 1; i < 100; i++) {
Object o = new Object();
v.add(o);
o = null;
}//此時,所有的Object物件都沒有被釋放,因為變數v引用這些物件。
觀察者模式解除註冊
Java 記憶體洩露的根本原因就是儲存了不可能再被訪問的變數型別的引用
- Android UI中的View如何重新整理。
在主執行緒中拿到view呼叫invalide()方法
在子執行緒裡面可以通過postInvalide()方法;
requestLayout
- 簡單描述下Android 數字簽名。
Android 數字簽名
在Android系統中,所有安裝到系統的應用程式都必有一個數字證照,此數字證照用於標識應用程式的作者和在應用程式之間建立信任關係
Android系統要求每一個安裝進系統的應用程式都是經過數字證照籤名的,數字證照的私鑰則儲存在程式開發者的手中。Android將數字證照用來標識應用程式的作者和在應用程式之間建立信任關係,不是用來決定終端使用者可以安裝哪些應用程式。
這個數字證照並不需要權威的數字證照籤名機構認證(CA),它只是用來讓應用程式包自我認證的。
同一個開發者的多個程式儘可能使用同一個數字證照,這可以帶來以下好處。
(1)有利於程式升級,當新版程式和舊版程式的數字證照相同時,Android系統才會認為這兩個程式是同一個程式的不同版本。如果新版程式和舊版程式的數字證照不相同,則Android系統認為他們是不同的程式,併產生衝突,會要求新程式更改包名。
(2)有利於程式的模組化設計和開發。Android系統允許擁有同一個數字簽名的程式執行在一個程式中,Android程式會將他們視為同一個程式。所以開發者可以將自己的程式分模組開發,而使用者只需要在需要的時候下載適當的模組。
在簽名時,需要考慮數字證照的有效期:
(1)數字證照的有效期要包含程式的預計生命週期,一旦數字證照失效,持有改數字證照的程式將不能正常升級。
(2)如果多個程式使用同一個數字證照,則該數字證照的有效期要包含所有程式的預計生命週期。
(3)Android Market強制要求所有應用程式數字證照的有效期要持續到2033年10月22日以後。
Android數字證照包含以下幾個要點:
(1)所有的應用程式都必須有數字證照,Android系統不會安裝一個沒有數字證照的應用程式
(2)Android程式包使用的數字證照可以是自簽名的,不需要一個權威的數字證照機構簽名認證
(3)如果要正式釋出一個Android ,必須使用一個合適的私鑰生成的數字證照來給程式簽名,而不能使用adt外掛或者ant工具生成的除錯證照來發布。
(4)數字證照都是有有效期的,Android只是在應用程式安裝的時候才會檢查證照的有效期。如果程式已經安裝在系統中,即使證照過期也不會影響程式的正常功能。
- 什麼是ANR 如何避免它?
在Android上,如果你的應用程式有一段時間響應不夠靈敏,系統會向使用者顯示一個對話方塊,這個對話方塊稱作應用程式無響應(ANR:Application Not Responding)對話方塊。使用者可以選擇讓程式繼續執行,但是,他們在使用你的應用程式時,並不希望每次都要處理這個對話方塊。因此,在程式裡對響應效能的設計很重要,這樣,系統不會顯示ANR給使用者。
Activity 5秒 broadcast10秒, service20秒
耗時的操作worker thread裡面完成, handler message…AsynTask , intentservice.等…
Data/anr/traces.txt
- android中的動畫有哪幾類,它們的特點和區別是什麼?
兩種,一種是Tween動畫、還有一種是Frame動畫。
Tween動畫,這種實現方式可以使檢視元件移動、放大、縮小以及產生透明度的變化;
可以通過佈局檔案,可以通過程式碼
1、控制View的動畫
a)alpha(AlphaAnimation)
漸變透明
b)scale(ScaleAnimation)
漸變尺寸伸縮
c)translate(TranslateAnimation)
畫面轉換、位置移動
d)rotate(RotateAnimation)
畫面轉移,旋轉動畫
2、控制一個Layout裡面子View的動畫效果
a)layoutAnimation(LayoutAnimationController)
b)gridAnimation(GridLayoutAnimationController)
另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。
屬性動畫ObjectAnimator, ValueAnimator, TypeEvaluator
Nineoldandroids.jar, 和真正的屬性動畫還是不一樣.
scrollTo/scrollBy
- 說說mvc模式的原理,它在android中的運用。
MVC英文即Model-View-Controller,即把一個應用的輸入、處理、輸出流程按照Model、View、Controller的方式進行分離,這樣一個應用被分成三個層——模型層、檢視層、控制層。
Android中介面部分也採用了當前比較流行的MVC框架,在Android中M就是應用程式中二進位制的資料,V就是使用者的介面。Android的介面直接採用XML檔案儲存的,介面開發變的很方便。在Android中C也是很簡單的,一個Activity可以有多個介面,只需要將檢視的ID傳遞到setContentView(),就指定了以哪個檢視模型顯示資料。
在Android SDK中的資料繫結,也都是採用了與MVC框架類似的方法來顯示資料。在控制層上將資料按照檢視模型的要求(也就是Android SDK中的Adapter)封裝就可以直接在檢視模型上顯示了,從而實現了資料繫結。比如顯示Cursor中所有資料的ListActivity,其檢視層就是一個ListView,將資料封裝為ListAdapter,並傳遞給ListView,資料就在ListView中顯示。
MVP
MVVM
- 通過點選一個網頁上的url 就可以完成程式的自動安裝,描述下原理
Day11 AddJavascriptInterface, Java/JS互相呼叫
new Object{
callphone();
installapk();
}
http://1.vduntest.sinaapp.com/webview/WebView%E8%AF%A6%E8%A7%A3.html
57,Service和Activity在同一個執行緒嗎
預設情況同一執行緒main主執行緒 ui執行緒
58,java中的soft reference是個什麼東西
StrongReference 是 Java 的預設引用實現, 它會盡可能長時間的存活於 JVM 內, 當沒有任何物件指向它時 GC 執行後將會被回收
SoftReference 會盡可能長的保留引用直到 JVM 記憶體不足時才會被回收(虛擬機器保證), 這一特性使得 SoftReference 非常適合快取
應用詳細見客戶端圖片的快取
LruCache
59,udp連線和TCP的不同之處
Tcp三次握手. 面向連線 流
udp 不關心資料是否達到,是否阻塞 面向無連線
畫面優先. tcp
流暢優先udp
http基於tcp
60, android開發中怎麼去除錯bug
邏輯錯誤
1.斷點 debug
- logcat
介面佈局,ActivityManager,hierarchyview
61.service裡面可以彈土司麼
可以, 對於對話方塊, 需要加許可權
AlertDialog dialog = new AlertDialog.Builder(this).setTitle("標題").setMessage("內容").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呼叫常用的兩個引數
JNIEnv *env, jobject javaThis
- 書寫出android工程的目錄結構
src
android. jar
asset
res
gen
manifest
- ddms 和traceview的區別.
daivilk debug manager system
1.在應用的主activity的onCreate方法中加入Debug.startMethodTracing("要生成的traceview檔案的名字");
2.同樣在主activity的onStop方法中加入Debug.stopMethodTracing();
3.同時要在AndroidManifest.xml檔案中配置許可權
3.重新編譯,安裝,啟動服務,測試完成取對應的traceview檔案(adb pull /sdcard/xxxx.trace)。
4.直接在命令列輸入traceview xxxxtrace,彈出traceview視窗,分析對應的應用即可。
traceview 分析程式執行時間和效率
KPI : key performance information : 關鍵效能指標:
splash介面不能超過5秒
從splash 介面載入mainactivity 不能超過0.7秒
- 利用mvc的模式重構程式碼
1)重構前的程式碼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:抽取所有介面元件的宣告和定義,整合到單獨一個函式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:抽取程式的邏輯(即介面元件的處理邏輯),整合到函式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:修改按鈕監聽器calcBMI中相應的部分(主要是變數已經在檢視部分定義了);
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);
}
}
};
總之,此重構的目的無非是使程式的脈絡更加清晰,即讓人一眼望去,就能很容易地分辨出介面(View)應該寫在哪裡,程式邏輯(Controller)應該寫在哪裡,最終使維護和擴充套件程式碼變得更加容易!
其實,重構很簡單,通讀程式碼,感覺哪邊不太爽,就改那邊吧!(我目前的感受)
一個良好的程式碼應該是能讓人感到舒服的!
2)重構後的程式碼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);
}
}
};
}
總結:
關於專案
在就是你專案經驗,一定要突出你遇到什麼難點,然後是怎麼解決的!把問題引導到你熟悉的領域,或者知識點上,儘量將每個技術點細節凸顯出來,