Android學習筆記-學習Intent的使用

剛看到Intent的時候,我的確有點困惑:從字面上來說,它表示一種意圖和目的;從使用上看,它似乎總是用於Activity之間的切換;而從它所在包 android.content來看,它似乎與內容有關。所以,我想或許可以這樣理解它: Intent類綁定一次操作,它負責攜帶這次操作所需要的數據以及操作的類型等。

  如果是這樣的話,是否可以將它與事件處理聯想起來?即一個Intent類似於一個Event。從Intent的兩個最重要的成員操作類型(Action)和數據(Data)來看,似乎是有道理的。文檔中說, Intent的Action的取值主要是一些定義好了的常量,例如PICK_ACTION,VIEW_ACTION,EDIT_ACTION之類的,而 Data則是一個ContentURI類型的變量,這一點,我們前面提到過。

  而且文檔中說Intent分爲兩大類,顯性的(Explicit )的和隱性的(Implicit)。在前面的例子中,我們在兩個Activity之間跳轉時初步使用了Intent類,當時是用setClass來設置 Intent的發起方與接收方,它被稱爲顯性的Intent,而隱性的Intent則不需要用setClass或setComponent來指定事件處理器,利用AndroidMenifest.xml中的配置就可以由平臺定位事件的消費者。

  一般來說,intent要定位事件的目的地,無外乎需要以下幾個信息:
1.種類(category),比如我們常見的 LAUNCHER_CATEGORY 就是表示這是一類應用程序。
2.類型(type),在前面的例子中沒用過,表示數據的類型,這是隱性Intent定位目標的重要依據。
3.組件(component),前面的例子中用的是setClass,不過也可以用setComponent來設置intent跳轉的前後兩個類實例。
4.附加數據(extras),在ContentURI之外還可以附加一些信息,它是Bundle類型的對象。

  Implicit Intent的使用相對有點麻煩,我們來做一個例子。首先,我們需要增加一個類:HelloThreeProvider,它必須實現於ConentProvider接口,所以代碼如下: 引用:
public class HelloThreeProvider extends ContentProvider ...{

    public boolean onCreate() ...{
        return true;
    }
   
    public int delete(ContentURI url, String where, String[] whereArgs) ...{
        return 0;
    }
    public ContentURI insert(ContentURI url, ContentValues initialValues)...{
        return url;
    }
    public Cursor query(ContentURI url, String[] projection, String selection,
            String[] selectionArgs, String groupBy, String having, String sort) ...{
        return null;
    }
    public int update(ContentURI url, ContentValues values, String where, String[] whereArgs) ...{
        return 0;
    }
   
    public String getType(ContentURI url) ...{
        return "vnd.sharetop.hello.three/vnd.hello.three";
    }

}這裏面有一堆方法要實現,因爲它們都是ContentProvider中的abstract方法,但是今天的例子中它們都半沒有什麼用處,只是一個 getType方法我們讓它不管什麼url都返回一個表示Intent所攜帶的數據類型是我們定義的一個長字串: vnd.sharetop.hello.three/vnd.hello.three。

  然後,在AndroidMenifest.xml中我們將上面這個HelloThreeProvider類加入應用程序: 引用:
<application android:icon="@drawable/icon">
        <provider class="HelloThreeProvider" android:authorities="cn.sharetop.android.hello" />               
        <activity class="HelloThree" android:label="@string/app_name">
            <intent-filter>
                <action android:value="android.intent.action.MAIN" />
                <category android:value="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity class="HelloThreeB" android:label="bbb">
        <intent-filter>
             <action android:value="android.intent.action.VIEW" />
             <category android:value="android.intent.category.DEFAULT" />
             <type android:value="vnd.sharetop.hello.three/vnd.hello.three" />
        </intent-filter>
        </activity>
    </application>相對於前面的例子,主要修改了HelloThreeB的配置,包括增加了一個<category>標籤表示這是  一個一般性的 activity而已。增加了<action>標籤,定義它負責處理VIEW_ACTION類型的操作。增加了<type>標籤給出一個數據類型的定義串vnd.sharetop.hello.three/vnd.hello.three。最主要的是在< application>下增加的那個<provider>標籤,有個authorities屬性,我們給的值是 cn.sharetop.android.hello,待一會我們再說它的用處。

  最後就是修改以前的跳轉代碼如下: 引用:
Intent intent = new Intent();
  intent.setData(new ContentURI("content://cn.sharetop.android.hello/one"));
  intent.setAction(intent.VIEW_ACTION);
  startActivity(intent);現在我們的setData裏的東西可與以前不一樣的,是吧?注意到它的格式了嗎?content://是個協議頭,固定這樣寫就行了。然後就是那個 authorities中定義的串了,再後面就是我們自定義的東西了,我這裏很簡單的寫個one,其它還可以更長一點,如one/101之類的。它負責去關聯上那個provider類。另外,增加了setAction的調用設置操作爲VIEW_ACTION,與Menifest中的< action>又掛上了。Android平臺負責根據Intent的Data信息中的authorities,找到 ContentProvider,然後getType,用type和intent中的Action兩個信息,再找到可以處理這個intent的消費者。

  OK,編譯運行。

  其實,如果是在一個應用內部,這種隱性的intent實在有點彆扭,個人覺得,這種鬆藕合的實現方法,只適用於那些較大的系統或者多個不同的應用之間的調用,可手機上又有什麼“較大”的系統呢?無非是可以與不同來源的多個應用之間方便地互操作而已,那麼會是什麼樣的場景呢?比如,給QQ好友發送gmail 郵件,用GoogleMap查找QQ好友所在的位置?看上去挺不錯的。

  關於這個ContentProvider,其實還有話說,它主要是的那些看似數據庫操作的方法我們都沒真正去實現呢。不過今天就到這裏了,等下回再去研究吧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章