1. 程式人生 > >Android中Activity之間引數傳遞

Android中Activity之間引數傳遞

Intent:一直穿梭在Activity之間,它不光只是為了使Activity之間進行跳轉。在跳轉的時候,還可以進行Acivity之間的引數傳遞。

下面舉幾個列子。以MianActivity,TheActivity為例子。

    MianActivity類

    Intent i  = new Intent(MianActivity.this,TheActivity.class);

    //這裡就可以傳入你想要傳遞的引數了,第一個引數是資料名,可以根據自己愛好或者工作需求命名。第二個就是傳遞的引數,可以是字串,int值,也就是資料基本型別。

    i.putExtra("name","小貓");

    i.putExtra("age","18");

    startActivity(i);         

    TheAcivity類

     Intent i = getIntent();

    String name = i.getStringExtra("name");

    String age = i.getStringExtra("age");

    這樣就可以得到你想要從MianAcitivity傳入的引數。

    上面說的是傳遞簡單的資料基本型別,可現實往往不會被它們所滿足,當資料比較多的時候,這樣的傳遞就會顯得比較複雜。於是,Android推出了一個新的概念,資料包(Bundle)。

    MianActivity類

    Intent i  = new Intent(MianActivity.this,TheActivity.class);

    Bundle b = new Bundle();

    b.putString("name", "小貓");
    b.putInt("age", 13);

    i.putExtras(b);

    TheAcivity類

     Intent i = getIntent();

     Bundle data = i.getExtras();

    tv.setText(String.format("name=%s,age=%d,name1=%s", data.getString(age),data.getStringArray(name),data.getString("name1", "leo")));

    在這裡,你會發現。從Activity中,並沒有傳入name1。所以在這裡我給了它他一個預設值(leo);


    defaultValue:表示在傳入的引數為空的時候,可以預設一個寫入一個引數

     這個時候的執行結果:

                                                                                              

   當我們給我一個值得時候

    b.putInt("name1", "iwen");

    這個時候的執行結果:

      Bundle還有一種傳遞方式

    MianActivity類

    Intent i  = new Intent(MianActivity.this,TheActivity.class);

    Bundle b = new Bundle();

    b.putString("name", "小貓");
    b.putInt("age", 13);

    // i.putExtras(b);

    i.putExtra(“data”,b);

    TheAcivity類

     Intent i = getIntent();

     // Bundle data = i.getExtras();

     Bundle data = i.getBundleExtra("data");

    tv.setText(String.format("name=%s,age=%d,name1=%s", data.getString(age),data.getStringArray(name),data.getString("name1", "leo")));

    執行結果同上。

    可能在這上面,你並不滿足,因為他達不到你所有的需求。而且看起資料比較扎亂。比如,如何傳入實體類(自定義)的資料

    首先,建造一個實體類

    public class User {
    
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
   public User(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    } 
      MianActivity類

    Intent i  = new Intent(MianActivity.this,TheActivity.class);

    i.putExtra("User", new User("小貓", 2));

   startActivity(i);

    當這樣寫的時候,程式就會報錯,因為i.putExrra();方法不支援傳入一個實體類(自定義),需要例項化。怎麼解決呢?這個時候,系統就會給我們兩個選擇。

                                                                                                                   

       第一個,實體類實現序列化,修改實體類

    public class User implements Serializable{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public User(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    這樣,MianActivity類就不會報錯了,現在就只剩下TheAcivity類,取資料。

    TheAcivity類

     Intent i = getIntent();

     User user = (User) i.getSerializableExtra("User");

     tv.setText(String.format("User info(anme=%d,age=%s)", user.getName(),user.getAge()));

    第二個,使用android自己提供的序列化(Parcelable)。使用這個介面,他需要實現連個發describeContents();writeToParcel();修改實體類(自定義)

    public class User implements Parcelable{
    
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public User(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    //不用管
    @Override
    public int describeContents() {
        return 0;
    }
    //因為Parcelable沒有全自動話的序列機制,所以需要自己手寫。
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getName());
        dest.writeInt(getAge());
    }
    
    public static final Creator<User> CREATOR = new Creator<User>() {
        
        @Override
        public User createFromParcel(Parcel source) {
            //當資料型別多的時候,或者大量相同資料型別的時候,可以使用source.readBundle();方法
            return new User(source.readString(), source.readInt());
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
     這個時候只需要稍微修改一下TheAcivity類就可以了

    TheAcivity類

     Intent i = getIntent();

     User user =i.getParcelableExtra("User");

     tv.setText(String.format("User info(anme=%d,age=%s)", user.getName(),user.getAge()));

    這兩種方式有何區別呢?第一種Serializable操作簡單,一切都是由系統幫助程式系列化,它的缺點就是執行慢。速度慢。第二種Parcelable是android提供的介面,操作比較複雜,但它的速度是非常快的,因為很多東西都是需要自己寫的。

    如何將TheAcivity類的資料返回給MainActivity類呢?

        Intent i = new Intent();
        //這裡可以寫你想要出入的引數
        i.putExtra("data", tv.getText().toString());
        //第一個引數代表請求碼,這裡的1代表返回結果成功。第二個引數代表放回的資料
        setResult(1,i);

       ​MianActivity

    ​    ​這個時候startActivity();方法已經不行了,需要換成

       ​ startActivityForResult(i, 0);//第一個引數代表返回的資料,第二個引數代表引數狀態。

    ​    ​還需要重寫onActivityResult()方法將返回結果進行處理、分析。

    ​    ​//第一個引數代表請求碼,根據它可以判斷請求的意義是什麼。第二個引數代表返回碼,根據它可以判斷放回的狀態。第三個引數代表返回值
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 這裡可以獲取返回的資料data
        super.onActivityResult(requestCode, resultCode, data);
    }

這樣就可以得到你想要從MianAcitivity傳入的引數。

 %在跳轉的時候,需要在AndroidManifest.xml中為你Activity註冊。<activity android:name="com.example.intentstartactivity.TheActivity"></activity>%

新手初入,望。大神指點,同行留言交流。