Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習小Demo(19)利用Loader來實時接收短信

Android學習小Demo(19)利用Loader來實時接收短信

編輯:關於Android編程

之前寫過一篇文章《Android學習小Demo(13)Android中關於ContentObserver的使用》,在裡面利用ContentOberver去監測短信URI內容的變化。我們先來回顧一下,是如何利用ContentOberver來監測短信內容的變化的。

1)要自定義一個類,比如SmsContentObserver,繼承ContentObserver,並且實現其onChange方法。

2)在onChange方法中去查詢對應Uri,比如短信收件箱的內容,並將對應的記錄利用Handler發送到主界面。

3)在主界面Activity中,要創建一個SmsContentObserver,並且將其注冊到ContentReslover中去。

4)在主界面Activity的Handler中獲得在SmsContentObserver中變化的消息,更新主界面。

總的來說,過程就大概是這樣,大家有興趣可以看一下這一篇文章。

而本文介紹的是另外一種方法,利用Loader來實現差不多的效果,既然能夠說效果差不多,那麼就說明了Loader有一個跟ContentObserver的特性,沒錯,它能夠檢測到對應內容的變化。

先簡單說一下什麼是Loader。

Loader是Android在3.0之後才引進的一個類,其主要目的在於讓Android跟Data之間的交互變得更加簡單和高效,概括起來,我覺得其功能有以下兩點:

1)動態監測所處理對象狀態的變化,大部分情況下是處理數據,但我覺得只是一方面。

2)當界面變化,需要被重新創建的時候,它們能夠重新load到上一次的數據,而不需要再重新進行查詢。

當然,它還是異步的,也就意味著不會阻塞到主界面的顯示,不過這個功能很多其他的輔助類都有,也就不算啥特點了。

而正是到其第一點的特性,才讓我們有機會可以不用那麼麻煩去實現一個ContentObserver,而轉而來利用Loader來實現相同的功能。

這一次我們做一個展示短信的Demo。當我們打開手機中的短信應用的時候,如果這個時候有新短信進來,我們會看到新短信馬上就顯示在界面上的,而我們這個Demo也正是如此效果,具體請看(截圖大了點,莫怪)。

\


從上圖中可以看到,當我們點擊Send按鈕的時候,短信發過去,ListView中馬上就顯示出來剛剛發送的短信。

那麼應該怎麼使用Loader呢,我們下面來看代碼吧。

1)由於Loader是3.0之後才引進來的,所以在3.0之前,如果我們想要使用Loader的時候,主Activity必須要繼承FragmentActivity,才能夠拿到LoaderManager。

2)要實現LoaderManager的內部接口LoaderCallbacks,這是一個泛型接口,其定義如下:

<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHByZSBjbGFzcz0="brush:java;">public interface LoaderCallbacks { /** * Instantiate and return a new Loader for the given ID. * * @param id The ID whose loader is to be created. * @param args Any arguments supplied by the caller. * @return Return a new Loader instance that is ready to start loading. */ public Loader onCreateLoader(int id, Bundle args); /** * ... * @param loader The Loader that has finished. * @param data The data generated by the Loader. */ public void onLoadFinished(Loader loader, D data); /** * Called when a previously created loader is being reset, and thus * making its data unavailable. The application should at this point * remove any references it has to the Loader's data. * * @param loader The Loader that is being reset. */ public void onLoaderReset(Loader loader); }
所以,我們代碼中的第一步就是要實現這個接口,如下:

public class MainActivity extends FragmentActivity implements LoaderCallbacks{
    ...
    private Uri uri = Uri.parse("content://sms/inbox");
    ...
    @Override
	public Loader onCreateLoader(int arg0, Bundle arg1) {
		String[] projection = new String[] {"_id","address","body","type"};
				
		return new CursorLoader(this, uri, projection, null, null, "date desc");
	}

	@Override
	public void onLoadFinished(Loader loader, Cursor cursor) {
		
		mAdapter.swapCursor(cursor);
		
	}

	@Override
	public void onLoaderReset(Loader arg0) {
		// TODO Auto-generated method stub
		
	}
3)要定義一個Uri,因為Loader它必須要從某個地方load數據,而這個Demo中,我們要獲取的是收件箱的短信,所以在這裡就是拿sms/inbox了。

4)在OnCreateLoader方法中,要創建一個CursorLoader。CursorLoader是AsyncTaskLoader的一個子類,所以它是一個異步的Loader,不會影響到主界面的展示。

5)在OnLoadFinished方法中,對Load完回來存放在cursor的數據進行處理。

上面的接口,只是實現的方式而已,而當調用下面這個方法的時候,Loader才開始真正地發揮作用。在onCreate方法中,

	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	
		lvListView = (ListView) findViewById(R.id.lvListView);
		
		mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, 
				new String[] {"address","body"}, new int[] {android.R.id.text1, android.R.id.text2});
		lvListView.setAdapter(mAdapter);
		
		getSupportLoaderManager().initLoader(LOADER_ID, null, this);
	}

由於我們是用的support包,所以需要用getSupportLoaderManager類來調用initLoader方法,此方法有三個參數:

a)id,由於一個Activity或者Fragment只有一個LoaderManager,但是一個LoaderManager可以有多個Loader,用來處理不同的數據,所以id在這裡能唯一地確定是哪個Loader。

b)bundle,這是傳給LoaderManager的參數集合。

c)這是一個LoaderCallbacks的實現類,在這個Demo中,就是此Activity,所以就是this。

6)當調用getSupportLoaderManager().initLoader()方法的時候,Android首先會根據 id 去判斷是否已經存在這樣的一個loader了,如果存在的話,它就會直接使用已有的loader,而不會去創建一個新的,也就是說,它不會去調用接口方法中的onCreateLoader方法了。而如果不存在對應 id 的Loader,則會去調用onCreateLoader方法,並實例化一個新的Loader出來。

而當對應 id 的loader已經存在的時候,Android會直接load數據,而接口方法中的onLoadFinished也會在數據load完之後馬上被調用,這樣就會存在一種情況,如果在onLoadFinished方法中使用的變量是在onCreateLoader中才初始化的,那麼這個變量根本都沒被初始化,就被使用了,程序就會報錯了,所以在實際開發中,要考慮到這樣一種情況的存在,在 onLoadFinished方法中,要做好一些判斷。

最後還有一個onLoaderReset方法,沒有被用到,這個方法主要是在Loader不再被使用的時候,被關閉了等情況下,用來釋放對Loader的使用的,比如在這個Demo中,如果loader不再用了,那麼我們的Adpater就不應該再關聯對應的cursor了,那麼就可以在這裡進行判斷。

結束!源代碼下載。



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved