1. 程式人生 > >Android面試題【初級工程師版】

Android面試題【初級工程師版】

初級工程師面試題

Android 基礎(2016.01.20 更新)(★★).
一、 Activity
1、 什麼是 Activity?
2、 請描述一下 Activity 生命週期
3、 常見的 Activity 型別
4、 如何儲存 Activity 的狀態?
5、 兩個 Activity 之間跳轉時必然會執行的是哪幾個方法?
6、 橫豎屏切換時 Activity 的生命週期
7、 如何將一個 Activity 設定成視窗的樣式
8、 如何退出 Activity?如何安全退出已呼叫多個 Activity 的Application?
9、 Activity 的四種啟動模式
10、 Android 中的 Context, Activity,Appliction 有什麼區別?
11、 兩個 Activity 之間傳遞資料,除了 intent,廣播接收者,content provider 還有啥?

12、 Context是什麼?
13、 如果後臺的Activity 由於某原因被系統回收了,如何在被系統回收之前儲存當前狀態?
14、你後臺的Activity 被系統回收怎麼辦?【較難】
15、怎麼在啟動一個Activity 時就啟動一個service?
16、同一個程式,但不同的Activity 是否可以放在不同的Task 任務棧中?
17  Activity 怎麼和service 繫結,怎麼在activity 中啟動自己對應的service? 

二、 Service
1、 Service 是否在 main thread 中執行, service 裡面是否能執行耗時的操作?
2、 Activity 怎麼和Service 繫結,怎麼在 Activity 中啟動自己對應的 Service?
3、 請描述一下 Service 的生命週期
4、 什麼是 IntentService?有何優點?
5、 說說 Activity、Intent、Service 是什麼關係
6、 Service 和 Activity 在同一個執行緒嗎
7、 Service 裡面可以彈吐司麼
8、 什麼是 Service 以及描述下它的生命週期。Service 有哪些啟動方法,有什麼區別,怎樣停用 Service?

9、 在 service 的生命週期方法 onstartConmand()可不可以執行網路操作?如何在 service 中執行網路操作?
10 不用service,B 頁面為音樂播放,跳轉到B,再返回,如何使音樂繼續播放11  什麼時候使用Service?

三、 Broadcast Receiver
1、 請描述一下 BroadcastReceiver
2、 在 manifest 和程式碼中如何註冊和使用 BroadcastReceiver
3、 BroadCastReceiver的生命週期
四、 ContentProvider
1、 請介紹下 ContentProvider 是如何實現資料共享的
2、 請介紹下 Android 的資料儲存方式
3、 為什麼要用 ContentProvider?它和sql 的實現上有什麼差別?
4、 說說 ContentProvider、ContentResolver、ContentObserver 之間的關係

五、 ListView
1、 ListView 如何提高其效率?
2、 當 ListView 資料集改變後,如何更新 ListView.
3、 ListView 如何實現分頁載入
4、 ListView 可以顯示多種型別的條目嗎
5、 ListView 如何定位到指定位置
6、 如何在 ScrollView 中如何嵌入 ListView
7、 ListView 中如何優化圖片
8、 ListView 中圖片錯位的問題是如何產生的
9、 如何重新整理 ListView 中單個 item 的資料,不重新整理整個ListView 的資料?

六、 Intent
1、 Intent 傳遞資料時,可以傳遞哪些型別資料?
2、 Serializable 和 Parcelable 的區別
3、 請描述一下 Intent 和 IntentFilter
七、 Fragment
1、 Fragment 跟 Activity 之間是如何傳值的
2、 描述一下 Fragment 的生命週期
3、 Fragment 的 replace 和 add 方法的區別
4、 Fragment 如何實現類似 Activity 棧的壓棧和出棧效果的?
5、 Fragment 在你們專案中的使用
6、 如何切換 fragement,不重新例項化


一、 Activity
1、什麼是Activity?
四大元件之一,一般的,一個使用者互動介面對應一個 activity
setContentView() ,// 要顯示的佈局
button.setOnclickLinstener{
}, activity 是Context的子類,同時實現了window.callback和keyevent.callback, 可以處理與窗體
使用者互動的事件.
我開發常用的的有FragmentActivitiyListActivity ,PreferenceActivity ,TabAcitivty 等…

2、請描述一下 Activity 生命週期
Activity 從建立到銷燬有多種狀態,從一種狀態到另一種狀態時會激發相應的回撥方法,這些回
調方法包括:onCreate onStart onResume onPause onStop onDestroy
其實這些方法都是兩兩對應的,onCreate建立與 onDestroy 銷燬;
onStart 可見與onStop 不可見;onResume可編輯(即焦點)與onPause;
如果介面有共同的特點或者功能的時候,還會自己定義一個 BaseActivity.
進度對話方塊的顯示與銷燬

3、常 見 的 Activity 類 型 有 FragmentActivitiy , ListActivity ,
TabAcitivty 等。請描述一下Activity 生命週期
Activity 從建立到銷燬有多種狀態,從一種狀態到另一種狀態時會激發相應的回撥方法,這些回撥方法包括:onCreate onStart onResume onPause onStop onDestroy
其實這些方法都是兩兩對應的,onCreate建立與 onDestroy 銷燬;
onStart 可見與onStop 不可見;onResume可編輯(即焦點)與onPause

4、如何儲存Activity 的狀態?
Activity 的狀態通常情況下系統會自動儲存的,只有當我們需要儲存額外的資料時才需要使用到這樣的功能。
一般來說, 呼叫onPause()和onStop()方法後的activity例項仍然存在於記憶體中, activity的所有資訊和狀態資料不會消失, 當activity 重新回到前臺之後, 所有的改變都會得到保留。
但是當系統記憶體不足時, 呼叫 onPause()和 onStop()方法後的 activity 可能會被系統摧毀, 此時記憶體中就不會存有該 activity 的例項物件了。如果之後這個 activity 重新回到前臺, 之前所作的改變就 會 消 失 。 為 了 避 免 此 種 情 況 的 發 生 , 我 們 可 以 覆 寫 onSaveInstanceState() 方 法 。
onSaveInstanceState()方法接受一個 Bundle 型別的引數, 開發者可以將狀態資料儲存到這個Bundle物件中, 這樣即使activity被系統摧毀, 當用戶重新啟動這個activity而呼叫它的onCreate()方法時, 上述的 Bundle 物件會作為實參傳遞給 onCreate()方法, 開發者可以從 Bundle 物件中取出儲存的資料, 然後利用這些資料將activity 恢復到被摧毀之前的狀態。
需要注意的是, onSaveInstanceState()方法並不是一定會被呼叫的, 因為有些場景是不需要儲存狀態資料的. 比如使用者按下BACK鍵退出activity時, 使用者顯然想要關閉這個activity, 此時是沒有必要儲存資料以供下次恢復的, 也就是 onSaveInstanceState()方法不會被呼叫. 如果呼叫onSaveInstanceState()方法, 呼叫將發生在 onPause()或 onStop()方法之前。
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}

5、兩個 Activity 之間跳轉時必然會執行的是哪幾個方法?
一般情況下比如說有兩個activity,分別叫A,B,當在A裡面啟用B元件的時候, A會呼叫 onPause()
方法,然後 B 呼叫 onCreate() ,onStart(), onResume()。
這個時候B 覆蓋了窗體, A 會呼叫 onStop()方法. 如果 B 是個透明的,或者是對話方塊的樣式, 就
不會呼叫A的 onStop()方法。

6、橫豎屏切換時Activity 的生命週期
此時的生命週期跟清單檔案裡的配置有關係。
1.不設定Activity 的 android:configChanges時, 切屏會重新呼叫各個生命週期預設首先銷燬
當前 activity,然後重新載入。
2.設定 Activity android:configChanges="orientation|keyboardHidden|screenSize"時,切
屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged 方法。
通常在遊戲開發, 螢幕的朝向都是寫死的。

7、如何將一個 Activity 設定成視窗的樣式
只需要給我們的Activity 配置如下屬性即可。
android:theme="@android:style/Theme.Dialog"

8、如 何退 出 Activity ? 如何 安全 退出 已 呼叫 多個 Activity 的Application?
1、通常情況使用者退出一個 Activity 只需按返回鍵,我們寫程式碼想退出activity 直接呼叫 finish()方法就行。
2、記錄開啟的 Activity:
每開啟一個 Activity,就記錄下來。在需要退出時,關閉每一個Activity 即可。
//虛擬碼
List<Activity> lists ;// 在 application 全域性的變數裡面
lists = new ArrayList<Activity>();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
lists.remove(this);
3、傳送特定廣播:
在需要結束應用時,傳送一個特定的廣播,每個Activity 收到廣播後,關閉即可。
//給某個 activity 註冊接受接受廣播的意圖
registerReceiver(receiver, filter)
//如果過接受到的是 關閉 activity 的廣播 就呼叫 finish()方法 把當前的 activity finish()掉
4、遞迴退出
在開啟新的 Activity 時使用 startActivityForResult,然後自己加標誌,在 onActivityResult 中
處理,遞迴關閉。
5、其實 也可以通過 intent的 flag 來實現 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
啟用一個新的activity。此時如果該任務棧中已經有該Activity,那麼系統會把這個Activity 上面的所有 Activity 幹掉。其實相當於給Activity 配置的啟動模式為 SingleTop。

9、Activity 的四種啟動模式,singletop 和 singletask 區別是什麼?
一般書籤的使用模式是 singletop,那為什麼不使用 singletask?
singleTop 跟 standard 模式比較類似。唯一的區別就是,當跳轉的物件是位於棧頂的activity(應
該可以理解為使用者眼前所 看到的 activity)時,程式將不會生成一個新的activity 例項,而是直接跳
到現存於棧頂的那個activity 例項。拿上面的例子來說,當 Act1 為 singleTop 模式時,執行跳轉
後棧裡面依舊只有一個例項,如果現在按返回鍵程式將直接退出。
singleTask模式和 singleInstance 模式都是隻建立一個例項的。在這種模式下,無論跳轉的對
象是不是位於棧頂的activity,程式都不會生成一個新的例項(當然前提是棧裡面已經有這個例項)。
這種模式相當有用,在以後的多activity 開發中,常會因為跳轉的關係導致同個頁面生成多個例項,
這個在使用者體驗上始終有點不好,而如果你將對應的activity 宣告為 singleTask 模式,這種問題將
不復存在。在主頁的Activity 很常用

10、Android 中的 Context, Activity,Appliction 有什麼區別?
相同:Activity 和Application都是 Context的子類。
Context從字面上理解就是上下文的意思, 在實際應用中它也確實是起到了管理上下文環境中各個參
數和變數的總用,方便我們可以簡單的訪問到各種資源。
不同:維護的生命週期不同。 Context維護的是當前的 Activity 的生命週期,Application維護
的是整個專案的生命週期。
使用 context的時候,小心記憶體洩露,防止記憶體洩露,注意一下幾個方面:
1. 不要讓生命週期長的物件引用activity context,即保證引用 activity 的物件要與 activity 本身
生命週期是一樣的。
2. 對於生命週期長的物件,可以使用application,context。
3. 避免非靜態的內部類,儘量使用靜態類,避免生命週期問題,注意內部類對外部物件引用導致
的生命週期變化。

11、兩個Activity 之間傳遞資料,除了intent,廣播接收者,content provider 還有啥?
1)利用 static靜態資料,public static成員變數
2)利用外部儲存的傳輸,
例如 File 檔案儲存
SharedPreferences首選項
Sqlite 資料庫

12、Context 是什麼?
1、它描述的是一個應用程式環境的資訊,即上下文。
2、該類是一個抽象(abstract class)類,Android 提供了該抽象類的具體實現類(ContextIml)。
3、 通過它我們可以獲取應用程式的資源和類, 也包括一些應用級別操作, 例如: 啟動一個 Activity,
傳送廣播,接受Intent,資訊,等。

二、 Service
1、Service 是否在 main thread 中執行, service 裡面是否能執行耗時的操
作?
預設情況,如果沒有顯示的指 servic所執行的程序, Service 和 activity 是執行在當前 app 所在進
程的 main thread(UI主執行緒)裡面。
service 裡面不能執行耗時的操作(網路請求,拷貝資料庫,大檔案 )
特殊情況 ,可以在清單檔案配置 service 執行所在的程序 ,讓 service 在另外的程序中執行
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" >
</service>

2、Activity 怎麼和 Service 繫結,怎麼在 Activity 中啟動自己對應的Service?
Activity 通過 bindService(Intent service, ServiceConnection conn, int flags)跟 Service進行
繫結,當繫結成功的時候 Service 會將代理物件通過回撥的形式傳給 conn,這樣我們就拿到了
Service 提供的服務代理物件。
在Activity 中可以通過 startService 和 bindService 方法啟動 Service。一般情況下如果想獲取
Service 的服務物件那麼肯定需要通過 bindService()方法,比如音樂播放器,第三方支付等。如
果僅僅只是為了開啟一個後臺任務那麼可以使用startService()方法。

3、請描述一下 Service 的生命週期
Service 有繫結模式和非繫結模式,以及這兩種模式的混合使用方式。不同的使用方法生命週期
方法也不同。
非 綁 定 模 式 : 當 第 一 次 調 用 startService 的 時 候 執 行 的 方 法 依 次 為 onCreate() 、
onStartCommand(),當 Service 關閉的時候呼叫onDestory 方法。
繫結模式:第一次 bindService()的時候,執行的方法為 onCreate()、onBind()解除繫結的
時候會執行 onUnbind()、onDestory()。
上面的兩種生命週期是在相對單純的模式下的情形。我們在開發的過程中還必須注意Service 實
例只會有一個,也就是說如果當前要啟動的Service 已經存在了那麼就不會再次建立該 Service 當然
也不會呼叫 onCreate()方法。
一個 Service 可以被多個客戶進行繫結,只有所有的繫結物件都執行了 onBind()方法後該
Service 才會銷燬,不過如果有一個客戶執行了 onStart()方法,那麼這個時候如果所有的 bind 客戶
都執行了unBind()該 Service 也不會銷燬。
Service 的生命週期圖如下所示,幫助大家記憶。


4、什麼是 IntentService?有何優點?
我們通常只會使用 Service,可能 IntentService 對大部分同學來說都是第一次聽說。那麼看了
下面的介紹相信你就不再陌生了。 如果你還是不瞭解那麼在面試的時候你就坦誠說沒用過或者不瞭解
等。並不是所有的問題都需要回答上來的。
一、IntentService 簡介
IntentService 是 Service 的子類,比普通的 Service 增加了額外的功能。先看 Service 本身存在
兩個問題:
Service 不會專門啟動一條單獨的程序,Service 與它所在應用位於同一個程序中;傳智播客武漢校區就業部出品 務實、創新、質量、分享、專注、責任
18
Service 也不是專門一條新執行緒,因此不應該在 Service 中直接處理耗時的任務;
二、IntentService 特徵
會建立獨立的worker執行緒來處理所有的Intent請求;
會建立獨立的worker執行緒來處理onHandleIntent()方法實現的程式碼,無需處理多執行緒問題;
所有請求處理完成後,IntentService 會自動停止,無需呼叫stopSelf()方法停止 Service;
為Service 的onBind()提供預設實現,返回null;
為Service 的onStartCommand提供預設實現,將請求 Intent新增到佇列中;
使用IntentService
本人寫了一個 IntentService 的使用例子供參考。該例子中一個 MainActivity 一個
MyIntentService,這兩個類都是四大元件當然需要在清單檔案中註冊。這裡只給出核心程式碼:


MainActivity.java:
public void click(View view){
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("start", "MyIntentService");
startService(intent);
}


MyIntentService.java

public class MyIntentService extends IntentService {
private String ex = "";
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Toast.makeText(MyIntentService.this, "-e " + ex,
Toast.LENGTH_LONG).show();
}
};
public MyIntentService(){
super("MyIntentService");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ex = intent.getStringExtra("start");
return super.onStartCommand(intent, flags, startId);
}
@Override
protected void onHandleIntent(Intent intent) {
/**
* 模擬執行耗時任務
* 該方法是在子執行緒中執行的,因此需要用到handler 跟主執行緒進行通訊
*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
執行後效果如下:

5、說說 Activity、Intent、Service 是什麼關係
他們都是 Android 開發中使用頻率最高的類。其中 Activity 和 Service 都是 Android 四大元件
之一。他倆都是 Context類的子類 ContextWrapper的子類,因此他倆可以算是兄弟關係吧。不過
兄弟倆各有各自的本領, Activity 負責使用者介面的顯示和互動, Service 負責後臺任務的處理。 Activity
和 Service 之間可以通過Intent傳遞資料,因此可以把Intent看作是通訊使者。

6、Service 和Activity 在同一個執行緒嗎
對於同一app 來說預設情況下是在同一個執行緒中的,main Thread (UI Thread)。

7、Service 裡面可以彈吐司麼
可以的。彈吐司有個條件就是得有一個 Context 上下文,而 Service 本身就是 Context 的子類,因此在 Service 裡面彈吐司是完全可以的。比如我們在 Service 中完成下載任務後可以彈一個吐司通知使用者。

8、什麼是 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 的話會丟擲異常。

9、在 service 的生命週期方法 onstartConmand()可不可以執行網路操作?如何在 service 中執行網路操作?
可以直接在 Service 中執行網路操作,在 onStartCommand()方法中可以執行網路操作

三、 Broadcast Receiver
1、請描述一下 BroadcastReceiver
BroadCastReceiver是 Android四大元件之一,主要用於接收系統或者app 傳送的廣播事件。
廣播分兩種:有序廣播和無序廣播。
內部通訊實現機制:通過Android 系統的 Binder機制實現通訊。
無序廣播:完全非同步,邏輯上可以被任何廣播接收者接收到。優點是效率較高。缺點是一個接收者不
能將處理結果傳遞給下一個接收者,並無法終止廣播intent的傳播。
有序廣播:按照被接收者的優先順序順序,在被接收者中依次傳播。比如有三個廣播接收者 A,B,C,
優先順序是A > B > C。那這個訊息先傳給 A,再傳給 B,最後傳給 C。每個接收者有權終止廣播,比
如 B終止廣播,C就無法接收到。此外 A接收到廣播後可以對結果物件進行操作,當廣播傳給 B 時,
B可以從結果物件中取得 A 存入的資料。
在通過 Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
initialCode, initialData, initialExtras)時我們可以指定 resultReceiver廣播接收者,這個接收者我們
可以認為是最終接收者,通常情況下如果比他優先順序更高的接收者如果沒有終止廣播,那麼他的
onReceive會被執行兩次,第一次是正常的按照優先順序順序執行,第二次是作為最終接收者接收。
如果比他優先順序高的接收者終止了廣播,那麼他依然能接收到廣播。
在我們的專案中經常使用廣播接收者接收系統通知,比如開機啟動、sd 掛載、低電量、外播電話、
鎖屏等。
如果我們做的是播放器,那麼監聽到使用者鎖屏後我們應該將我們的播放之暫停等。

2、在 manifest和程式碼中如何註冊和使用 BroadcastReceiver
在清單檔案中註冊廣播接收者稱為靜態註冊,在程式碼中註冊稱為動態註冊。靜態註冊的廣播接收者只要 app 在系統中執行則一直可以接收到廣播訊息,動態註冊的廣播接收者當註冊的 Activity 或
者 Service 銷燬了那麼就接收不到廣播了。
靜態註冊:在清單檔案中進行如下配置
<receiver android:name=".BroadcastReceiver1" >
<intent-filter>
<action android:name="android.intent.action.CALL" >
</action>
</intent-filter>
</receiver>
動態註冊:在程式碼中進行如下注冊
receiver = new BroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CALL_ACTION);
context.registerReceiver(receiver, intentFilter);

3、BroadCastReceiver 的生命週期
a. 廣播接收者的生命週期非常短暫的,在接收到廣播的時候建立,onReceive()方法結束之後銷
毀;
b. 廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response 錯誤對話方塊;
c. 最好也不要在廣播接收者中建立子執行緒做耗時的工作, 因為廣播接收者被銷燬後進程就成為了
空程序,很容易被系統殺掉;
d. 耗時的較長的工作最好放在服務中完成;

4、Android引入廣播機制的用意
a. 從 MVC的角度考慮(應用程式內) 其實回答這個問題的時候還可以這樣問,android 為什麼要有
那 4大元件,現在的移動開發模型基本上也是照搬的web 那一套 MVC架構,只不過是改了點
嫁妝而已。android 的四大元件本質上就是為了實現移動或者說嵌入式裝置上的 MVC架構,它們之間有時候是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制可以方便幾大組
件的資訊和資料互動。
b. 程式間互通訊息(例如在自己的應用程式內監聽系統來電)
c. 效率上(參考UDP的廣播協議在區域網的方便性)
d. 設計模式上(反轉控制的一種應用,類似監聽者模式)

四、 ContentProvider
1、請介紹下 ContentProvider 是如何實現資料共享的
在 Android 中如果想將自己應用的資料(一般多為資料庫中的資料)提供給第三發應用,那麼
我們只能通過ContentProvider來實現了。
ContentProvider 是應用程式之間共享資料的介面。使用的時候首先自定義一個類繼承
ContentProvider,然後覆寫 query、insert、update、delete 等方法。因為其是四大元件之一因
此必須在AndroidManifest檔案中進行註冊。
把自己的資料通過uri的形式共享出去
android 系統下 不同程式 資料預設是不能共享訪問
需要去實現一個類去繼承ContentProvider
public class PersonContentProvider extends ContentProvider{
public boolean onCreate(){
}
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])
}
<provider
android:exported="true"
android:name="com.itheima.contenProvider.provider.PersonContentPro
vider"android:authorities="com.itheima.person" />
第三方可以通過ContentResolver來訪問該 Provider。

2、請介紹下 Android 的資料儲存方式
a. File儲存
b. SharedPreference儲存
c. ContentProvider儲存
d. SQLiteDataBase 儲存
e. 網路儲存

3、為什麼要用 ContentProvider?它和sql 的實現上有什麼差別?
ContentProvider 遮蔽了資料儲存的細節,內部實現對使用者完全透明,使用者只需要關心操作資料的
uri就可以了,ContentProvider可以實現不同app 之間共享。
Sql也有增刪改查的方法,但是 sql 只能查詢本應用下的資料庫。而 ContentProvider 還可
以去增刪改查本地檔案. xml 檔案的讀取等。

4、說說 ContentProvider、ContentResolver、ContentObserver 之間的關係
a. ContentProvider 內容提供者,用於對外提供資料
b. ContentResolver.notifyChange(uri)發出訊息
c. ContentResolver 內容解析者,用於獲取內容提供者提供的資料
d. ContentObserver 內容監聽器,可以監聽資料的改變狀態傳智播客武漢校區就業部出品 務實、創新、質量、分享、專注、責任
26
e. ContentResolver.registerContentObserver()監聽訊息。

五、 ListView
1、ListView 如何提高其效率?
當 convertView 為空時,用 setTag()方法為每個 View 繫結一個存放控制元件的 ViewHolder 物件。當
convertView不為空, 重複利用已經建立的view的時候, 使用getTag()方法獲取繫結的ViewHolder
物件,這樣就避免了findViewById對控制元件的層層查詢,而是快速定位到控制元件。
① 複用ConvertView,使用歷史的view,提升效率200%
② 自定義靜態類ViewHolder,減少findViewById 的次數。提升效率50%
③ 非同步載入資料,分頁載入資料。
④ 使用WeakRefrence引用ImageView物件

2、當 ListView 資料集改變後,如何更新 ListView
使用該ListView的 adapter的 notifyDataSetChanged()方法。 該方法會使 ListView 重新繪製。

3、ListView 如何實現分頁載入
① 設定 ListView的滾動監聽器:setOnScrollListener(new OnScrollListener{….})
在監聽器中有兩個方法: 滾動狀態發生變化的方法(onScrollStateChanged)和 listView 被滾動
時呼叫的方法(onScroll)
② 在滾動狀態發生改變的方法中,有三種狀態:
手指按下移動的狀態: SCROLL_STATE_TOUCH_SCROLL: // 觸控滑動
慣性滾動(滑翔(flgin)狀態): SCROLL_STATE_FLING: // 滑翔
靜止狀態: SCROLL_STATE_IDLE: // 靜止
對不同的狀態進行處理:
分批載入資料,只關心靜止狀態:關心最後一個可見的條目,如果最後一個可見條目就是資料適
配器(集合)裡的最後一個,此時可載入更多的資料。在每次載入的時候,計算出滾動的數量,當滾
動的數量大於等於總數量的時候,可以提示使用者無更多資料了。

4、ListView 可以顯示多種型別的條目嗎
這個當然可以的,ListView 顯示的每個條目都是通過 baseAdapter 的 getView(int position,
View convertView, ViewGroup parent)來展示的, 理論上我們完全可以讓每個條目都是不同型別的
view。
比如:從伺服器拿回一個標識為id=1,那麼當 id=1 的時候,我們就載入型別一的條目,當 id=2
的時候,載入型別二的條目。常見佈局在資訊類客戶端中可以經常看到。
除此之外 adapter還提供了 getViewTypeCount()和 getItemViewType(int position)兩個方
法。在 getView方法中我們可以根據不同的viewtype 載入不同的佈局檔案。

5、ListView 如何定位到指定位置
可以通過ListView提供的 lv.setSelection(listView.getPosition());方法。

6、如何在 ScrollView 中如何嵌入 ListView
通常情況下我們不會在 ScrollView 中巢狀 ListView,但是如果面試官非讓我巢狀的話也是可以
的。
在ScrollView 新增一個ListView 會導致 listview 控制元件顯示不全,通常只會顯示一條,這是因為兩個控制元件的滾動事件衝突導致。所以需要通過listview 中的 item數量去計算 listview 的顯示高度,
從而使其完整展示,如下提供一個方法供大家參考。
lv = (ListView) findViewById(R.id.lv);
adapter = new MyAdapter();
lv.setAdapter(adapter);
setListViewHeightBasedOnChildren(lv);
----------------------------------------------------
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() *
(listAdapter.getCount() - 1));
params.height += 5;// if without this statement,the listview will be a
// little short
listView.setLayoutParams(params);
}
現階段最好的處理的方式是: 自定義 ListView,過載 onMeasure()方法,設定全部顯示。傳智播客武漢校區就業部出品 務實、創新、質量、分享、專注、責任
29
package com.meiya.ui;
import android.widget.ListView;
/**
*
* @Description: scrollview 中內嵌listview 的簡單實現
*
* @File: ScrollViewWithListView.java
*
*
* @Version
*/
public class ScrollViewWithListView extends ListView {
public ScrollViewWithListView(android.content.Context context,
android.util.AttributeSet attrs) {
super(context, attrs);
}
/**
* Integer.MAX_VALUE >> 2,如果不設定,系統預設設定是顯示兩條
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}

7、ListView 中如何優化圖片
圖片的優化策略比較多。
1、處理圖片的方式:
如果ListView中自定義的 Item中有涉及到大量圖片的,一定要對圖片進行細心的處理,因為圖片佔的記憶體是ListView項中最頭疼的,處理圖片的方法大致有以下幾種:
①、不要直接拿路徑就去迴圈 BitmapFactory.decodeFile;使用 Options儲存圖片大小、不要加
載圖片到記憶體去。
②、對圖片一定要經過邊界壓縮尤其是比較大的圖片,如果你的圖片是後臺伺服器處理好的那就
不需要了
③、在 ListView 中取圖片時也不要直接拿個路徑去取圖片,而是以 WeakReference(使用
WeakReference 代替強引用。比如可以使用 WeakReference mContextRef)、SoftReference、
WeakHashMap 等的來儲存圖片資訊。
④、在 getView中做圖片轉換時,產生的中間變數一定及時釋放
2、非同步載入圖片基本思想:
1)、 先從記憶體快取中獲取圖片顯示(記憶體緩衝)
2)、獲取不到的話從 SD卡里獲取(SD卡緩衝)
3)、都獲取不到的話從網路下載圖片並儲存到 SD 卡同時加入記憶體並顯示(視情況看是否要顯
示)
原理:
優化一:先從記憶體中載入,沒有則開啟執行緒從 SD卡或網路中獲取,這裡注意從 SD 卡獲取圖片
是放在子執行緒裡執行的,否則快速滑屏的話會不夠流暢。
優化二:於此同時,在 adapter裡有個 busy 變數,表示 listview 是否處於滑動狀態,如果是滑
動狀態則僅從記憶體中獲取圖片,沒有的話無需再開啟執行緒去外存或網路獲取圖片。
優化三:ImageLoader 裡的執行緒使用了執行緒池,從而避免了過多執行緒頻繁建立和銷燬,如果每
次總是 new一個執行緒去執行這是非常不可取的,好一點的用的 AsyncTask類,其實內部也是用到了
執行緒池。在從網路獲取圖片時,先是將其儲存到sd 卡,然後再載入到記憶體,這麼做的好處是在載入到記憶體時可以做個壓縮處理,以減少圖片所佔記憶體。

8、ListView 中圖片錯位的問題是如何產生的
圖片錯位問題的本質源於我們的listview使用了快取convertView, 假設一種場景, 一個listview
一屏顯示九個item,那麼在拉出第十個item 的時候,事實上該 item 是重複使用了第一個 item,也
就是說在第一個 item 從網路中下載圖片並最終要顯示的時候,其實該 item 已經不在當前顯示區域
內了,此時顯示的後果將可能在第十個 item上輸出影象,這就導致了圖片錯位的問題。所以解決之
道在於可見則顯示,不可見則不顯示。
9、如何重新整理 ListView 中單個 item 的資料,不重新整理整個 ListView 的數
據?
修改單個Item的資料,然後呼叫介面卡的 notifyDataSetChanged()方法

六、Intent
1、Intent 傳遞資料時,可以傳遞哪些型別資料?
Intent可以傳遞的資料型別非常的豐富, java的基本資料型別和 String以及他們的陣列形式
都可以,除此之外還可以傳遞實現了Serializable和 Parcelable介面的物件。

2、Serializable 和Parcelable 的區別
在使用記憶體的時候,Parcelable 類比 Serializable 效能高,所以推薦使用 Parcelable類。
1.Serializable在序列化的時候會產生大量的臨時變數,從而引起頻繁的GC。傳智播客武漢校區就業部出品 務實、創新、質量、分享、專注、責任
32
2.Parcelable 不能使用在要將資料儲存在磁碟上的情況。儘管 Serializable 效率低點,但在這
種情況下,還是建議你用Serializable 。
實現:
1.Serializable 的實現,只需要繼承 Serializable 即可。這只是給物件打了一個標記,系統會
自動將其序列化。
2.Parcelabel 的實現,需要在類中新增一個靜態成員變數 CREATOR,這個變數需要繼承
Parcelable.Creator 介面。
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}

3、請描述一下 Intent 和 IntentFilter
Android 中通過 Intent 物件來表示一條訊息,一個 Intent 物件不僅包含有這個訊息的目的
地,還可以包含訊息的內容,這好比一封 Email,其中不僅應該包含收件地址,還可以包含具體的內
容。對於一個 Intent 物件,訊息“目的地”是必須的,而內容則是可選項。
通過Intent 可以實現各種系統元件的呼叫與啟用.
IntentFilter: 可以理解為郵局或者是一個信箋的分揀系統…
這個分揀系統通過3個引數來識別
Action: 動作 view
Data: 資料 uri uri
Category : 而外的附加資訊
Action 匹配
Action 是一個使用者定義的字串, 用於描述一個 Android 應用程式元件, 一個 IntentFilter 可
以包含多個 Action。在 AndroidManifest.xml 的 Activity 定義時可以在其 <intent-filter >節點
指定一個 Action 列表用於標示 Activity 所能接受的“動作”,例如:
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<action android:name="cn.itheima.action" />
……
</intent-filter>
如果我們在啟動一個 Activity 時使用這樣的 Intent 物件:
Intent intent =new Intent();
intent.setAction("cn.itheima.action");
那麼所有的 Action 列表中包含了“cn.itheima”的 Activity 都將會匹配成功。
Android 預定義了一系列的 Action 分別表示特定的系統動作。這些 Action 通過常量的方式
定義在 android.content. Intent中,以“ACTION_”開頭。我們可以在 Android 提供的文件中找
到它們的詳細說明。
URI 資料匹配
一個 Intent 可以通過 URI 攜帶外部資料給目標元件。在 <intent-filter >節點中,通過
<data/>節點匹配外部資料。
mimeType 屬性指定攜帶外部資料的資料型別,scheme 指定協議,host、port、path 指定
資料的位置、埠、和路徑。如下:
<data android:mimeType="mimeType" android:scheme="scheme"
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 類別匹配
<intent-filter >節點中可以為元件定義一個 Category 類別列表,當 Intent 中包含這個列表
的所有專案時 Category 類別匹配才會成功。

七、Fragment
1、Fragment 跟 Activity 之間是如何傳值的
當 Fragment 跟 Activity 繫結之後,在 Fragment 中可以直接通過 getActivity()方法獲取到
其繫結的Activity 物件,這樣就可以呼叫Activity 的方法了。在 Activity 中可以通過如下方法獲取到
Fragment例項
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
Fragment fragment = fragmentManager.findFragmentById(id);
獲取到 Fragment之後就可以呼叫Fragment的方法。也就實現了通訊功能。

2、描述一下 Fragment 的生命週期

3、Fragment 的 replace 和 add方法的區別
Fragment本身並沒有replace和add方法, 這裡的理解應該為使用FragmentManager的replace
和 add 兩種方法切換Fragment時有什麼不同。
我們經常使用的一個架構就是通過 RadioGroup 切換 Fragment,每個 Fragment 就是一個功能模組。
case R.id.rb_1:
rb_1.setBackgroundColor(Color.RED);
transaction.show(fragment1);
// transaction.replace(R.id.fl, fragment1, "Fragment1");
break;
case R.id.rb_2:
rb_2.setBackgroundColor(Color.YELLOW);
// transaction.replace(R.id.fl, fragment2, "Fragment2");
transaction.show(fragment2);
break;
case R.id.rb_3:
rb_3.setBackgroundColor(Color.BLUE);
// transaction.replace(R.id.fl, fragment3, "Fragment3");
transaction.show(fragment3);
break;
實現這個功能可以通過replace 和 add 兩種方法。
Fragment 的容器一個 FrameLayout,add 的時候是把所有的 Fragment 一層一層的疊加到了
FrameLayout上了, 而replace的話首先將該容器中的其他Fragment去除掉然後將當前Fragment
新增到容器中。
一個 Fragment 容器中只能新增一個 Fragment 種類,如果多次新增則會報異常,導致程式終止,
而 replace 則無所謂,隨便切換。
因為通過 add 的方法新增的 Fragment,每個 Fragment 只能新增一次,因此如果要想達到切換效
果需要通過 Fragment 的的 hide 和 show 方法結合者使用。將要顯示的 show 出來,將其他 hide
起來。這個過程Fragment的生命週期沒有變化。
通過 replace 切換 Fragment,每次都會執行上一個 Fragment 的 onDestroyView,新 Fragment
的 onCreateView、onStart、onResume 方法。
基於以上不同的特點我們在使用的使用一定要結合著生命週期操作我們的檢視和資料。

4、Fragment 如何實現類似 Activity 棧的壓棧和出棧效果的?
Fragment 的事物管理器內部維持了一個雙向連結串列結構,該結構可以記錄我們每次 add 的
Fragment和 replace 的 Fragment, 然後當我們點選 back 按鈕的時候會自動幫我們實現退棧操作。
Add this transaction to the back stack. This means that the transaction will be remembered after it is committed,
and will reverse its operation when later popped off the stack.
Parameters:
name An optional name for this back stack state, or null.
transaction.addToBackStack("name");
//實現原始碼 在 BackStackRecord 中
public FragmentTransaction addToBackStack(String name) {
if (!mAllowAddToBackStack) {
throw new IllegalStateException(
"This FragmentTransaction is not allowed to be added to the back
stack.");
}
mAddToBackStack = true;
mName = name;
return this;
}
//上面的原始碼僅僅做了一個標記
除此之外因為我們要使用FragmentManger用的是FragmentActivity, 因此FragmentActivity
的 onBackPress方法必定重新覆寫了。開啟看一下,發現確實如此。
/**
* Take care of popping the fragment back stack or finishing the activity
* as appropriate.
*/
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
//mFragments 的原型是 FragmentManagerImpl,看看這個方法都幹嘛了
@Override
public boolean popBackStackImmediate() {
checkStateLoss();
executePendingTransactions();
return popBackStackState(mActivity.mHandler, null, -1, 0);
}
//看看 popBackStackState 方法都幹了啥,其實通過名稱也能大概瞭解 只給幾個片段吧,程式碼太多

while (index >= 0) {
//從後退棧中取出當前記錄物件
BackStackRecord bss = mBackStack.get(index);
if (name != null && name.equals(bss.getName())) {
break;
}
if (id >= 0 && id == bss.mIndex) {
break;
}
index--;
}

5、Fragment 在你們專案中的使用
Fragment 是 android3.0 以後引入的的概念,做區域性內容更新更方便,原來為了到達這一點要
把多個佈局放到一個 activity 裡面,現在可以用多 Fragment 來代替,只有在需要的時候才載入Fragment,提高效能。
Fragment的好處:
(1)Fragment 可以使你能夠將 activity 分離成多個可重用的元件,每個都有它自己的生命週期和
UI。
(2)Fragment可以輕鬆得建立動態靈活的 UI 設計,可以適應於不同的螢幕尺寸。從手機到平板電
腦。
(3)Fragment是一個獨立的模組,緊緊地與 activity 繫結在一起。可以執行中動態地移除、加入、
交換等。
(4)Fragment提供一個新的方式讓你在不同的安卓裝置上統一你的UI。
(5)Fragment 解決 Activity 間的切換不流暢,輕量切換。
(6)Fragment 替代 TabActivity 做導航,效能更好。
(7)Fragment 在 4.2.版本中新增巢狀fragment使用方法,能夠生成更好的介面效果。

6、如何切換 fragement,不重新例項化
翻看了 Android 官方 Doc,和一些元件的原始碼,發現 replace()這個方法只是在上一個 Fragment
不再需要時採用的簡便方法.
正確的切換方式是 add(),切換時hide(),add()另一個 Fragment;再次切換時,只需hide()當前,
show()另一個。
這樣就能做到多個Fragment切換不重新例項化:
public void switchContent(Fragment from, Fragment to) {
if (mContent != to) {
mContent = to;
FragmentTransaction transaction
=mFragmentMan.beginTransaction().setCustomAnimations(android.R.anim.fad
e_in, R.anim.slide_out);
if (!to.isAdded()) { // 先判斷是否被add 過
transaction.hide(from).add(R.id.content_frame, to).commit(); // 隱藏
當前的 fragment,add下一個到Activity中
} else {
transaction.hide(from).show(to).commit(); // 隱藏當前的
fragment,顯示下一個
}
}
}
}

1:Android中五種資料儲存方式分別是什麼?他們的特點?



(1)SharedPreference,存放較少的五種型別的資料,只能在同一個包內使
            用,生成XML的格式存放在裝置中
(2) SQLite資料庫,存放各種資料,是一個輕量級的嵌入式資料庫
(3) File檔案,通過讀取寫入方式生成檔案存放資料
(4) ContentProvider,主要用於讓其他應用程式使用儲存的資料
(5) 通過網路獲取資料和寫入資料到網路儲存空間


        答:Android提供了五種存取資料的方式


2:說說 android 中 mvc 的具體體現


mvc是model,view,controller的縮寫,mvc包含三個部分:
模型(model)物件:是應用程式的主體部分,所有的業務邏輯都應該寫在該層。
檢視(view)物件:是應用程式中負責生成使用者介面的部分。也是在整個mvc架構中使用者唯一可以看到的一層,接收使用者的輸入,顯示處理結果。
控制器(control)物件:是根據使用者的輸入,控制使用者介面資料顯示及更新model物件狀態的部分,控制器更重要的一種導航功能,響應使用者出發的相關事件,交給m層處理。
android鼓勵弱耦合和元件的重用,在android中mvc的具體體現如下:
(1)檢視(view):一般採用xml檔案進行介面的描述,使用的時候可以非常方便的引入。
(2)控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫過多的程式碼,要通過activity交割model業務邏輯層處理,這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這裡,程式就很容易被回收掉。
(3)模型層(model):對資料庫的操作、對網路等的操作都應該在model裡面處理,當然對業務計算等操作也是必須放在的該層的。


3:簡述SharedPreferences儲存方式以及SharedPreferences與SQLite資料庫的區別


SharedPreferences也是一種輕型的資料儲存方式,它的本質是基於XML檔案儲存key-value鍵值對資料,通常用來儲存一些簡單的配置資訊。其儲存位置在/data/data/<包名>/shared_prefs目錄下。SharedPreferences物件本身只能讀取資料而不支援寫入資料,儲存修改是通過Editor物件實現。SharedPreferences物件與SQLite資料庫相比,免去了建立資料庫,建立表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能儲存boolean,int,float,long和String五種簡單的資料型別,比如其無法進行條件查詢等。所以不論SharedPreferences的資料儲存操作是如何簡單,它也只能是儲存方式的一種補充,而無法完全替代如SQLite資料庫這樣的其他資料儲存方式。



4:描述handler 機制的原理


andriod提供了 Handler 和 Looper 來滿足執行緒間的通訊。
Handler 先進先出原則。
Looper類用來管理特定執行緒內物件之間的訊息交換(Message Exchange)。 
(1)Looper: 一個執行緒可以產生一個Looper物件,由它來管理此執行緒裡的Message Queue(訊息佇列)。 
(2)Handler: 你可以構造Handler物件來與Looper溝通,以便push新訊息到Message Queue裡;或者接收Looper從Message Queue取出)所送來的訊息。 
(3) Message Queue(訊息佇列):用來存放執行緒放入的訊息。 
(4)執行緒:UI thread 通常就是main thread,而Android啟動程式時會替它建立一個Message Queue。
 

 
5:顯式intent和隱式intent的區別是什麼(android)


答:Intent定義:Intent是一種在不同元件之間傳遞的請求訊息,是應用程式發出的請求和意圖。作為一個完整的訊息傳遞機制,Intent不僅需要傳送端,還需要接收端。
顯式Intent定義:對於明確指出了目標元件名稱的Intent,我們稱之為顯式Intent。
隱式Intent定義:對於沒有明確指出目標元件名稱的Intent,則稱之為隱式Intent。
說明:Android系統使用IntentFilter 來尋找與隱式Intent相關的物件。


6:如何優化ListView


1、如果自定義介面卡,那麼在getView方法中要考慮方法傳進來的引數contentView是否為null,如果為null就建立contentView並返回,如果不為null則直接使用。在這個方法中儘可能少建立view。
2、給contentView設定tag(setTag()),傳入一個viewHolder物件,用於快取要顯示的資料,可以達到影象資料非同步載入的效果。
3、如果listview需要顯示的item很多,就要考慮分頁載入。比如一共要顯示100條或者更多的時候,我們可以考慮先載入20條,等使用者拉到列表底部的時候再去載入接下來的20條。


7:簡述通過contentResolver獲取ContentProvider內容的基本步驟


第一:得到ContentResolver類物件:ContentResolver cr = getContentResolver();
第二:定義要查詢的欄位String陣列。
第三:使用cr.query();返回一個Cursor物件。
第四:使用while迴圈得到Cursor裡面的內容。


8:描述4 種 activity 的啟動模式


(1)standard :系統的預設模式,一次跳轉即會生成一個新的例項。假設有一個activity命名為MainActivity,執行語句:
startActivity(new Intent(MainActivity.this, MainActivity.class))後,MainActivity將跳轉到另外一個MainActivity,也就是現在的Task棧裡面有MainActivity的兩個例項。按返回鍵後你會發現仍然是在MainActivity(第一個)裡面。
(2)singleTop:singleTop 跟standard 模式比較類似。如果已經有一個例項位於Activity棧的頂部時,就不產生新的例項,而只是呼叫Activity中的newInstance()方法。如果不位於棧頂,會產生一個新的例項。例:當MainActivity為 singleTop 模式時,執行跳轉後棧裡面依舊只有一個例項,如果現在按返回鍵程式將直接退出。
(3)singleTask: singleTask模式和後面的singleInstance模式都是隻建立一個例項的。在這種模式下,無論跳轉的物件是不是位於棧頂的activity,程式都不會生成一個新的例項(當然前提是棧裡面已經有這個例項)。這種模式相當有用,在以後的多activity開發中,經常會因為跳轉的關係導致同個頁面生成多個例項,這個在使用者體驗上始終有點不好,而如果你將對應的activity宣告為 singleTask 模式,這種問題將不復存在。
(4)singleInstance: 設定為 singleInstance 模式的 activity 將獨佔一個task(感覺task可以理解為程序),獨佔一個task的activity與其說是activity,倒不如說是一個應用,這個應用與其他activity是獨立的,它有自己的上下文activity。


9:Android中如何訪問自定義ContentProvider?


通過ContentProvider的Uri訪問開放的資料。
(1)ContenResolver物件通過Context提供的方法getContenResolver()來獲得。
(2)ContenResolver提供了以下方法來操作:insert  delete  update  query這些方法分別會呼叫ContenProvider中與之對應的方法並得到返回的結果。

10:android中的動畫有哪幾類,它們的特點和區別是什麼?


答:Android中動畫可以分為兩大類:幀動畫、補間動畫
(1)補間動畫:你定義一個開始和結束,中間的部分由程式運算得到。主要有:旋轉、平移、放縮和漸變;AlphaAnimation(漸變型動畫)、scaleAnimation(縮放型動畫)、TranslateAnimation(平移型動畫)、 RotateAnimation(旋轉型動畫)、

(2)逐幀動畫:Frame(把一連串的圖片進行系列化連續播放,如同放電影的效果),它是通過播放一張一張圖片來達到動畫的效果;