編輯:關於Android編程
1、TCP和UDP之間的區別?什麼是URL ?
TCP被稱為用戶數據報協議;UDP被稱為信息傳輸控制協議;URL被稱為統一資源定位符,通過統一資源定位符可以唯一定位到互聯網上的某個資源(圖片、視頻、音頻和網頁等)。
2、成員方法和構造方法有什麼區別?
成員方法必須有返回類型,即使是沒有返回,也要寫上void;構造函數沒有返回類型,而且和類名一樣。
3、什麼是棧?
棧是一種先進後出的線性表,只要符合先進後出的原則的線性表都是棧。至於采用的存儲方式(實現方式)是順序存儲(順序棧)還是鏈式存儲(鏈式棧)是沒有關系的。堆則是二叉樹的一種,有最大堆最小堆,排序算法中有常用的堆排序。
4、常用的流分別有哪些?
(一)節點流
按字節:FileInputStream、FileOutputStream;按字符:FileReader、FileWriter
包裝流(處理流、過濾流)是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫
(二)緩沖相關(可以大幅提升性能)
按字節: BufferedInputStream、BufferedOutputStream
按字符: BufferedReader、BufferedWriter
1)過濾處理
按字節: FilterInputStream、FilterOutputStream
按字符: FilterReader、FilterWriter
2)字節轉化成字符
輸入:InputStreamReader 輸出: OutputStreamWriter
3)對象序列化處理(要求放在流中的對象一定是實現Serializable接口)
輸入:ObjectInputStream 輸出: ObjectOutputStream
4)數據轉化處理(可以讀寫4類8中類型(包含String)的數據)
輸入: DataInputStream 輸出:DataOutputStream
5、Java的常用設計模式:
單例模式:
public class Singleton {
//將自身的實例對象設置為一個屬性,並加上Static和final修飾符
private static final Singleton instance = new Singleton();
//將構造方法設置成私有形式
private Singleton() {
}
//通過一個靜態方法向外界提供這個類的實例
public static Singleton getInstance() {
return instance;
}
}
工廠模式:
public class Factory{
public ClassesDao getClassesDao(){
ClassesDao cd = new ClassesDaoImpl();
return cd;
}
}
interface ClassesDao{
public String getClassesName();
}
class ClassesDaoImpl implements ClassesDao {
public String getClassesName(){
System.out.println("A班");
}
}
class test
{
public static void main(String[] args){
Factory f = new Factory();
f.getClassesDao().getClassesName();
}
}
觀察者模式:
public abstract class Subject {
/**
* 用來保存注冊的觀察者對象
*/
private List
/**
* 注冊觀察者對象
* @param observer 觀察者對象
*/
public void attach(Observer observer){
list.add(observer);
System.out.println("Attached an observer");
}
/**
* 刪除觀察者對象
* @param observer 觀察者對象
*/
public void detach(Observer observer){
list.remove(observer);
}
/**
* 通知所有注冊的觀察者對象
*/
public void nodifyObservers(String newState){
for(Observer observer : list){
observer.update(newState);
}
}
}
具體主題角色類
public class ConcreteSubject extends Subject{
private String state;
public String getState() {
return state;
}
public void change(String newState){
state = newState;
System.out.println("主題狀態為:" + state);
//狀態發生改變,通知各個觀察者
this.nodifyObservers(state);
}
}
抽象觀察者角色類
public interface Observer {
/**
* 更新接口
* @param state 更新的狀態
*/
public void update(String state);
}
具體觀察者角色類
public class ConcreteObserver implements Observer {
//觀察者的狀態
private String observerState;
public void update(String state) {
/**
* 更新觀察者的狀態,使其與目標的狀態保持一致
*/
observerState = state;
System.out.println("狀態為:"+observerState);
}
}
客戶端類
public class Client {
public static void main(String[] args) {
//創建主題對象
ConcreteSubject subject = new ConcreteSubject();
//創建觀察者對象
Observer observer = new ConcreteObserver();
//將觀察者對象登記到主題對象上
subject.attach(observer);
//改變主題對象的狀態
subject.change("new state");
}
}
6、什麼是Activity?
Activity是四大組件之一,一般情況下,一個用戶界面對應一個activity,兩個activity之間的跳轉、通訊、攜帶數據,通常使用Intent來實現。
7、Activity有哪些啟動模式?
Standard:是activity的默認啟動模式,可以不用在manifest文件中重寫配置,沒創建一個Activity實例,都會放在任務棧中,每啟動一個activity,都會創建一個activity;
SingleTop:可以有多個實例,但是不允許有多個相同的activity進行疊加,如果當前的activity在棧頂,則不會創建activity,其余情況都會創建activity;
SingleTask:只有一個實例,在同一應用中,如果不存在,task則會創建一個實例;如存在,會把存在於task之上的所有的Destroy掉,並調用OnnewIntent();
SingleInstance:只能有一個實例,並且這個實例是獨立運行的,不允許有其他的activity存在;
Activity的啟動模式通過AndroidManifest.xml文件中的元素的屬性來指定:
8、activity的生命周期:
onCreat( )創建
onStart( )開啟
onResume( )交互
onPause( )掛起
onStop( )停止
onDestory( )銷毀
onRestart( )重啟
9.什麼是ANR?如何避免?
ANR: Application Not Responding(程序未響應)
在Android中,活動管理器和窗口管理器這兩個系統服務負責見識應用程序,出現一下兩種情況會出現ANR:
主線程 (“事件處理線程” / “UI線程”) 在5秒內沒有響應輸入事件
BroadcastReceiver 沒有在10秒內完成返回
運行在主線程裡的任何方法都盡可能少做事情,可以避免ANR的產生。如Activity中的(onCreat和onResume方法中)盡量不要有耗時操作;網絡或數據庫操作,或者高耗時的計算如改變位圖尺寸,應該在子線程裡來完成或這用異步請求的方式。主線程應該為子線程提供一個Handler,以便完成時能夠提交給主線程。
10.Android常用的五大布局是哪些?
LinearLayout(線性布局)、FrameLayout(幀布局)、AbsoluteLayout(絕對布局)、RelativeLayout(相對布局)、TableLayout(表格布局)
11.Android的四大組件?簡述各自的作用?
Activity:
Activity是Android程序與用戶交互的窗口,是Android構造塊中最基本的一種,它需要為保持各界面的狀態,做很多持久化的事情,妥善管理生命周期以及一些跳轉邏輯。
service:
後台服務於 Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的事物,定義好需要接受的 Intent 提供同步和異步的接口。
Content Provider:
是 Android 提供的第三方應用數據的訪問方案,可以派生 Content Provider 類,對外提供數據,可以像數據庫一樣進行選擇排序,屏蔽內部數據的存儲細節,向外提供統一的接口模型,大大簡化上層應用,對數據的整合提供了更方便的途徑。
BroadCastReceiver:
接受一種或者多種 Intent 作觸發事件,接受相關消息,做一些簡單處理,轉換成一條 Notification,統一了 Android 的事件廣播模型。 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()方法。
12.ListView如何優化?
利用convertview(復用)優化資源
第一,定義一個內部類ViewHolder,在該類中定義item中的控件
第二,在getview類中把ViewHolder對象holder設置為null,再判斷convertview是否為空
第三,如果為空,則new一個ViewHolder對象(holder), 通過布局加載器加載convertview所對應的布局,通過convertview視圖布局實例化ViewHolder中的控件
第四,在把holder中的數據設置到convertview中去
第五,如果不為空,則convertview直接獲取holder的數據
第六,給item設置要顯示的數據
13.計算機網絡的七層模型?
應用層 (Application):網絡服務與最終用戶的一個接口。
協議有:HTTP FTP TFTP SMTP SNMP DNS
表示層(Presentation Layer):數據的表示、安全、壓縮。(在五層模型裡面已經合並到了應用層)格式有,JPEG、ASCll、DECOIC、加密格式等
會話層(Session Layer):建立、管理、終止會話。(在五層模型裡面已經合並到了應用層)對應主機進程,指本地主機與遠程主機正在進行的會話
傳輸層 (Transport):定義傳輸數據的協議端口號,以及流控和差錯效驗。
協議有:TCP UDP,數據包一旦離開網卡即進入網絡傳輸層網絡層 (Network):進行邏輯地址尋址,實現不同網絡之間的路徑選擇。
協議有:ICMP IGMP IP(IPV4 IPV6) ARP RARP
數據鏈路層 (Link):建立邏輯連接、進行硬件地址尋址、差錯校驗等功能。(由底層網絡定義協議)將比特組合成字節進而組合成幀,用MAC地址訪問介質,錯誤發現但不能糾正。
物理層(Physical Layer):建立、維護、斷開物理連接。(由底層網絡定義協議)
TCP/IP 層級模型結構:
應用層之間的協議通過逐級調用傳輸層(Transport layer)、網絡層(Network Layer)和物理數據鏈路層(Physical Data Link)而可以實現應用層的應用程序通信互聯。
14.你對Android動態升級與DexClassLoader動態加載技術有何了解?
Android的Dalvik/ART虛擬機如同標准JAVA的JVM虛擬機一樣,在運行程序時首先需要將對應的類加載到內存中。因此,我們可以利用這一點,在程序運行時手動加載Class,從而達到代碼動態加載可執行文件的目的。Android的Dalvik/ART虛擬機雖然與標准Java的JVM虛擬機不一樣,ClassLoader具體的加載細節不一樣,但是工作機制是類似的,也就是說在Android中同樣可以采用類似的動態加載插件的功能,只是在Android應用中動態加載一個插件的工作要比Eclipse加載一個插件復雜許多。
15.你對Android NDK與JNI有何了解?區別是什麼?
JNI是Java Native Interface的縮寫,中文為JAVA本地調用。從Java1.1開始,Java Native Interface(JNI)標准成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他語言,只要調用約定受支持就可以了。使用java與本地已編譯的代碼交互,通常會喪失平台可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統進行交互,或者為了提高程序的性能。JNI標准至少保證本地代碼能工作在任何Java 虛擬機實現下。 標准的java類庫可能不支持你的程序所需的特性。 JNI·或許你已經有了一個用其他語言寫成的庫或程序,而你希望在java程序中使用它。你可能需要用底層語言實現一個小型的時間敏感代碼,比如匯編,然後在你的java程序中調用這些功能。 NDK是Google公司推出的幫助Android開發者通過C/C++本地語言編寫應用的開發包,包含了C/C++的頭文件、庫文件、說明文檔和示例代碼,我們可以理解為Windows Platform SDK一樣,是純C/C++編寫的,但是Android並不支持純C/C++編寫的應用,同時NDK提供的庫和函數功能很有限,僅僅處理些算法效率敏感的問題,所以推薦初學者學好Java後再學習JNI。 NDK集成了交叉編譯器,並提供了相應的mk文件隔離CPU、平台、ABI等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。 NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。
16.如何進行反編譯,如何防止反編譯?
反編譯:
1.用apktool 把apk--> 資源包(java代碼變成smali文件看不懂的),可以修改資源包裡面的文件。
2.apk後綴名改成zip或rar解壓,獲取 classes.dex 文件,用dex2jar轉換成jar包(注:直接解壓出來的資源文件是不能直接打開的,要用第一步的反編譯工具,dex2jar.bat文件目錄不要有中文)。
3.用jd-ui等java反編譯工具直接查看java代碼。
4.把java代碼和第一版的資源包整到一起重新組成一個新的應用。
5.用apktool 重新編譯。
6.用簽名工具重新簽名。
7.重新發布帶新的簽名的應用。
防止編譯:
17.什麼是mvc ?mvc有哪些原理?
Model -View-control
model:代表應用的業務邏輯,用JavaBean和EJB實現。在Struts裡是用Action和ActionForm實現。
view:代表應用的表示層。用JSP頁面實現
controller:提供應用的處理過程控制。一般是一個servlet。在Struts裡用Action Servlet和ActionMapping實現。
MVC優點:
模型-視圖-控制器(MVC)是一種軟件設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分成三個核心部件:模型、視圖、控制器。它們各自處理自己的任務。
MVC缺點:
MVC的缺點是由於它沒有明確的定義,所以完全理解MVC並不是很容易。使用MVC需要精心的計劃,由於它的內部原理比較復雜,所以需要花費一些時間去思考。
18.寫Java線程中同步的方法,如何讓安全的退出一個線程?
設置一個全局bool變量, 然後在線程內部 while(全局bool變量), 在你需要退出線程的時候就在外面設置全局bool變量 = false, 這樣就退出了循環, 最後安全退出線程了.
19.Android中進程與進程之間數據傳遞的方式有哪些?
1、基於消息的通信機制 Intent---bounble,extra
2、利用static靜態數據 public static 成員變量
3、基於外部存儲的傳輸 File/Preference/Sqlite,如果要針對第三方應用需要Content Provider
4、基於IPC通信機制 Context 與 service之間的傳輸
20.Android中 Service和activity的交互方式有哪些?
1、Activity調用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service對象的一個引用,這樣Activity可以直接調用到Service中的方法,如果要主動通知Activity,我們可以利用回調方法
2、Service向Activity發送消息,可以使用廣播,當然Activity要注冊相應的接收器。比如Service要向多個Activity發送同樣的消息的話,用這種方法就更好。
21.Dalvik 和標准 Java 虛擬機之間的主要差別?Dalvik 和標准 Java 虛擬機(JVM)之間的首要差別之一,就是 Dalvik 基於寄存器,而
JVM 基於棧。
Dalvik 和 Java 之間的另外一大區別就是運行環境——Dalvik 經過優化,允許在有限的內
存中同時運行多個虛擬機的實例,並且每一個 Dalvik 應用作為一個獨立的 Linux 進程
執行。
(1)虛擬機很小,使用的空間也小;
(2)Dalvik 沒有 JIT 編譯器;
(3)常量池已被修改為只使用 32 位的索引,以簡化解釋器;
(4)它使用自己的字節碼,而非 Java 字節碼。
22. Manifest.xml 文件中主要包括哪些信息?
答:manifest:根節點,描述了 package 中所有的內容。
User-sdk:指定支持的手機系統的最小版本
application:包含 package 中 application 級別組件聲明的根節點。
activity:Activity 是用來與用戶交互的主要工具。
receiver:IntentReceiver 能使的 application 獲得數據的改變或者發生的操作,
即使它當前不在運行。
service:Service 是能在後台運行任意時間的組件。
provider:ContentProvider 是用來管理持久化數據並發布給其他應用程序使用的組
件。
uses-permission:請求你的 package 正常運作所需賦予的安全許可。
permission: 聲明了安全許可來限制哪些程序能你 package 中的組件和功能。
instrumentation:聲明了用來測試此 package 或其他 package 指令組件的代碼。
23. 如何退出 Activity?如何安全退出已調用多個Activity 的 Application?
在 Android 中退出程序比較麻煩,尤其是在多個 Activity 的程序中,在 2.2 之前可
以采用如下代碼退出程序:
1. ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);
2. am.restartPackage(getPackageName());
此種方法是一種最方便和最簡單的退出程序的辦法,但是在 2.2 和 2.2 之後就不能用了,
一種常用的方法是自定義一個 Activity 的棧,在程序退出時將棧中的所有的 Activity
進行 finish。
24.如果後台的 Activity 由於某原因被系統回收了,如何在被系統回收之前保存當前狀態?
答:重寫 onSaveInstanceState()方法,在此方法中保存需要保存的數據,該方法將會
在 activity 被回收之前調用。通過重寫 onRestoreInstanceState()方法可以從中
提取保存好的數據。
25.activity 在屏幕旋轉時的生命周期
答:不設置 Activity 的 android:configChanges 時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次;設置 Activity 的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次;設置 Activity 的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行 onConfigurationChanged 方法。
26.如何開發一個 Service 組件?
第一步:繼承 Service 類 public class SMSService extends Service {}
第二步:在 AndroidManifest.xml 文件中的節點裡對服務進行配
置:
第三步:啟動服務
方法一:context.startService():調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行
方法二:context.bindService():調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。 27. Service 的生命周期?
onCreate():
該方法在服務被創建時調用,該方法只會被調用一次,無論調用多少次startService()或 bindService()方法,服務也只被創建一次。
onDestroy():
該方法在服務被終止時調用。與采用 Context.startService()方法啟動服務有關的生命周期方法
onStart():
只有采用 Context.startService()方法啟動服務時才會回調該方法。該方法在服務開始運行時被調用。多次調用 startService()方法盡管不會多次創建服務,但onStart() 方法會被多次調用。
onBind():
只有采用 Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用 Context.bindService()方法並不會導致該方法被多次調用。
onUnbind():
只有采用 Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務解除綁定時被調用。
28. 簡單描述 AIDL 答:由於每個應用程序都運行在自己的進程空間,並且可以從應用程序 UI 運行另一個服
務進程,而且經常會在不同的進程間傳遞對象。在 Android 平台,一個進程通常不能訪問另一個進程的內存空間,所以要想對話,需要將對象分解成操作系統可以理解的基本單元,並且有序的通過進程邊界。
通過代碼來實現這個數據傳輸過程是冗長乏味的,Android 提供了 AIDL 工具來處理這項
工作。
AIDL (Android Interface Definition Language)是一種 IDL 語言,用於生成可以在 Android 設備上兩個進程之間進行進程間通信(IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如 Service)對象的操作,就可以使用 AIDL 生成可序列化的參數。
AIDL 支持的數據類型:
1. 不需要 import 聲明的簡單 Java 編程語言類型(int,boolean 等)
2. String, CharSequence 不需要特殊聲明
3. List, Map 和 Parcelables 類型, 這些類型內所包含的數據成員也只能是簡單數據類型, String 等其他比支持的類型. 29. 請描述一下 Broadcast Receiver
Broadcast Receiver 用於接收並處理廣播通知(broadcast announcements)。多數的廣播是系統發起的,如地域變換、電量不足、來電來信等。程序也可以播放一個廣播。程序可以有任意數量的 broadcast receivers 來響應它覺得重要的通知。broadcast receiver 可以通過多種方式通知用戶:啟動 activity、使用NotificationManager、開啟背景燈、振動設備、播放聲音等,最典型的是在狀態欄顯示一個圖標,這樣用戶就可以點它打開看通知內容。通常我們的某個應用或系統本身在某些事件(電池電量不足、來電來短信)來臨時會廣播一個 Intent 出去,我們可以利用注冊一個 Broadcast Receiver 來監聽到這些 Intent 並獲取 Intent 中的數據。
30. 注冊廣播有幾種方式,這些方式有何優缺點?
答:首先寫一個類要繼承 BroadcastReceiver
第一種:在清單文件中聲明,添加
android:name="android.provider.Telephony.SMS_RECEIVED")
第二種使用代碼進行注冊如:
IntentFilter filter = new
IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(receiver.filter);
兩種注冊類型的區別是:
第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。
第二種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
31. 請介紹下 ContentProvider 是如何實現數據共享的
一個程序可以通過實現一個 Content provider 的抽象接口將自己的數據完全暴露出去,而且 Content providers 是以類似數據庫中表的方式將數據暴露。Content providers 存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。 要想使應用程序的數據公開化,可通過 2 種方法:創建一個屬於你自己的 Content provider 或者將你的數據添加到一個已經存在的 Content provider 中,前提是有相同數據類型並且有寫入 Content provider 的權限。 如何通過一套標准及統一的接口獲取其他應用程序暴露的數據?Android 提供了ContentResolver,外界的程序可以通過 ContentResolver 接口訪問ContentProvider 提供的數據。
32. android 中的動畫有哪幾類,它們的特點和區別是什麼?
答:兩種,一種是 Tween 動畫、還有一種是 Frame 動畫。
Tween 動畫,這種實現方式可以使視圖組件移動、放大、縮小以及產生透明度的變化;
Frame 動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。
33. ListView 的優化方案 1、如果自定義適配器,那麼在 getView 方法中要考慮方法傳進來的參數contentView 是否為 null,如果為 null 就創建 contentView 並返回,如果不為 null則直接使用。在這個方法中盡可能少創建 view。
2、給 contentView 設置 tag(setTag()),傳入一個 viewHolder 對象,用於緩存要顯示的數據,可以達到圖像數據異步加載的效果。
3、如果listview 需要顯示的item 很多,就要考慮分頁加載。比如一共要顯示 100條或者更多的時候,我們可以考慮先加載 20 條,等用戶拉到列表底部的時候再去加載接下來的 20 條。
34. 請介紹下 Android 的數據存儲方式
Android 提供了 5 種方式存儲數據:
(1)使用 SharedPreferences 存儲數據;它是 Android 提供的用來存儲一些簡單配置信息的一種機制,采用了 XML 格式將數據存儲到設備中。只能在同一個包內使用,不能在不同的包之間使用。
(2)文件存儲數據;文件存儲方式是一種較常用的方法,在 Android 中讀取/寫入文件的方法,與 Java 中實現 I/O 的程序是完全一樣的,提供了 openFileInput()和openFileOutput()方法來讀取設備上的文件。
(3)SQLite 數據庫存儲數據;SQLite 是 Android 所帶的一個標准的數據庫,它支持SQL 語句,它是一個輕量級的嵌入式數據庫。
(4)ContentProvider 存儲數據;主要用於應用程序之間進行數據交換,從而能夠讓其他的應用保存或讀取此 Content Provider 的各種數據類型。
(5)網絡存儲數據;通過網絡上提供給我們的存儲空間來上傳(存儲)和下載(獲取)我們存儲在網絡空間中的數據信息。
35. android 中有哪幾種解析 xml 的類,官方推薦哪種?以及它們的原理和區別?
方式一:DOM 解析
優點:
XML 樹在內存中完整存儲,因此可以直接修改其數據和結構。 2.可以通過該解析器隨
時訪問 XML 樹中的任何一個節點。 3.DOM 解析器的 API 在使用上也相對比較簡單。
缺點:
如果 XML 文檔體積比較大時,將文檔讀入內存是非常消耗系統資源的。
使用場景:
DOM 是用與平台和語言無關的方式表示 XML 文檔的官方 W3C 標准。DOM 是以層次
結構組織的節點的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構
通常需要加載整個文檔和構造層次結構,然後才能進行任何工作。DOM 是基於對象層次
結構的。
方式二:SAX 解析
優點:
SAX 對內存的要求比較低,因為它讓開發人員自己來決定所要處理的標簽。特別是當
開發人員只需要處理文檔中所包含的部分數據時,SAX 這種擴展能力得到了更好的體現。
缺點:
用 SAX 方式進行 XML 解析時,需要順序執行,所以很難訪問到同一文檔中的不同數據。
此外,在基於該方式的解析編碼過程也相對復雜。
使用場景:
對於含有數據量十分巨大,而又不用對文檔的所有數據進行遍歷或者分析的時候,使用該方法十分有效。該方法不用將整個文檔讀入內存,而只需讀取到程序所需的文檔標簽處即可。
方式三:Xmlpull 解析
android SDK 提供了 xmlpull api,xmlpull 和 sax 類似,是基於流(stream)操作文件,然後根據節點事件回調開發者編寫的處理程序。因為是基於流的處理,因此xmlpull 和 sax 都比較節約內存資源,不會象 dom 那樣要把所有節點以對橡樹的形式展現在內存中。
xmlpull 比 sax 更簡明,而且不需要掃描完整個流。
36. 請解釋下在單線程模型中 Message、Handler、Message Queue、Looper 之間的關系
簡單的說,Handler 獲取當前線程中的 looper 對象,looper 用來從存放 Message的 MessageQueue 中取出 Message,再有 Handler 進行 Message 的分發和處理。 Message Queue(消息隊列):用來存放通過 Handler 發布的消息,通常附屬於某一個創建它的線程,可以通過 Looper.myQueue()得到當前線程的消息隊列
Handler:可以發布或者處理一個消息或者操作一個 Runnable,通過 Handler 發布消息,消息將只會發送到與它關聯的消息隊列,然也只能處理該消息隊列中的消息。
Looper:是 Handler 和消息隊列之間通訊橋梁,程序組件首先通過 Handler 把消息傳遞給 Looper,Looper 把消息放入隊列。Looper 也把消息隊列裡的消息廣播給所有的Handler。
Handler:Handler 接受到消息後調用 handleMessage 進行處理
Message:消息的類型,在 Handler 類中的 handleMessage 方法中得到單個的消息進行處理 在單線程模型下,為了線程通信問題,Android 設計了一個 Message Queue(消息隊列), 線程間可以通過該 Message Queue 並結合 Handler 和 Looper 組件進行信息交換。下面將對它們進行分別介紹:
1. Message
Message 消息,理解為線程間交流的信息,處理數據後台線程需要更新 UI,則發送Message 內含一些數據給 UI 線程。
2. Handler
Handler 處理者,是 Message 的主要處理者,負責 Message 的發送,Message 內容的執行處理。後台線程就是通過傳進來的 Handler 對象引用來sendMessage(Message)。而使用 Handler,需要 implement 該類的 handleMessage(Message)方法,它是處理這些Message的操作內容,例如Update UI。通常需要子類化 Handler 來實現 handleMessage 方法。
3. Message Queue
Message Queue 消息隊列,用來存放通過 Handler 發布的消息,按照先進先出執行。 每個 message queue 都會有一個對應的 Handler。Handler 會向 message queue 通過兩種方法發送消息:sendMessage 或 post。這兩種消息都會插在 message queue隊尾並按先進先出執行。但通過這兩種方法發送的消息執行的方式略有不同:通過sendMessage 發送的是一個 message 對象,會被 Handler 的 handleMessage()函數處理;而通過 post 方法發送的是一個 runnable 對象,則會自己執行。
4. Looper
Looper 是每條線程裡的 Message Queue 的管家。Android 沒有 Global 的Message Queue,而 Android 會自動替主線程(UI 線程)建立 Message Queue,但在子線程裡並沒有建立 Message Queue。所以調用 Looper.getMainLooper()得到的主線程的 Looper 不為 NULL,但調用 Looper.myLooper() 得到當前線程的 Looper 就有可能為 NULL。對於子線程使用 Looper,API Doc 提供了正確的使用方法:這個 Message機制的大概流程:
1. 在 Looper.loop()方法運行開始後,循環地按照接收順序取出 Message Queue裡面的非 NULL 的 Message。
2. 一開始 Message Queue 裡面的 Message 都是 NULL 的。當Handler.sendMessage(Message)到 Message Queue,該函數裡面設置了那個Message對象的target屬性是當前的Handler對象。隨後Looper取出了那個Message,則調用 該 Message 的 target 指向的 Hander 的 dispatchMessage 函數對 Message進行處理。在 dispatchMessage 方法裡,如何處理 Message 則由用戶指定,三個判斷,優先級從高到低:
1) Message 裡面的 Callback,一個實現了 Runnable 接口的對象,其中 run 函數做處理工作;
2) Handler 裡面的 mCallback 指向的一個實現了 Callback 接口的對象,由其handleMessage 進行處理;
3) 處理消息 Handler 對象對應的類繼承並實現了其中 handleMessage 函數,通過這個實現的 handleMessage 函數處理消息。
3. Handler 處理完該 Message (update UI) 後,Looper 則設置該 Message為 NULL,以便回收!在網上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執行處理信息之類的,個人理解是最簡單的方法——判斷 Handler 對象裡面的 Looper 對象是屬於哪條線程的,則由該線程來執行!
1. 當 Handler 對象的構造函數的參數為空,則為當前所在線程的 Looper;
2. Looper.getMainLooper()得到的是主線程的 Looper 對象,Looper.myLooper()得到的是當前線程的 Looper 對象。
37. 說說你對 AsyncTask 的理解
在開發 Android 移動客戶端的時候往往要使用多線程來進行操作,我們通常會將耗時的操作放在單獨的線程執行,避免其占用主線程而給用戶帶來不好的用戶體驗。但是在子線程中無法去操作主線程(UI 線程),在子線程中操作 UI 線程會出現錯誤。因此 android提供了一個類 Handler 來在子線程中來更新 UI 線程,用發消息的機制更新 UI 界面,呈現給用戶。這樣就解決了子線程更新 UI 的問題。但是費時的任務操作總會啟動一些匿名的子線程,太多的子線程給系統帶來巨大的負擔,隨之帶來一些性能問題。因此 android 提供了一個工具類 AsyncTask,顧名思義異步執行任務。這個 AsyncTask 生來就是處理一些後台的比較耗時 的任務,給用戶帶來良好用戶體驗的,從編程的語法上顯得優雅了許多,不再需要子線程和Handler 就可以完成異步操作並且刷新用戶界面。
38. 什麼情況會導致 Force Close ?如何避免?能否捕獲導致其的異常?
答:程序出現異常,比如 nullpointer。
避免:編寫程序時邏輯連貫,思維缜密。能捕獲異常,在 logcat 中能看到異常信息
39. DDMS 和 TraceView 的區別?
DDMS 是一個程序執行查看器,在裡面可以看見線程和堆棧等信息 TraceView 是程序性能分析器 。
40. Android 中內存洩露出現情況有哪些?
1. 數據庫的 cursor 沒有關閉, 可以使用 startManagerCursor(cursor)
2. 構造 adapter 時,沒有使用緩存 contentview,衍生 listview 的優化問題-----減少創建 view 的對象,充分使用 contentview,可以使用一靜態類來優化處理getview 的過程
3. Bitmap 對象不使用時沒有釋放,可以通過調用 bitmap.recycle()釋放內存
41. sim 卡的 EF 文件是什麼?有何作用?
答:sim 卡的文件系統有自己規范,主要是為了和手機通訊,sim 本 身可以有自己的操作
系統,EF 就是作存儲並和手機通訊用的
42. 什麼是嵌入式實時操作系統, Android 操作系統屬於實時操作系統嗎?
嵌入式實時操作系統是指當外界事件或數據產生時,能夠接受並以足夠快的速度予以處理,
其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制
所有實時任務協調一致運行的嵌入式操作系統。主要用於工業控制、 軍事設備、 航空航
天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬
實時兩種,而 android 是基於 linux 內核的,因此屬於軟實時。
43. 談談 Android 的 IPC(進程間通信)機制
IPC 是內部進程通信的簡稱, 是共享"命名管道"的資源。Android 中的 IPC 機制是為了
讓 Activity 和 Service 之間可以隨時的進行交互,故在 Android 中該機制,只適用於
Activity 和 Service 之間的通信,類似於遠程方法調用,類似於 C/S 模式的訪問。通
過定義 AIDL 接口文件來定義 IPC 接口。Servier 端實現 IPC 接口,Client 端調用 IPC
接口本地代理。 44. NDK 是什麼?
NDK 是一些列工具的集合,NDK 提供了一系列的工具,幫助開發者迅速的開發 C/C++的動
態庫,並能自動將 so 和 java 應用打成 apk 包。
NDK 集成了交叉編譯器,並提供了相應的 mk 文件和隔離 cpu、平台等的差異,開發人員只需簡單的修改 mk 文件就可以創建出 so
45. Android 平台手機 5 大優勢:
一、開放性
在優勢方面,Android 平台首先就是其開發性,開發的平台允許任何移動終端廠商加
入到 Android 聯盟中來。顯著的開放性可以使其擁有更多的開發者,隨著用戶和應用的日
益豐富,一個嶄新的平台也將很快走向成熟開發性對於 Android 的發展而言,有利於積累人氣,這裡的人氣包括消費者和廠商,而對於消費者來講,隨大的受益正是豐富的軟件資源。開放的平台也會帶來更大競爭,如此一來,消費者將可以用更低的價位購得心儀的手機。
二、掙脫運營商的束縛
在過去很長的一段時間,特別是在歐美地區,手機應用往往受到運營商制約,使用什麼功能接入什麼網絡,幾乎都受到運營商的控制。從去年 iPhone 上市 ,用戶可以更加方便地連接網絡,運營商的制約減少。隨著 EDGE、HSDPA 這些 2G 至 3G 移動網絡的逐步過渡和提升,手機隨意接入網絡已不是運營商口中的笑談,當你可以通過手機 IM 軟件方便地進行即時聊天時,再回想不久前天價的彩信和圖鈴下載業務,是不是像噩夢一樣? 互聯網巨頭 Google 推動的 Android 終端天生就有網絡特色,將讓用戶離互聯網更近。
三、豐富的硬件選擇
這一點還是與 Android 平台的開放性相關,由於 Android 的開放性,眾多的廠商會推出千奇百怪,功能特色各具的多種產品。功能上的差異和特色,卻不會影響到數據同步、甚至軟件的兼容,好比你從諾基亞 Symbian 風格手機 一下改用蘋果 iPhone ,同時還可將 Symbian 中優秀的軟件帶到 iPhone 上使用、聯系人等資料更是可以方便地轉移,是不是非常方便呢?
四、不受任何限制的開發商
Android 平台提供給第三方開發商一個十分寬泛、自由的環境,不會受到各種條條框框的阻擾,可想而知,會有多少新穎別致的軟件會誕生。但也有其兩面性,血腥、暴力、情色方面的程序和游戲如可控制正是留給 Android 難題之一。
五、無縫結合的 Google 應用
如今叱詫互聯網的 Google 已經走過 10 年度歷史,從搜索巨人到全面的互聯網滲透,Google 服務如地圖、郵件、搜索等已經成為連接用戶和互聯網的重要紐帶,而 Android平台手機將無縫結合這些優秀的 Google 服務。
46. 在 android 中,請簡述 jni 的調用過程
1)安裝和下載 Cygwin,下載 AndroidNDK
2)在 ndk 項目中 JNI 接口的設計
3)使用 C/C++實現本地方法
4)JNI 生成動態鏈接庫.so 文件
5)將動態鏈接庫復制到 java 工程,在 java 工程中調用,運行 java 工程即可
47. Android的四大組件是哪些,它們的作用?
答:Activity:Activity是Android程序與用戶交互的窗口,是Android構造塊中最基本的一種,它需要為保持各界面的狀態,做很多持久化的事情,妥善管理生命周期以及一些跳轉邏輯:
service:後台服務於Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的食物,定義好需要接受的Intent提供同步和異步的接口。
Content Provider:是Android提供的第三方應用數據的訪問方案,可以派生Content Provider類,對外提供數據,可以像數據庫一樣進行選擇排序,屏蔽內部數據的存儲細節,向外提供統一的借口模型,大大簡化上層應用,對數據的整合提供了更方便的途徑。
BroadCast Receiver:接受一種或者多種Intent作觸發事件,接受相關消息,做一些簡單處理,轉換成一條Notification,統一了Android的事件廣播模型
48. 請介紹下Android中常用的五種布局。
常用五種布局方式,分別是:FrameLayout(框架布局),LinearLayout (線性布局),AbsoluteLayout(絕對布局),RelativeLayout(相對布局),TableLayout(表格布局)。
一、FrameLayout:所有東西依次都放在左上角,會重疊,這個布局比較簡單,也只能放一點比較簡單的東西。
二、LinearLayout:線性布局,每一個LinearLayout裡面又可分為垂直布局(android:orientation="vertical")和水平布局(android:orientation="horizontal" )。當垂直布局時,每一行就只有一個元素,多個元素依次垂直往下;水平布局時,只有一行,每一個元素依次向右排列。
三、AbsoluteLayout:絕對布局用X,Y坐標來指定元素的位置,這種布局方式也比較簡單,但是在屏幕旋轉時,往往會出問題,而且多個元素的時候,計算比較麻煩。
四、RelativeLayout:相對布局可以理解為某一個元素為參照物,來定位的布局方式。主要屬性有:相對於某一個元素android:layout_below、android:layout_toLeftOf相對於父元素的地方android:layout_alignParentLeft、android:layout_alignParentRigh。
五、TableLayout:表格布局,每一個TableLayout裡面有表格行TableRow,TableRow裡面可以具體定義每一個元素。每一個布局都有自己適合的方式,這五個布局元素可以相互嵌套應用,做出美觀的界面。
49. android中的動畫有哪幾類,它們的特點和區別是什麼
答:兩種,
一、Tween動畫(補間動畫)
二、Frame動畫(逐幀動畫)
Tween動畫,這種實現方式可以使視圖組件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。
50. android 中有哪幾種解析xml的類?官方推薦哪種?以及它們的原理和區別。
答:XML解析主要有三種方式,SAX、DOM、PULL。常規在PC上開發我們使用Dom相對輕松些,但一些性能敏感的數據庫或手機上還是主要采用SAX方式,SAX讀取是單向的,優點:
不占內存空間、解析屬性方便,但缺點就是對於套嵌多個分支來說處理不是很方便。而DOM方式會把整個XML文件加載到內存中去,這裡Android開發網提醒大家該方法在查找方面可以和XPath很好的結合如果數據量不是很大推薦使用,而PULL常常用在J2ME對於節點處理比較好,類似SAX方式,同樣很節省內存,在J2ME中我們經常使用的KXML庫來解析。
51. ListView的優化方案
答:1、如果自定義適配器,那麼在getView方法中要考慮方法傳進來的參數contentView是否為null,如果為null就創建contentView並返回,如果不為null則直接使用。在這個方法中盡可能少創建view。
2、給contentView設置tag(setTag()),傳入一個viewHolder對象,用於緩存要顯示的數據,可以達到圖像數據異步加載的效果。
3、如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去加載接下來的20條。
52. 請介紹下Android的數據存儲方式。
答:SharedPreferences存儲數據;文件存儲數據;SQLite數據庫存儲數據;使用ContentProvider存儲數據;
網絡存儲數據;Preference,File, DataBase這三種方式分別對應的目錄是/data/data/Package
Name/Shared_Pref,/data/data/Package
Name/files, /data/data/Package Name/database 。
一:使用SharedPreferences存儲數據
首先說明SharedPreferences存儲方式,它是 Android提供的用來存儲一些簡單配置信息的一種機制,例如:登錄用戶的用戶名與密碼。其采用了Map數據結構來存儲數據,以鍵值的方式存儲,可以簡單的讀取與寫入,具體實例如下:
void ReadSharedPreferences(){
String strName,strPassword;
SharedPreferences user = getSharedPreferences(“user_info”,0);
strName = user.getString(“NAME”,””);
strPassword = user getString(“PASSWORD”,””);
} void WriteSharedPreferences(String strName,String strPassword){
SharedPreferences user = getSharedPreferences(“user_info”,0);
uer.edit();
user.putString(“NAME”, strName);
user.putString(“PASSWORD” ,strPassword);
user.commit();} 數據讀取與寫入的方法都非常簡單,只是在寫入的時候有些區別:先調用edit()使其處於編輯狀態,然後才能修改數據,最後使用commit()提交修改的數據。實際上SharedPreferences是采用了XML格式將數據存儲到設備中,在DDMS中的File Explorer中的/data/data/
二:文件存儲數據
文件存儲方式是一種較常用的方法,在Android中讀取/寫入文件的方法,與 Java中實現I/O的程序是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取設備上的文件。具體實例如下:
String fn = “moandroid.log”;
FileInputStream fis = openFileInput(fn);
FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);
三:網絡存儲數據
網絡存儲方式,需要與Android 網絡數據包打交道,關於Android 網絡數據包的詳細說明,請閱讀Android SDK引用了Java SDK的哪些package?。
四:ContentProvider
1、ContentProvider簡介
當應用繼承ContentProvider類,並重寫該類用於提供數據和存儲數據的方法,就可以向其他應用共享其數據。雖然使用其他方法也可以對外共享數據,但數據訪問方式會因數據存儲的方式而不同,如:采用文件方式對外共享數據,需要進行文件操作讀寫數據;采用sharedpreferences共享數據,需要使用sharedpreferences API讀寫數據。而使用ContentProvider共享數據的好處是統一了數據訪問方式。
2、Uri類簡介
Uri代表了要操作的數據,Uri主要包含了兩部分信息:
1.需要操作的ContentProvider ,
2.對ContentProvider中的什麼
數據進行操作,一個Uri由以下幾部分組成:
1.scheme:ContentProvider(內容提供者)的scheme已經由Android所規定為:content://…
2.主機名(或Authority):用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。
3.路徑(path):可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:
要操作contact表中id為10的記錄,可以構建這樣的路徑:/contact/10
要操作contact表中id為10的記錄的name字段, contact/10/name
要操作contact表中的所有記錄,可以構建這樣的路徑:/contact?
要操作的數據不一定來自數據庫,也可以是文件等他存儲方式,如下:
要操作xml文件中contact節點下的name節點,可以構建這樣的路徑:/contact/name
如果要把一個字符串轉換成Uri,可以使用Uri類中的parse()方法,如下:
Uri uri=Uri.parse("content://com.changcheng.provider.contactprovider/contact")
3、UriMatcher、ContentUrist和ContentResolver簡介
因為Uri代表了要操作的數據,所以我們很經常需要解析Uri,並從 Uri中獲取數據。Android系統提供了兩個用於操作Uri的工具類,分別為UriMatcher 和ContentUris 。掌握它們的使用,會便於我們的開發工作。
UriMatcher:用於匹配Uri,它的用法如下:
1.首先把你需要匹配Uri路徑全部給注冊上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼(-1)。
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider /contact路徑,返回匹配碼為1
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,
如果匹配就會返回匹配碼
//如果match()方法匹配 content://com.changcheng.sqlite.provider.contactprovider/contact/230路徑,返回匹配
碼為2
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#號為通配符
2.注冊完需要匹配的Uri後,就可以使用uriMatcher.match(uri)方法對輸入的Uri進行匹配,如果匹配就返回匹配碼,匹配碼是調用 addURI()方法傳入的第三個參數,假設匹配
content://com.changcheng.sqlite.provider.contactprovider/contact路徑,返回的匹配碼為1。
ContentUris:用於獲取Uri路徑後面的ID部分,它有兩個比較實用的方法:
withAppendedId(uri, id)用於為路徑加上ID部分
parseId(uri)方法用於從路徑中獲取ID部分
ContentResolver:當外部應用需要對ContentProvider中的數據進行添加、刪除、修改和查詢操作時,可以使用ContentResolver 類來完成,要獲取ContentResolver 對象,可以使用Activity提供的getContentResolver()方法。
ContentResolver使用insert、delete、update、query方法,來操作數據。
53. activity的啟動模式有哪些?是什麼含義?
答:在android裡,有4種activity的啟動模式,分別為:
“standard” (默認)
“singleTop”
“singleTask”
“singleInstance”
它們主要有如下不同:
1. 如何決定所屬task
“standard”和”singleTop”的activity的目標task,和收到的Intent的發送者在同一個task內,除非intent包括參數FLAG_ACTIVITY_NEW_TASK。如果提供了FLAG_ACTIVITY_NEW_TASK參數,會啟動到別的task裡。“singleTask”和”singleInstance”總是把activity作為一個task的根元素,他們不會被啟動到一個其他task裡。
2. 是否允許多個實例
“standard”和”singleTop”可以被實例化多次,並且存在於不同的task中,且一個task可以包括一個activity的多個
實例;
“singleTask”和”singleInstance”則限制只生成一個實例,並且是task的根元素。 singleTop要求如果創建intent的時候棧頂已經有要創建 的Activity的實例,則將intent發送給該實例,而不發送給新的實例。
3. 是否允許其它activity存在於本task內
“singleInstance”獨占一個task,其它activity不能存在那個task裡;如果它啟動了一個新的activity,不管新的activity的launch mode 如何,新的activity都將會到別的task裡運行(如同加了FLAG_ACTIVITY_NEW_TASK參數)。而另外三種模式,則可以和其它activity共存。
4. 是否每次都生成新實例
“standard”對於沒一個啟動Intent都會生成一個activity的新實例;“singleTop”的activity如果在task的棧頂的話,則不生成新的該activity的實例,直接使用棧頂的實例,否則,生成該activity的實例。比如現在task棧元素為A-B-C-D(D在棧頂),這時候給D發一個啟動intent,如果D是 “standard”的,則生成D的一個新實例,棧變為A-B-C-D-D。如果D是singleTop的話,則不會生產D的新實例,棧狀態仍為A-B-C-D
如果這時候給B發Intent的話,不管B的launchmode是”standard” 還是 “singleTop” ,都會生成B的新實例,棧狀態變為A-B-C-D-B。“singleInstance”是其所在棧的唯一activity,它會每次都被重用。“singleTask”如果在棧頂,則接受intent,否則,該intent會被丟棄,但是該task仍會回到前台。當已經存在的activity實例處理新的intent時候,會調用onNewIntent()方法 如果收到intent生成一個activity實例,那麼用戶可以通過back鍵回到上一個狀態;如果是已經存在的一個activity來處理這個intent的話,用戶不能通過按back鍵返回到這之前的狀態。
54. 跟activity和Task 有關的 Intent啟動方式有哪些?其含義?
核心的Intent Flag有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_NEW_TASK
如果設置,這個Activity會成為歷史stack中一個新Task的開始。一個Task(從啟動它的Activity到下一個Task中的Activity)定義了用戶可以遷移的Activity原子組。Task可以移動到前台和後台;在某個特定Task中的所有Activity總是保持相同的次序。
這個標志一般用於呈現“啟動”類型的行為:它們提供用戶一系列可以單獨完成的事情,與啟動它們的Activity完全無關。
使用這個標志,如果正在啟動的Activity的Task已經在運行的話,那麼,新的Activity將不會啟動;代替的,當前Task會簡單的移入前台。
參考FLAG_ACTIVITY_MULTIPLE_TASK標志,可以禁用這一行為。這個標志不能用於調用方對已經啟動的Activity請求結果。
FLAG_ACTIVITY_CLEAR_TOP如果設置,並且這個Activity已經在當前的Task中運行,因此,不再是重新啟動一個這個Activity的實例,而是在這個Activity上方的所有Activity都將關閉,然後這個Intent會作為一個新的Intent投遞到老的Activity(現在位於頂端)中。例如,假設一個Task中包含這些Activity:A,B,C,D。如果D調用了startActivity(),並且包含一個指向ActivityB的Intent,那麼,C和D都將結束,然後B接收到這個Intent,因此,目前stack的狀況是:A,B。上例中正在運行的Activity B既可以在onNewIntent()中接收到這個新的Intent,也可以把自己關閉然後重新啟動來接收這個Intent。如果它的啟動模式聲明為 “multiple”(默認值),並且你沒有在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標志,那麼它將關閉然後重新創建;對於其它的啟動模式,或者在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標志,都將把這個Intent投遞到當前這個實例的onNewIntent()中。這個啟動模式還可以與FLAG_ACTIVITY_NEW_TASK結合起來使用:用於啟動一個Task中的根Activity,它會把那個Task中任何運行的實例帶入前台,然後清除它直到根Activity。這非常有用,例如,當從Notification Manager處啟動一個Activity。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
如果設置這個標志,這個activity不管是從一個新的棧啟動還是從已有棧推到棧頂,它都將以the front door of the task的方式啟動。這就講導致任何與應用相關的棧都講重置到正常狀態(不管是正在講activity移入還是移除),如果需要,或者直接重置該棧為初始狀態。FLAG_ACTIVITY_SINGLE_TOP如果設置,當這個Activity位於歷史stack的頂端運行時,不再啟動一個新的
FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個標志一般不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統幫你設定。FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
如果設置,這將在Task的Activity stack中設置一個還原點,當Task恢復時,需要清理Activity。也就是說,下一次Task帶著 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
標記進入前台時(典型的操作是用戶在主畫面重啟它),這個Activity和它之上的都將關閉,以至於用戶不能再返回到它們,但是可以回到之前的Activity。這在你的程序有分割點的時候很有用。例如,一個e-mail應用程序可能有一個操作是查看一個附件,需要啟動圖片浏覽Activity來顯示。這個 Activity應該作為e-mail應用程序Task的一部分,因為這是用戶在這個Task中觸發的操作。然而,當用戶離開這個Task,然後從主畫面選擇e-mail app,我們可能希望回到查看的會話中,但不是查看圖片附件,因為這讓人困惑。通過在啟動圖片浏覽時設定這個標志,浏覽及其它啟動的Activity在下次用戶返回到mail程序時都將全部清除。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果設置,新的Activity不會在最近啟動的Activity的列表中保存。FLAG_ACTIVITY_FORWARD_RESULT如果設置,並且這個Intent用於從一個存在的Activity啟動一個新的Activity,那麼,這個作為答復目標的Activity將會傳到這個新的Activity中。這種方式下,新的Activity可以調用setResult(int),並且這個結果值將發送給那個作為答復目標的 Activity。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
這個標志一般不由應用程序代碼設置,如果這個Activity是從歷史記錄裡啟動的(常按HOME鍵),那麼,系統會幫你設定。
FLAG_ACTIVITY_MULTIPLE_TASK
不要使用這個標志,除非你自己實現了應用程序啟動器。與FLAG_ACTIVITY_NEW_TASK結合起來使用,可以禁用把已存的Task送入前台的行為。當設置時,新的Task總是會啟動來處理Intent,而不管這是是否已經有一個Task可以處理相同的事情。由於默認的系統不包含圖形Task管理功能,因此,你不應該使用這個標志,除非你提供給用戶一種方式可以返回到已經啟動的Task。
如果FLAG_ACTIVITY_NEW_TASK標志沒有設置,這個標志被忽略。
FLAG_ACTIVITY_NO_ANIMATION如果在Intent中設置,並傳遞給Context.startActivity()的話,這個標志將阻止系統進入下一個Activity時應用Acitivity遷移動畫。這並不意味著動畫將永不運行——如果另一個Activity在啟動顯示之前,沒有指定這個標志,那麼,動畫將被應用。這個標志可以很好的用於執行一連串的操作,而動畫被看作是更高一級的事件的驅動。
FLAG_ACTIVITY_NO_HISTORY如果設置,新的Activity將不再歷史stack中保留。用戶一離開它,這個Activity就關閉了。這也可以通過設置noHistory特性。
FLAG_ACTIVITY_NO_USER_ACTION如果設置,作為新啟動的Activity進入前台時,這個標志將在Activity暫停之前阻止從最前方的Activity回調的onUserLeaveHint()。典型的,一個Activity可以依賴這個回調指明顯式的用戶動作引起的Activity移出後台。這個回調在Activity的生命周期中標記一個合適的點,並關閉一些Notification。如果一個Activity通過非用戶驅動的事件,如來電或鬧鐘,啟動的,這個標志也應該傳遞給Context.startActivity,保證暫停的Activity不認為用戶已經知曉其Notification。FLAG_ACTIVITY_PREVIOUS_IS_TOP
If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately.
FLAG_ACTIVITY_REORDER_TO_FRONT如果在Intent中設置,並傳遞給Context.startActivity(),這個標志將引發已經運行的Activity移動到歷史stack的頂端。
例如,假設一個Task由四個Activity組成:A,B,C,D。如果D調用startActivity()來啟動Activity B,那麼,B會移動到歷史stack的頂端,現在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標志也設置的話,那麼這個標志將被忽略。
55. 請描述下Activity的生命周期。
答:activity的生命周期方法有:onCreate()、onStart()、onReStart()、onResume()、onPause()、onStop()、onDestory();
可見生命周期:從onStart()直到系統調用onStop()
前台生命周期:從onResume()直到系統調用onPause()
56. activity在屏幕旋轉時的生命周期
答:不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次;設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次;設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生
命周期,只會執行onConfigurationChanged方法
57. 如何啟用Service,如何停用Service。
服務的開發比較簡單,如下:
第一步:繼承Service類
public class SMSService extends Service {}
第二步:在AndroidManifest.xml文件中的節點裡對服務進行配置:
服務不能自己運行,需要通過調用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()方法。
服務常用生命周期回調方法如下:
onCreate() 該方法在服務被創建時調用,該方法只會被調用一次,無論調用多少次startService()或bindService()方法,服務也只被創建一次。
onDestroy()該方法在服務被終止時調用。
與采用Context.startService()方法啟動服務有關的生命周期方法
onStart() 只有采用Context.startService()方法啟動服務時才會回調該方法。該方法在服務開始運行時被調用。多次調用startService()方法盡管不會多次創建服務,但onStart() 方法會被多次調用。
與采用Context.bindService()方法啟動服務有關的生命周期方法
onBind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。
onUnbind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務解除綁定時被調用
58. 注冊廣播有幾種方式,這些方式有何優缺點?請談談Android引入廣播機制的用意。
答:首先寫一個類要繼承BroadcastReceiver
第一種:在清單文件中聲明,添加
第二種使用代碼進行注冊如:
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(receiver.filter);
兩種注冊類型的區別是:
1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。
2)第二種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
59. 請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關系。
答:簡單的說,Handler獲取當前線程中的looper對象,looper用來從存放Message的MessageQueue中取出Message,再有Handler進行Message的分發和處理.
Message Queue(消息隊列):用來存放通過Handler發布的消息,通常附屬於某一個創建它的線程,可以通過Looper.myQueue()得到當前線程的消息隊列
Handler:可以發布或者處理一個消息或者操作一個Runnable,通過Handler發布消息,消息將只會發送到與它關聯的消息隊列,然也只能處理該消息隊列中的消息
Looper:是Handler和消息隊列之間通訊橋梁,程序組件首先通過Handler把消息傳遞給Looper,Looper把消息放入隊列。Looper也把消息隊列裡的消息廣播給所有的
Handler:Handler接受到消息後調用handleMessage進行處理
Message:消息的類型,在Handler類中的handleMessage方法中得到單個的消息進行處理。在單線程模型下,為了線程通信問題,Android設計了一個Message Queue(消息隊列), 線程間可以通過該Message
Queue並結合Handler和Looper組件進行信息交換。下面將對它們進行分別介紹:
1. Message
Message消息,理解為線程間交流的信息,處理數據後台線程需要更新UI,則發送Message內含一些數據給UI線程。
2. Handler
Handler處理者,是Message的主要處理者,負責Message的發送,Message內容的執行處理。後台線程就是通過傳進來的 Handler對象引用來sendMessage(Message)。而使用Handler,需要implement 該類的 handleMessage(Message)方法,它是處理這些Message的操作內容,例如Update UI。通常需要子類化Handler來實現handleMessage方法。
3. Message Queue
Message Queue消息隊列,用來存放通過Handler發布的消息,按照先進先出執行。每個message queue都會有一個對應的Handler。Handler會向message queue通過兩種方法發送消息:sendMessage或
post。這兩種消息都會插在message queue隊尾並按先進先出執行。但通過這兩種方法發送的消息執行的方式略有不同:
通過sendMessage發送的是一個message對象,會被 Handler的handleMessage()函數處理;而通過post方法發送的是一個runnable對象,則會自己執行。
4. Looper
Looper是每條線程裡的Message Queue的管家。Android沒有Global的Message Queue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程裡並沒有建立Message Queue。所以調用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調用Looper.myLooper() 得到當前線程的Looper就有可能為NULL。對於子線程使用Looper,API Doc提供了正確的使用方法:這個Message機制的大概流程:
1. 在Looper.loop()方法運行開始後,循環地按照接收順序取出Message Queue裡面的非NULL的Message。
2. 一開始Message Queue裡面的Message都是NULL的。當Handler.sendMessage(Message)到Message Queue,該函數裡面設置了那個Message對象的target屬性是當前的Handler對象。隨後Looper取出了那個Message,則調用 該Message的target指向的Hander的dispatchMessage函數對Message進行處理。在dispatchMessage方法裡,如何處理Message則由用戶指定,三個判斷,優先級從高到低:
1) Message裡面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;
2) Handler裡面的mCallback指向的一個實現了Callback接口的對象,由其handleMessage進行處理;
3) 處理消息Handler對象對應的類繼承並實現了其中handleMessage函數,通過這個實現的handleMessage函數處理消息。
由此可見,我們實現的handleMessage方法是優先級最低的!
3. Handler處理完該Message (update UI) 後,Looper則設置該Message為NULL,以便回收!
在網上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執行處理信息之類的,個人理解是最簡單的方法——判斷Handler對象裡面的Looper對象是屬於哪條線程的,則由該線程來執行!
1. 當Handler對象的構造函數的參數為空,則為當前所在線程的Looper;
2. Looper.getMainLooper()得到的是主線程的Looper對象,Looper.myLooper()得到的是當前線程的Looper對象。
60. 簡要解釋一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver
答:一個activity呈現了一個用戶可以操作的可視化用戶界面;一個service不包含可見的用戶界面,而是在後台運行,可以與一個activity綁定,通過綁定暴露出來接口並與其進行通信;一個broadcast receiver是一個接收廣播消息並做出回應的component,broadcast receiver沒有界面;一個intent是一個Intent對象,它保存了消息的內容。對於activity和service來說,它指定了請求的操作名稱和待操作數據的URI,Intent對象可以顯式的指定一個目標component。如果這樣的話,android會找到這個component(基於manifest文件中的聲明)並激活它。但如果一個目標不是顯式指定的,android必須找到響應intent的最佳component。它是通過將Intent對象和目標的intent filter相比較來完成這一工作的;一個component的intent filter告訴android該component能處理的intent。intent filter也是在manifest文件中聲明的。
63. 說說mvc模式的原理,它在android中的運用,android的官方建議應用程序的開發采用mvc模式。何謂mvc?
mvc是model,view,controller的縮寫,mvc包含三個部分:
模型(model)對象:是應用程序的主體部分,所有的業務邏輯都應該寫在該層。
視圖(view)對象:是應用程序中負責生成用戶界面的部分。也是在整個mvc架構中用戶唯一可以看到的一層,接收用戶的輸入,顯示處理結果。
控制器(control)對象:是根據用戶的輸入,控制用戶界面數據顯示及更新model對象狀態的部分,控制器更重要的一種導航功能,響應用戶出發的相關事件,交給m層處理。
android鼓勵弱耦合和組件的重用,在android中mvc的具體體現如下:
1)視圖層(view):一般采用xml文件進行界面的描述,使用的時候可以非常方便的引入,當然,如果你對android了解的比較的多了話,就一定可以想到在android中也可以使用javascript+html等的方式作為view層,當然這裡需要進行java和javascript之間的通信,幸運的是,android提供了它們之間非常方便的通信實現。
2)控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫代碼,要通過activity交割model業務邏輯層處理,這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這裡,程序就很容易被回收掉。
3)模型層(model):對數據庫的操作、對網絡等的操作都應該在model裡面處理,當然對業務計算等操作也是必須放在的該層的。
62. 什麼是ANR 如何避免它?
答:ANR:Application Not Responding。在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應,當用戶操作的在5s內應用程序沒能做出反應,BroadcastReceiver在10秒內沒有執行完畢,就會出現應用程序無響應對話框,這既是ANR。
避免方法:Activity應該在它的關鍵生命周期方法(如onCreate()和onResume())裡盡可能少的去做創建操作。潛在的耗時操作,例如網絡或數據庫操作,或者高耗時的計算如改變位圖尺寸,應該在子線程裡(或者異步方式)來完成。主線程應該為子線程提供一個Handler,以便完成時能夠提交給主線程。
63. 什麼情況會導致Force Close ?如何避免?能否捕獲導致其的異常?
答:程序出現異常,比如nullpointer。
避免:編寫程序時邏輯連貫,思維缜密。能捕獲異常,在logcat中能看到異常信息
64. 描述一下android的系統架構
android系統架構分從下往上為linux 內核層、運行庫、應用程序框架層、和應用程序層。
linuxkernel:負責硬件的驅動程序、網絡、電源、系統安全以及內存管理等功能。
libraries和 android runtime:libraries:即c/c++函數庫部分,大多數都是開放源代碼的函數庫,例如webkit(引擎),該函數庫負責 android網頁浏覽器的運行,例如標准的c函數庫libc、openssl、sqlite等,當然也包括支持游戲開發2dsgl和 3dopengles,在多媒體方面有mediaframework框架來支持各種影音和圖形文件的播放與顯示,
例如mpeg4、h.264、mp3、 aac、amr、jpg和png等眾多的多媒體文件格式。android的runtime負責解釋和執行生成的dalvik格式的字節碼。
applicationframework(應用軟件架構),java應用程序開發人員主要是使用該層封裝好的api進行快速開發。
applications:該層是java的應用程序層,android內置的googlemaps、e-mail、即時通信工具、浏覽器、mp3播放器等處於該層,java開發人員開發的程序也處於該層,而且和內置的應用程序具有平等的位置,可以調用內置的應用程序,也可以替換內置的應用程序。
上面的四個層次,下層為上層服務,上層需要下層的支持,調用下層的服務,這種嚴格分層的方式帶來的極大的穩定性、靈活性和可擴展性,使得不同層的開發人員可以按照規范專心特定層的開發。
android應用程序使用框架的api並在框架下運行,這就帶來了程序開發的高度一致性,另一方面也告訴我們,要想寫出優質高效的程序就必須對整個 applicationframework進行非常深入的理解。精通applicationframework,你就可以真正的理解android的設計和運行機制,也就更能夠駕馭整個應用層的開發。
65. 請介紹下ContentProvider是如何實現數據共享的。
一個程序可以通過實現一個Content provider的抽象接口將自己的數據完全暴露出去,而且Content providers是以類似數據庫中表的方式將數據暴露。Content providers存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。要想使應用程序的數據公開化,可通過2種方法:創建一個屬於你自己的Content provider或者將你的數據添加到一個已經存在的Content provider中,前提是有相同數據類型並且有寫入Content provider的權限。
如何通過一套標准及統一的接口獲取其他應用程序暴露的數據?
Android提供了ContentResolver,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數據。
66. Service和Thread的區別?
答:servie是系統的組件,它由系統進程托管(servicemanager);它們之間的通信類似於client和server,是一種輕量級的ipc通信,這種通信的載體是binder,它是在linux層交換信息的一種ipc。而thread是由本應用程序托管。
1). Thread:Thread是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。
2). Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那麼對應的 Service 是運行在主進程的main 線程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是RemoteService,那麼對應的 Service 則是運行在獨立進程的 main 線程上。既然這樣,那麼我們為什麼要用 Service 呢?其實這跟 android 的系統機制有關,我們先拿 Thread 來說。Thread 的運行是獨立於 Activity 的,也就是說當一個 Activity 被 finish 之後,如果你沒有主動停止 Thread 或者 Thread 裡的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裡會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。
舉個例子:如果你的 Thread 需要不停地隔一段時間就要連接服務器做某種同步的話,該 Thread 需要在 Activity 沒有start的時候也在運行。這個時候當你 start 一個 Activity 就沒有辦法在該 Activity 裡面控制之前創建的 Thread。因此你便需要創建並啟動一個 Service ,在 Service 裡面創建、運行並控制該 Thread,這樣便解決了該問題(因為任何 Activity 都可以控制同一 Service,而系統也只會創建一個對應 Service 的實例)。
因此你可以把 Service 想象成一種消息服務,而你可以在任何有 Context 的地方調用
Context.startService、Context.stopService、Context.bindService,Context.unbindService,來控制它,你也可以在 Service 裡注冊BroadcastReceiver,在其他地方通過發送 broadcast 來控制它,當然這些都是 Thread 做不到的。
67. Android本身的api並未聲明會拋出異常,則其在運行時有無可能拋出runtime異常,你遇到過嗎?諾有的話會導致什麼問題?如何解決?
答:會,比如nullpointerException。我遇到過,比如textview.setText()時,textview沒有初始化。會導致程序無法正常運行出現forceclose。打開控制台查看logcat信息找出異常信息並修改程序。
68. IntentService有何優點?
答:Acitivity的進程,當處理Intent的時候,會產生一個對應的Service; Android的進程處理器現在會盡可能的不kill掉你;非常容易使用。
69. 如果後台的Activity由於某原因被系統回收了,如何在被系統回收之前保存當前狀態?
答:重寫onSaveInstanceState()方法,在此方法中保存需要保存的數據,該方法將會在activity被回收之前調用。通過重寫onRestoreInstanceState()方法可以從中提取保存好的數據
70. 如何將一個Activity設置成窗口的樣式。
答:中配置:android :theme="@android:style/Theme.Dialog"另外android:theme="@android:style/Theme.Translucent" 是設置透明
71. 如何退出Activity?如何安全退出已調用多個Activity的Application?
答:對於單一Activity的應用來說,退出很簡單,直接finish()即可。當然,也可以用killProcess()和System.exit()這樣的方法。對於多個activity,1、記錄打開的Activity:每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。2、發送特定廣播:在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。3、遞歸退出:在打開新的Activity時使用startActivityForResult,然後自己加標志,在onActivityResult中處理,遞歸關閉。為了編程方便,最好定義一個Activity基類,處理這些共通問題。在2.1之前,可以使用ActivityManager的restartPackage方法。它可以直接結束整個應用。在使用時需要權限android.permission.RESTART_PACKAGES。注意不要被它的名字迷惑。可是,在2.2,這個方法失效了。在2.2添加了一個新的方法,killBackground Processes(),需要權限android.permission.KILL_BACKGROUND_PROCESSES。可惜的是,它和2.2的restartPackage一樣,根本起不到應有的效果。
另外還有一個方法,就是系統自帶的應用程序管理裡,強制結束程序的方法,forceStopPackage()。它需要權限android.permission.FORCE_STOP_PACKAGES。並且需要添加android:sharedUserId="android.uid.system"屬性。同樣可惜的是,該方法是非公開的,他只能運行在系統進程,第三方程序無法調用。因為需要在Android.mk中添加LOCAL_CERTIFICATE := platform。而Android.mk是用於在Android源碼下編譯程序用的。從以上可以看出,在2.2,沒有辦法直接結束一個應用,而只能用自己的辦法間接辦到。現提供幾個方法,供參考:
1、拋異常強制退出:
該方法通過拋異常,使程序Force Close。
驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。
2、記錄打開的Activity:
每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
3、發送特定廣播:
在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。
4、遞歸退出
在打開新的Activity時使用startActivityForResult,然後自己加標志,在onActivityResult中處理,遞歸關閉。除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。但是這樣做同樣不完美。你會發現,如果自己的應用程序對每一個Activity都設置了nosensor,在兩個Activity結束的間隙,sensor可能有效了。但至少,我們的目的達到了,而且沒有影響用戶使用。為了編程方便,最好定義一個Activity基類,處理這些共通問題。
72. AIDL的全稱是什麼?如何工作?能處理哪些類型的數據?
答:全稱是:Android Interface Define Language
在Android中, 每個應用程序都可以有自己的進程. 在寫UI應用的時候, 經常要用到Service. 在不同的進程中, 怎樣傳遞對象呢?顯然, Java中不允許跨進程內存共享. 因此傳遞對象, 只能把對象拆分成操作系統能理解的簡單形式, 以達到跨界對象訪問的目的. 在J2EE中,采用RMI的方式, 可以通過序列化傳遞對象. 在Android中, 則采用AIDL的方式. 理論上AIDL可以傳遞Bundle,實際上做起來卻比較麻煩。
AIDL(AndRoid接口描述語言)是一種借口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程的目的. 如果需要在一個Activity中, 訪問另一個Service中的某個對象, 需要先將對象轉化成AIDL可識別的參數(可能是多個參數), 然後使用AIDL來傳遞這些參數, 在消息的接收端, 使用這些參數組裝成自己需要的對
象.
AIDL的IPC的機制和COM或CORBA類似, 是基於接口的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關類.; 2. 調用aidl產生的class.AIDL的創建方法:AIDL語法很簡單,可以用來聲明一個帶一個或多個方法的接口,也可以傳遞參數和返回值。 由於遠程調用的需要, 這些參數和返回值並不是任何類型.下面是些AIDL支持的數據類型:
1. 不需要import聲明的簡單Java編程語言類型(int,boolean等)
2. String, CharSequence不需要特殊聲明
3. List, Map和Parcelables類型, 這些類型內所包含的數據成員也只能是簡單數據類型, String等其他比支持的類型.
(另外: 我沒嘗試Parcelables, 在Eclipse+ADT下編譯不過, 或許以後會有所支持)
73. 請解釋下Android程序運行時權限與文件系統權限的區別。
答:運行時權限Dalvik( android授權)文件系統 linux 內核授權
74. 系統上安裝了多種浏覽器,能否指定某浏覽器訪問指定頁面?請說明原由。
通過直接發送Uri把參數帶過去,或者通過manifest裡的intentfilter裡的data屬性
75. android系統的優勢和不足
Android平台手機 5大優勢:
一、開放性
在優勢方面,Android平台首先就是其開發性,開發的平台允許任何移動終端廠商加入到Android聯盟中來。顯著的開放性可以使其擁有更多的開發者,隨著用戶和應用的日益豐富,一個嶄新的平台也將很快走向成熟。開放性對於Android的發展而言,有利於積累人氣,這裡的人氣包括消費者和廠商,而對於消費者來講,隨大的受益正是豐富的軟件資源。開放的平台也會帶來更大競爭,如此一來,消費者將可以用更低的價位購得心儀的手機。
二、掙脫運營商的束縛
在過去很長的一段時間,特別是在歐美地區,手機應用往往受到運營商制約,使用什麼功能接入什麼網絡,幾乎都受到運營商的控制。從去年iPhone 上市 ,用戶可以更加方便地連接網絡,運營商的制約減少。隨著EDGE、HSDPA這些2G至3G移動網絡的逐步過渡和提升,手機隨意接入網絡已不是運營商口中的笑談,當你可以通過手機IM軟件方便地進行即時聊天時,再回想不久前天價的彩信和圖鈴下載業務,是不是像噩夢一樣?互聯網巨頭Google推動的Android終端天生就有網絡特色,將讓用戶離互聯網更近。
三、豐富的硬件選擇
這一點還是與Android平台的開放性相關,由於Android的開放性,眾多的廠商會推出千奇百怪,功能特色各具的多種產品。功能上的差異和特色,卻不會影響到數據同步、甚至軟件的兼容,好比你從諾基亞 Symbian風格手機 一下改用蘋果iPhone ,同時還可將Symbian中優秀的軟件帶到iPhone上使用、聯系人等資料更是可以方便地轉移,是不是非常方便呢?
四、不受任何限制的開發商
Android平台提供給第三方開發商一個十分寬泛、自由的環境,不會受到各種條條框框的阻擾,可想而知,會有多少新穎別致的軟件會誕生。但也有其兩面性,血腥、暴力、情色方面的程序和游戲如可控制正是留給Android難題之一。
五、無縫結合的Google應用
如今叱詫互聯網的Google已經走過10年度歷史,從搜索巨人到全面的互聯網滲透,Google服務如地圖、郵件、搜索等已經成為連接用戶和互聯網的重要紐帶,而Android平台手機將無縫結合這些優秀的Google服務。
Android的5大不足:
一、安全和隱私
由於手機 與互聯網的緊密聯系,個人隱私很難得到保守。除了上網過程中經意或不經意留下的個人足跡,Google這個巨人也時時站在你的身後,洞穿一切,因此,互聯網的深入將會帶來新一輪的隱私危機。
二、首先開賣Android手機的不是最大運營商
眾所周知,T-Mobile在23日,於美國紐約發布 了Android首款手機G1。但是在北美市場,最大的兩家運營商乃AT&T和Verizon,而目前所知取得Android手機銷售權的僅有 T-Mobile和Sprint,其中T-Mobile的3G網絡相對於其他三家也要遜色不少,因此,用戶可以買賬購買G1,能否體驗到最佳的3G網絡服務則要另當別論了!
三、運營商仍然能夠影響到Android手機
在國內市場,不少用戶對購得移動定制機不滿,感覺所購的手機被人塗畫了廣告一般。這樣的情況在國外市場同樣出現。Android手機的另一發售運營商Sprint就將在其機型中內置其手機商店程序。
四、同類機型用戶減少
在不少手機論壇都會有針對某一型號的子論壇,對一款手機的使用心得交流,並分享軟件資源。而對於Android平台手機,由於廠商豐富,產品類型多樣,這樣使用同一款機型的用戶越來越少,缺少統一機型的程序強化。舉個稍顯不當的例子,現在山寨機泛濫,品種各異,就很少有專門針對某個型號山寨機的討論和群組,除了哪些功能異常搶眼、頗受追捧的機型以外。
五、過分依賴開發商缺少標准配置
在使用PC端的Windows Xp系統的時候,都會內置微軟Windows Media Player這樣一個浏覽器程序,用戶可以選擇更多樣的播放器,如Realplay或暴風影音等。但入手開始使用默認的程序同樣可以應付多樣的需要。在 Android平台中,由於其開放性,軟件更多依賴第三方廠商,比如Android系統的SDK中就沒有內置音樂 播放器,全部依賴第三方開發,缺少了產品的統一性。
76. Android dvm的進程和Linux的進程, 應用程序的進程是否為同一個概念
答:DVM指dalivk的虛擬機。每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。而每一個DVM都是在Linux 中的一個進程,所以說可以認為是同一個概念。
77. sim卡的EF文件是什麼?有何作用
答:sim卡的文件系統有自己規范,主要是為了和手機通訊,sim本 身可以有自己的操作系統,EF就是作存儲並和手機通訊用的
78. 嵌入式操作系統內存管理有哪幾種, 各有何特性
頁式,段式,段頁,用到了MMU,虛擬空間等技術
79. 什麼是嵌入式實時操作系統, Android 操作系統屬於實時操作系統嗎?
嵌入式實時操作系統是指當外界事件或數據產生時,能夠接受並以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制所有實時任務協調一致運行的嵌入式操作系統。主要用於工業控制、 軍事設備、 航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬實時兩種,而android是基於linux內核的,因此屬於軟實時。
80. 一條最長的短信息約占多少byte?
中文70(包括標點),英文160,160個字節。
81. 有一個一維整型數組int[]data保存的是一張寬為width,高為height的圖片像素值信息。請寫一個算法,將該圖片所有的白色不透明(0xffffffff)像素點的透明度調整為50%。
82. 如何將SQLite數據庫(dictionary.db文件)與apk文件一起發布
解答:可以將dictionary.db文件復制到Eclipse Android工程中的res aw目錄中。所有在res aw目錄中的文件不會被壓縮,這樣可以直接提取該目錄中的文件。可以將dictionary.db文件復制到res aw目錄中
83. 如何將打開res aw目錄中的數據庫文件?
解答:在Android中不能直接打開res aw目錄中的數據庫文件,而需要在程序第一次啟動時將該文件復制到手機內存或SD卡的某個目錄中,然後再打開該數據庫文件。復制的基本方法是使用getResources().openRawResource方法獲得res aw目錄中資源的 InputStream對象,然後將該InputStream對象中的數據寫入其他的目錄中相應文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數據庫文件。
84. DDMS和TraceView的區別?
DDMS是一個程序執行查看器,在裡面可以看見線程和堆棧等信息,TraceView是程序性能分析器 。
85. java中如何引用本地語言
可以用JNI(java native interface java 本地接口)接口 。
86. 談談Android的IPC(進程間通信)機制
IPC是內部進程通信的簡稱, 是共享"命名管道"的資源。Android中的IPC機制是為了讓Activity和Service之間可以隨時的進行交互,故在Android中該機制,只適用於Activity和Service之間的通信,類似於遠程方法調用,類似於C/S模式的訪問。通過定義AIDL接口文件來定義IPC接口。Servier端實現IPC接口,Client端調用IPC接口本地代理。
87. NDK是什麼
NDK是一些列工具的集合,NDK提供了一系列的工具,幫助開發者迅速的開發C/C++的動態庫,並能自動將so和java 應用打成apk包。NDK集成了交叉編譯器,並提供了相應的mk文件和隔離cpu、平台等的差異,開發人員只需簡單的修改mk文件就可以創建
出so
88.一個“.java”源文件中是否可以包括多個類(不包括內部類)?有什麼限制?
可以。限制:一個文件中只能有一個public類,並且此public類必須與文件名相同
89.switch能否作用在byte上 能否作用在string上 能否作用在long上?
可以用在byte,但是long和string不行
確切說int之下的數字類型都可以,以及封裝了數字的類型 如enum
90.char型變量中能不能存儲一個中文漢字?為什麼?
是能夠定義成為一個中文的,因為java中以unicode編碼,一個char占16個字節,所以放一個中文是沒問題的,一個字符=8個字節,一個漢字=2個字符=16個字節。
91.使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?
使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。
92.View界面刷新的方法
Android程序中可以使用的界面刷新方法有兩種,分別是利用Handler與Invalidate()的組合和利用postInvalidate()來實現在線程中刷新界面。
每一次調用他們,他們就會自動去執行View中的OnDraw()一次,從而達到刷新界面的效果,所以如果你想不斷的刷新界面則最好是把調用此兩個方法的語句放在一個Thread中,判斷這線程是否已經中斷while (!Thread.currentThread().isInterrupted()) {},沒有不斷的執行調語句來刷新界面。
93.android 中 padding與margin的區別
android:padding和android:layout_margin的區別,其實概念很簡單,padding是站在父view的角度描述問題,它規定它裡面的內容必須與這個父view邊界的距離。margin則是站在自己的角度描述問題,規定自己和其他(上下左右)的view之間的距離,如果同一級只有一個view,那麼它的效果基本上就和padding一樣了。
94.android 匿名內部類是否可以繼承其他類?是否可以實現接口?
匿名的內部類不能extends(繼承)其它類,但內部類可以作為一個接口,由另一個內部類實現。
嵌套類可以作為接口的內部類。正常情況下,你不能在接口內部放置任何代碼,但嵌套類可以作為接口的一部分,因為它是static 的。只是將嵌套類置於接口的命名空間內,這並不違反接口的規則。
內部類被繼承,由於內部類有一個指向外圍類對象的秘密引用,所以在繼承內部類的時候,該秘密引用必須被初始化。
95.HashMap和Hashtable的有哪些不同?
繼承類不同:
A.HashMap繼承AbstractMap
B.Hashtable繼承
Dictionary 執行效率不同:
A.HashMap是非線程安全的,是Hashtable的輕量級實現,效率較高
B.Hashtable是線程安全的,效率較低
put方法對key和value的要求不同:
A.HashMap允許Entry的key或value為null
B.Hashtable不允許Entry的key或value為null,否則出現NullPointerException
有無contains方法:
A.HashMap沒有contains方法
B.Hashtable有contains方法
96.HTTP POST請求和GET請求的區別?
Get是向服務器發索取數據的一種請求,而Post是向服務器提交數據的一種請求
Get是獲取信息,而不是修改信息,類似數據庫查詢功能一樣,數據不會被修改
Get請求的參數會跟在url後進行傳遞,請求的數據會附在URL之後,以?分割URL和傳輸數據,參數之間以&相連,Get傳輸的數據有大小限制,因為GET是通過URL提交數據,那麼GET可提交的數據量就跟URL的長度有直接關系了,不同的浏覽器對URL的長度的限制是不同的。
GET請求的數據會被浏覽器緩存起來,用戶名和密碼將明文出現在URL上,其他人可以查到歷史浏覽記錄,數據不太安全。在服務器端,用Request.QueryString來獲取Get方式提交來的數據
Post請求則作為http消息的實際內容發送給web服務器,數據放置在HTML Header內提交,Post沒有限制提交的數據。Post比Get安全,當數據是中文或者不敏感的數據,則用get,因為使用get,參數會顯示在地址,對於敏感數據和不是中文字符的數據,則用post
POST表示可能修改變服務器上的資源的請求,在服務器端,用Post方式提交的數據只能用Request.Form來獲取。
97.Android中有哪幾種方法可以提高程序運行效率?
1)開發過程中,你只實現你所需要的功能;
2)能避免占用內存時,就一定不要去占用內存;
3)避免在類內部進行Getters/Setters
4)盡量使用內部類
5)最小化局部變量的作用域
98.android 在activity中使用this的優缺點
優點:
應用一:引用成員變量
應用二:調用類的構造方法
應用三:返回對象的值
缺點:
this一般出現在方法中,當方法沒有被調用時。並不知道this指向那個具體的對象。當某個對象調用有this的方法時,this就指向調用這個方法的對象。
99.站在地球上某一點,向南走一公裡,向東走一公裡,最後向北走一公裡回到了原點,地球上有多少個滿足這樣的條件?
分析:這是一道智力題。從邏輯上來講,題目從好像缺少了一次向西的過程,才可以回到原地。北極點的起點出發剛好走了一個正三角形,所以可以返回原點。
100.一個屋子裡有N人,已知3個人一桌多出兩人,5個人一桌多出四人,7個人一桌多六人,9個人一桌多八人,11個人剛好
設有X個人,那麼(X+1)能被3,5,7,9,整除~
這幾個數字的公倍數是315。
(X+1)應該是315的倍數,然後一個個驗證315N-1能被11整除~
那麼N就是8的公倍數啦~
所以,X是2519~
Linux內核啟動之後就到Android Init進程,進而啟動Android相關的服務和應用。啟動的過程如下圖所示: 下面將從Android4.0源碼中,和
現在的移動支付越來越便捷,為了防止被他人隨意使用,很多人都開始使用鎖屏功能。但是傳統的鎖屏功能都是使用的單一密碼,這樣被他人破解的可能性又大大的增加。那麼有
如果你想在你的Android程序中自動打印MainActivity.onCreate(line:37)這種類名.方法名(行數)的日志該如何實現呢? 1.引入Java的線程
中國電信發布了“天翼4G+”品牌,號稱比移動4G、聯通4G速度更快。4G才剛普及不久,現在又冒出來個4G+,4G+是什麼意思呢?需要