Intent使用小結

一、Intent簡介:Intent(意圖)主要是解決Android應用的各項組件之間的通訊。
Intent負責對應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android則根據此Intent的描述,負責找到對應的組件,將 Intent傳遞給調用的組件,並完成組件的調用。
因此,Intent在這裏起着一個媒體中介的作用,專門提供組件互相調用的相關信息,實現調用者與被調用者之間的解耦。

二、Intent的功能:啓動活動、啓動服務、發送廣播等等

三、顯示意圖和隱式意圖
1.顯示意圖:對於明確指出了目標組件名稱的Intent,我們稱之爲顯式Intent。
直接用組件的名稱定義目標組件,這種方式很直接。但是由於開發人員往往並不清楚別的應用程序的組件名稱,因此,顯示Intent更多用於在應用程序內部傳遞消息。比如在某應用程序內,一個Activity啓動一個Service。

//顯式意圖第一種方式
        //Intent intent = new Intent(this,TargetActivity.class);        
        //顯式意圖第二種方式
        //Intent intent = new Intent();
        //intent.setClass(this, TargetActivity.class);
        //intent.setClassName(this, "com.bei_ing.TargetActivity");
        //intent.setClassName("com.bei_ing", "com.bei_ing.TargetActivity");
        //顯式意圖第三種方式
        Intent intent = new Intent();
        //ComponentName component = new ComponentName(this, TargetActivity.class);
        //ComponentName component = new ComponentName(this,  "com.bei_ing.TargetActivity");
        ComponentName component = new ComponentName("com.bei_ing", "com.bei_ing.TargetActivity");
        intent.setComponent(component);
        startActivity(intent);

//開啓一個服務
startService(intent);
//發送一個廣播
sendBroadcast(intent);

2.隱式意圖:對於沒有明確指出目標組件名稱的Intent,則稱之爲隱式Intent。
恰恰相反,它不會用組件名稱定義需要激活的目標組件,它更廣泛地用於在不同應用程序之間傳遞消息。
Android系統尋找與Intent請求意圖最匹配的組件具體的選擇方法 是:Android將Intent的請求內容和一個叫做IntentFilter的過濾器比較,IntentFilter中包含系統中所有可能的待選組件。
如果IntentFilter中某一組件匹配隱式Intent請求的內容,那麼Android就選擇該組件作爲該隱式Intent的目標組件。
Android如何知道應用程序能夠處理某種類型的Intent請求呢?這需要應用程序在Android-Manifest.xml中聲明自己所含組件的過濾器(即可以匹配哪些Intent請求)。
一個沒有聲明Intent-Filter的組件只能響應指明自己名字的顯示Intent請求,而無法響應隱式Intent請求。
而一個聲明瞭IntentFilter的組件既可以響應顯示Intent請求,也可以響應隱式Intent請求。在通過和 IntentFilter比較來解析隱式Intent請求時,Android將以下三個因素作爲選擇的參考標準:
Action
Data
Category

Intent intent = new Intent();       
intent.setAction("action");
intent.setAction("hello.world");
intent.addCategory("category);
startActivity(intent);//該方法默認加入了 category: android.intent.category.DEFAULT,所以在配置文件必須要加蓋屬性

//調用系統的撥打電話的功能
    public void call(View v)
    {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.CALL");
        intent.setData(Uri.parse("tel://120"));
        startActivity(intent)
    }

    //調用系統的發送短信的功能
    public void send(View v)
    {
        Intent intent = new Intent();       
        intent.setAction(Intent.ACTION_SENDTO);
        intent.setData(Uri.parse("smsto://18612346789"));       
        startActivity(intent);
    }

    //調用系統的播放音樂的功能
    public void play(View v)
    {
        Intent intent = new Intent();       
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("file://mnt/sdcard/mp1.mp3"), "audio/mp3");     
        startActivity(intent);          
    }

—->intent 的setData()方法中的參數類型是Uri格式(可以看一看MIME格式的定義)
MIME:http://baike.baidu.com/link?url=37nGvdZ18j73c6ktJ9H7ZqsadX3CIt9yji_s25TpGOhhJirnXaAMUNXoiRwqUrg6YVfiY1BsZFsDbOVTqXudJq

四、通過Intent傳值:
1.普通方式:

//普通傳值,普通類型如int String float double boolean
intent.putExtra("name", "小白");
//  intent.putExtra("isOk", true);
intent.putExtra("age", 20);
//intent.putExtra("float", 99.9f);
//intent.putExtra("double", 99.9);

2.傳遞對象:
2.1 Serializable方式
序列化,講一個對象轉化成可存儲或可傳輸的狀態,序列化的對象可以在網絡上進行傳輸,也可以存儲到本地,操作只用讓一個類去實現Serializeable接口.

class Dog implements Serializable{
    String name;
    int age;
    @Override
    public String toString() {
        return "Dog [name=" + name + ", age=" + age + "]";
    }
}
傳值:
Dog dog = new Dog();
dog.name = "小白";
dog.age = 1;
intent.putExtra("dog", dog);//直接傳
//Bundle bundle = new Bundle();//傳bundle對象
//bundle.putSerializable("dog", dog);
//intent.putExtras(bundle);

接收:
Dog dog = (Dog) intent.getSerializableExtra("dog");//直接獲取所傳對象
//Bundle bundle =intent.getExtras();//接收一個bundle對象
//Dog dog = (Dog) bundle.get("dog");//再從bundle對象中獲取

2.2 Parcelable方式
與Serializable方式不同,Parcelable方式實現原理是將一個完整的對象進行分解,而分解後的每一部分都是Intent所支持的數據類型,這樣也就實現傳遞對象的功能了。
實現方式比Serializable稍微複雜一點:
1)實現Parcelable接口
2)重寫describeContents()方法和writeToParcel(..)方法
3)提供一個CREATOR 常量,重寫createFromParcel()方法和newArray()方法

class Cat implements Parcelable{
    String name;
    int age;
    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age + "]";
    }   
    @Override
    public int describeContents() {
        return 0;//直接返回0即可
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);//寫出名字
        dest.writeInt(age);//寫出年齡
    }   
    public static final Parcelable.Creator<Cat> CREATOR = new Creator<Cat>() {      
        @Override
        public Cat[] newArray(int size) {
            return new Cat[size];
        }       
        @Override
        public Cat createFromParcel(Parcel source) {
            Cat cat = new Cat();
            cat.name = source.readString();//讀取name
            cat.age = source.readInt();//讀取age
            return cat;
        }
    };
}

傳值:和Serializable沒兩樣
Cat cat = new Cat();
cat.name = "花花";
cat.age = 1;
intent.putExtra("cat", cat);

接收:
Cat cat = intent.getParcelableExtra("cat");

這裏寫圖片描述
3.兩種方式對比
Serializable的方式比較簡單,但是由於會把整個對象進行序列化,因此效率會比Parcelable方式低一些。

源碼實例

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