LoaderManager使用详解(一)---没有Loader之前的世界
生活随笔
收集整理的這篇文章主要介紹了
LoaderManager使用详解(一)---没有Loader之前的世界
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來源: http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html 感謝作者Alex Lockwood的努力,讓我們看到如此精彩的文章。
這一部分將對Loaders和LoaderManager做一個簡短的介紹。第一節將在Android3.0之前如何載入數據,指出其缺陷。第二節講述每個類的目的,以及它們異步載入數據的能力。 這篇文章是有關Loaders和LoaderManager一系列文章的開篇,該系列如下:
一:Loaders之前世界 二:了解LoaderManager 三:實現Loaders 四:實例:AppListLoader
如果你對Loaders和LoaderManager完全不了解,在繼續閱讀之前,強烈建議你讀一下Loaders向導。
在這篇文章強調及時反饋的同時,Android3.0之前的APIs似乎并沒有支持該特性。在Loaders之前,cursors主要通過兩個Activity方法(現在已經過時deprecated)來進行管理和查詢: ? public void startManagingCursor(Cursor) 告訴activity根據自己的生命周期來管理cursor的生命周期。cursor會被自 動deactivate()當活動stopped時。會自動close()當活動摧毀的時候。當活動stopped之后重新 restarted,cursor會re-queried(requery())重新查詢最新的數據。
public Cursor managedQuery(Uri, String, String, String, String) 該函數是對ContentResolver的query()方法的包裝。除了執行query之外,在它返回之前還會將調用startManagingCursor(cursor)。也就是說將這個query的cursor放入了activity生命周期管理了。
用起來很方便的同時,上面的方法在UI線程中執行查詢操作時,會導致嚴重的延遲問題。而且該 “managed cursors”方式在activity配置變化(configuration changed,橫豎屏切換、鍵盤彈出等)時,并不會保持數據。在這些情況下會重新requry()數據,但是實際上是沒有必要、低效,而且會導致方向切 換呆滯和卡頓。
[java] view plaincopypublic?class?SampleListActivity?extends?ListActivity?{?? ?? ??private?static?final?String[]?PROJECTION?=?new?String[]?{"_id",?"text_column"};?? ?? ??@Override?? ??protected?void?onCreate(Bundle?savedInstanceState)?{?? ????super.onCreate(savedInstanceState);?? ?? ????//?Performs?a?"managed?query"?to?the?ContentProvider.?The?Activity??? ????//?will?handle?closing?and?requerying?the?cursor.?? ????//?? ????//?WARNING!!?This?query?(and?any?subsequent?re-queries)?will?be?? ????//?performed?on?the?UI?Thread!!?? ????Cursor?cursor?=?managedQuery(?? ????????CONTENT_URI,??//?The?Uri?constant?in?your?ContentProvider?class?? ????????PROJECTION,???//?The?columns?to?return?for?each?data?row?? ????????null,?????????//?No?where?clause?? ????????null,?????????//?No?where?clause?? ????????null);????????//?No?sort?order?? ?? ????String[]?dataColumns?=?{?"text_column"?};?? ????int[]?viewIDs?=?{?R.id.text_view?};?? ??? ????//?Create?the?backing?adapter?for?the?ListView.?? ????//?? ????//?WARNING!!?While?not?readily?obvious,?using?this?constructor?will??? ????//?tell?the?CursorAdapter?to?register?a?ContentObserver?that?will?? ????//?monitor?the?underlying?data?source.?As?part?of?the?monitoring?? ????//?process,?the?ContentObserver?will?call?requery()?on?the?cursor??? ????//?each?time?the?data?is?updated.?Since?Cursor#requery()?is?performed??? ????//?on?the?UI?thread,?this?constructor?should?be?avoided?at?all?costs!?? ????SimpleCursorAdapter?adapter?=?new?SimpleCursorAdapter(?? ????????this,????????????????//?The?Activity?context?? ????????R.layout.list_item,??//?Points?to?the?XML?for?a?list?item?? ????????cursor,??????????????//?Cursor?that?contains?the?data?to?display?? ????????dataColumns,?????????//?Bind?the?data?in?column?"text_column"...?? ????????viewIDs);????????????//?...to?the?TextView?with?id?"R.id.text_view"?? ?? ????//?Sets?the?ListView's?adapter?to?be?the?cursor?adapter?that?was??? ????//?just?created.?? ????setListAdapter(adapter);?? ??}?? }??
上面的代碼有3個問題。如果你讀懂了上面講的內容,那么開始兩個問題不難讀懂。
1. managedQuery在Ui線程中執行了一個查詢操作,這將導致應用無響應,這種方法不應該再使用。 2. 通過查看Activity.java源碼,可以知道managedQuery也順便調用了startManagingCursor來管理查詢到的數據。看 起來很簡便,因為我們不用考慮cursor后續的關閉、requery等。但是使用這種方式導致每次activity的狀態從stopped返回時都需要 重新查詢數據,這通常會導致UI線程卡頓。讓activity替我們管理cursor所冒的風險大于便捷性。 3. 32行的SimpleCursorAdapter構造方法過時了,不應該再使用。該構造方法問題是,當有改變時,將導致 SimpleCursorAdapter自動查詢。更具體來說,CursorAdapter會在數據上注冊一個ContentObserver監聽器,當 監聽的數據變化時會requery數據。我們應該使用標準的構造函數(如果你嘗試使用CursorLoader來載入適配器數據,確保最后一個參數傳入值 為0)。如果你不能理解第三條,沒有關系,這僅僅只是個小錯誤。
Android平板設備的發布,應該加強UI友好性(反應更快)。更大的設備,7~10寸的 平板的應用更復雜、交互更多、有更多的界面布局。后續將介紹Fragment,fragment使應用更動態化,更多的事件驅動。一個簡單的,單線程的方 法來載入數據顯然已經不再合適。所以這就是Loader和LoaderManager在Android3.0誕生的背景。
第一部分?沒有Loader之前的世界
這一部分將對Loaders和LoaderManager做一個簡短的介紹。第一節將在Android3.0之前如何載入數據,指出其缺陷。第二節講述每個類的目的,以及它們異步載入數據的能力。 這篇文章是有關Loaders和LoaderManager一系列文章的開篇,該系列如下:
一:Loaders之前世界 二:了解LoaderManager 三:實現Loaders 四:實例:AppListLoader
如果你對Loaders和LoaderManager完全不了解,在繼續閱讀之前,強烈建議你讀一下Loaders向導。
以前情況
在Android3.0之前,很多應用程序響應性能方面有缺陷。UI切換之間的小故障、activity切換延遲、ANR問題。響應性能方面的故障大多數來源于此事實----大多數開發者在UI線程中執行了查詢操作---用這種方式載入數據是最差的選擇。在這篇文章強調及時反饋的同時,Android3.0之前的APIs似乎并沒有支持該特性。在Loaders之前,cursors主要通過兩個Activity方法(現在已經過時deprecated)來進行管理和查詢: ? public void startManagingCursor(Cursor) 告訴activity根據自己的生命周期來管理cursor的生命周期。cursor會被自 動deactivate()當活動stopped時。會自動close()當活動摧毀的時候。當活動stopped之后重新 restarted,cursor會re-queried(requery())重新查詢最新的數據。
public Cursor managedQuery(Uri, String, String, String, String) 該函數是對ContentResolver的query()方法的包裝。除了執行query之外,在它返回之前還會將調用startManagingCursor(cursor)。也就是說將這個query的cursor放入了activity生命周期管理了。
用起來很方便的同時,上面的方法在UI線程中執行查詢操作時,會導致嚴重的延遲問題。而且該 “managed cursors”方式在activity配置變化(configuration changed,橫豎屏切換、鍵盤彈出等)時,并不會保持數據。在這些情況下會重新requry()數據,但是實際上是沒有必要、低效,而且會導致方向切 換呆滯和卡頓。
Managed Cursors的問題
讓我們在一個簡單的代碼里面模擬managed cursors的問題。下面提供的代碼是在一個ListActivity里面載入數據使用的是Android3.0之前的APIs。該活動從 ContentProvider里面查詢數據,并且管理返回的cursor。查詢結果用SimpleCursorAdapter包裝,并且顯示在 listview中。代碼精煉如下:[java] view plaincopy
上面的代碼有3個問題。如果你讀懂了上面講的內容,那么開始兩個問題不難讀懂。
1. managedQuery在Ui線程中執行了一個查詢操作,這將導致應用無響應,這種方法不應該再使用。 2. 通過查看Activity.java源碼,可以知道managedQuery也順便調用了startManagingCursor來管理查詢到的數據。看 起來很簡便,因為我們不用考慮cursor后續的關閉、requery等。但是使用這種方式導致每次activity的狀態從stopped返回時都需要 重新查詢數據,這通常會導致UI線程卡頓。讓activity替我們管理cursor所冒的風險大于便捷性。 3. 32行的SimpleCursorAdapter構造方法過時了,不應該再使用。該構造方法問題是,當有改變時,將導致 SimpleCursorAdapter自動查詢。更具體來說,CursorAdapter會在數據上注冊一個ContentObserver監聽器,當 監聽的數據變化時會requery數據。我們應該使用標準的構造函數(如果你嘗試使用CursorLoader來載入適配器數據,確保最后一個參數傳入值 為0)。如果你不能理解第三條,沒有關系,這僅僅只是個小錯誤。
Android平板設備的發布,應該加強UI友好性(反應更快)。更大的設備,7~10寸的 平板的應用更復雜、交互更多、有更多的界面布局。后續將介紹Fragment,fragment使應用更動態化,更多的事件驅動。一個簡單的,單線程的方 法來載入數據顯然已經不再合適。所以這就是Loader和LoaderManager在Android3.0誕生的背景。
Android3.0,Loaders, LoaderManager
在Honeycomb之前,很難管理cursors的操作,比如,在UI線程中正常同步,確 保所有查詢適時在后臺線程中執行。Android3.0引入了Loader和LoaderManager類來簡化該過程。可以通過使用 ASL(Android Support Library),在Android1.6以上的系統實現這兩個類。 新的Loader API是一個巨大的進步,是用戶體驗的巨大進步。Loaders確保所有的cursor操作是異步的,從而排除了UI線程中堵塞的可能性。而且,當通過 LoaderManager來管理,Loaders還可以在activity實例中保持當前的cursor數據,也就是不需要重新查詢(比如,當因為橫豎 屏切換需要重新啟動activity時)。還有額外的好處,當數據改變時,Loaders可以很聰明的自動檢測底層數據的更新和重新檢索。總結
自從有了Honeycomb的Loaders以及其實現庫,Android應用變得更好了。 現在還使用startManagingCursor和managedQuery是非常不合適的,不僅僅將你的程序變慢,而且存在程序卡死的潛在地可能性。 另一方面,Loaders可以通過將數據載入工作交給單獨的后臺進程,將明顯的提高用戶體驗。總結
以上是生活随笔為你收集整理的LoaderManager使用详解(一)---没有Loader之前的世界的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android开发】用户界面设计-开发
- 下一篇: linux下查找某个目录下包含某个字符串