欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android intent之间复杂参数传递方法详解

程序员文章站 2024-03-02 23:09:10
本文详细讲述了android intent之间复杂参数传递方法。分享给大家供大家参考,具体如下: intent是activity与activity之间,activity与...

本文详细讲述了android intent之间复杂参数传递方法。分享给大家供大家参考,具体如下:

intent是activity与activity之间,activity与service之间传递参数的介质,而这两种通常实现的是java基本对象类型和string的传递。
在实际项目中,页面之间传值,除了以上几种,经常还有传递object对象、list类型、list<object>类型和全局变量等等的需求。本文就是介绍怎么传递这几种类型的参数。

一、传递list<string>和list<integer>

以下以传递list<string>为例,发送list<string>语法为:

intent.putstringarraylistextra(key, list);

接收list<string>的语法为:

list = (arraylist<string>)getintent().getstringarraylistextra(key);

以下是一个运用实例:

// =============发送list<string>=============
arraylist<string> stringlist = new arraylist<string>();
stringlist.add("string1");
stringlist.add("string2");
stringlist.add("string3");
intent intent = new intent();
intent.setclass(listdemoactivity.this, stringlistactivity.class);
intent.putstringarraylistextra("liststring", stringlist);
startactivity(intent);
// ====================接收list<string>======================
arraylist<string> stringlist = (arraylist<string>) getintent().getstringarraylistextra("liststring");

list<integer>类似以上的操作调用下面的方法也可以实现发送和接收:

intent.putintegerarraylistextra(key, list);
list =(arraylist<integer>) getintent().getintegerarraylistextra(key);

二、使用serializable和parcelable两种方式传递object

android的intent之间传递对象有两种方法,一种是bundle.putserializable(key,object);另一种是bundle.putparcelable(key,object)。方法中的object要满足一定的条件,前者实现了serializable接口,而后者实现了parcelable接口。

以下是实现了serializable接口的user类,命名为serializableuser纯粹是从类名方便区分实现了parcelable接口的user类,实际开发中不建议这么命名:

public class serializableuser implements serializable {
  private string username;
  private string password;
  public serializableuser() {
  }
  public serializableuser(string username, string password) {
    this.username = username;
    this.password = password;
  }
  public string getusername() {
    return username;
  }
  public void setusername(string username) {
    this.username = username;
  }
  public string getpassword() {
    return password;
  }
  public void setpassword(string password) {
    this.password = password;
  }
}

以下是实现了parcelable接口的user类:

public class parcelableuser implements parcelable {
  private string username;
  private string password;
  public parcelableuser() {
  }
  public parcelableuser(string username, string password) {
    this.username = username;
    this.password = password;
  }
  public string getusername() {
    return username;
  }
  public void setusername(string username) {
    this.username = username;
  }
  public string getpassword() {
    return password;
  }
  public void setpassword(string password) {
    this.password = password;
  }
  public static final parcelable.creator<parcelableuser> creator = new creator<parcelableuser>() {
    @override
    public parcelableuser createfromparcel(parcel source) {
      parcelableuser parcelableuser = new parcelableuser();
      parcelableuser.username = source.readstring();
      parcelableuser.password = source.readstring();
      return parcelableuser;
    }
    @override
    public parcelableuser[] newarray(int size) {
      return new parcelableuser[size];
    }
  };
  @override
  public int describecontents() {
    // todo auto-generated method stub
    return 0;
  }
  @override
  public void writetoparcel(parcel dest, int flags) {
    // todo auto-generated method stub
    dest.writestring(username);
    dest.writestring(password);
  }
}

使用两种方式传递的语法分别为:

bundle.putserializable(key,object);
bundle.putparcelable(key,object);

使用两种方式接收的语法分别为:

object=(object) getintent().getserializableextra(key);
object=(object) getintent().getparcelableextra(key);

// ==========分别使用serializable和parcelable发送object===============
serializableuser serializableuser = new serializableuser("user1", "123456");
parcelableuser parcelableuser = new parcelableuser("user2","654321");
intent intent = new intent();
bundle bundle = new bundle();
bundle.putserializable("serializableuser", serializableuser);
bundle.putparcelable("parcelableuser", parcelableuser);
intent.setclass(listdemoactivity.this,objectactivity.class);
intent.putextras(bundle);
startactivity(intent);
// ====================接收object======================
serializableuser serializableuser = (serializableuser) getintent().getserializableextra("serializableuser");
parcelableuser parcelableuser = (parcelableuser) getintent().getparcelableextra("parcelableuser");

可能有人注意到,实现serializable接口就是把对象序列化,然后再传输,和java的常用编程没什么明显区别,而且user不需要明显改变,比较简单。我也推荐用这种方式。

然而,后一种实现parcelable接口的类比较复杂,parcelable是个什么东西呢?

android提供了一种新的类型:parcel,被用作封装数据的容器,封装后的数据可以通过intent或ipc传递。 除了基本类型以外,只有实现了parcelable接口的类才能被放入parcel中。

实现parcelable接口需要实现三个方法:

1)writetoparcel 方法。该方法将类的数据写入外部提供的parcel中。
声明:writetoparcel (parcel dest, int flags)。

2)describecontents方法。直接返回0就可以。

3)静态的parcelable.creator<t>接口,本接口有两个方法:

createfromparcel(parcel in) 实现从in中创建出类的实例的功能。
newarray(int size) 创建一个类型为t,长度为size的数组, returnnew t[size];即可。本方法是供外部类反序列化本类数组使用。

通过log测试输出可知程序的运行情况,在bundle.putparcelable("parcelableuser", parcelableuser);时,调用了parcelableuser类中的publicvoid writetoparcel(parcel dest, int flags)方法,并向dest写数据,在 parcelableuserparcelableuser= (parcelableuser)getintent().getparcelableextra("parcelableuser");的时候,调用了parcelableuser类中的public parcelableusercreatefromparcel(parcel source) 方法,创建了一个parcelableuser对象,并给这个对象的属性赋值,这里的parcel source和parcel dest是相同的,然后返回这个parcelableuser对象。最后就可以打印出parcelableuser的属性信息了。

三、传递list<object>

如果我们要传递的是object组成的list列表,即list<object>,该怎么办呢?首先需要将object对象实现serializable接口,然后把list强制类型转换成serializable类型,最后通过:

intent.putextra(key, (serializable)objectlist);

这样的语法来传递,接收方在接收的时候也需要强制类型转换成list<object>,接收 list<object>使用的语法是:

objectlist= (list<object>) getintent().getserializableextra(key);

以下是一个应用实例,这里使用的serializableuser类在上一步有给出,这里就不再重复给出。

// ==============发送list<object>===========
serializableuser user1 = new serializableuser("user1", "123456");
serializableuser user2 = new serializableuser("user2", "654321");
list<serializableuser> objectlist = new arraylist<serializableuser>();
objectlist.add(user1);
objectlist.add(user2);
intent intent = new intent();
intent.setclass(listdemoactivity.this, objectlistactivity.class);
intent.putextra("listobject", (serializable) objectlist);
startactivity(intent);
// ====================接收list<object>======================
list<serializableuser> objectlist = (list<serializableuser>) getintent().getserializableextra("listobject");

四、全局变量

如果一些特殊的应用级别的参数,不方便使用intent来传递参数,我们很容易想到是不是有全局变量或静态变量可以使用?java中的静态变量在这里是适合的,但其值在activity调用了system.exit(0)或finish()后就丢失了。

而在android中有个更优雅的方式是使用applicationcontext。这种全局变量方法相对静态类更有保障,直到应用的所有activity全部被destory掉之后才会被释放掉。

android的sdk中有说道,application是用来保存全局变量的,并且是在package创建的时候就存在了。所以当我们需要创建全局变量的时候,不需要再像j2se那样需要创建public权限的static变量,而直接在application中去实现。只需要调用context的 getapplicationcontext或者activity的getapplication方法来获得一个application对象,就可以设置或读取全局变量的值。

启动application时,系统会创建一个pid,即进程id,所有的activity就会在此进程上运行。那么我们在application创建的时候初始化全局变量,同一个应用的所有activity都可以取到这些全局变量的值,换句话说,我们在某一个activity中改变了这些全局变量的值,那么在同一个应用的其他activity中值就会改变。

用法:

1. 创建一个属于你自己的android.app.application的子类,为想要共享的private全局变量增加setter和getter方法。

public class myapp extends application{
  private string globalvariable;
  public string getglobalvariable() {
    return globalvariable;
  }
  public void setglobalvariable(string globalvariable) {
    this.globalvariable = globalvariable;
  }
}

2. 在manifest中申明一下这个类,这时android就为此建立一个全局可用的实例。

其实就是在原来仅有的一个application标签上为application制定一个名字为这个全局实例。

复制代码 代码如下:
<application android:name=".myapp" android:icon="@drawable/icon" android:label="@string/app_name">

3. 可以在其他任何地方使用context.getapplicationcontext()方法获取这个实例,进而获取其中的状态(变量)。

// ============使用全局变量传递参数==============
myapp myapp = ((myapp) getapplicationcontext());//获得我们的应用程序myapp
myapp.setglobalvariable("全局变量");
intent intent = new intent();
intent.setclass(listdemoactivity.this, globalactivity.class);
startactivity(intent);
// ============接收全局变量的参数==============
myapp myapp = ((myapp) getapplicationcontext());
string globalvariable = myapp.getglobalvariable();

更多关于android相关内容感兴趣的读者可查看本站专题:《android开发入门与进阶教程》、《android编程之activity操作技巧总结》、《android资源操作技巧汇总》、《android文件操作技巧汇总》、《android操作sqlite数据库技巧总结》、《android操作json格式数据技巧总结》、《android数据库操作技巧总结》、《android编程开发之sd卡操作方法汇总》、《android视图view技巧总结》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。