zoukankan      html  css  js  c++  java
  • Android学习笔记_46_Android的intent之间Object、List、List<Object>和全局变量数据的传递(Parcelable Serializable)

    转http://blog.csdn.net/pku_android/article/details/7456305

    一、传递List<String>和List<Integer>

    以下以传递List<String>为例,发送List<String>语法为:

    intent.putStringArrayListExtra(key, list);

    接收List<String>的语法为:

    list = (ArrayList<String>)getIntent().getStringArrayListExtra(key);

    以下是一个运用实例:

    <span style="font-size:16px;">// =============发送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");  
    </span>  

    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类,实际开发中不建议这么命名:

    <span style="font-size:16px;">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;  
        }  
    }  
    </span>  

    以下是实现了Parcelable接口的User类:

    <span style="font-size:16px;">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);  
        }  
    }  
    </span>  

     

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

    bundle.putSerializable(key,object);

    bundle.putParcelable(key,object);

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

    object=(Object) getIntent().getSerializableExtra(key);

    object=(Object) getIntent().getParcelableExtra(key);

    <span style="font-size:16px;">// ==========分别使用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");  
    </span>  

     

    可能有人注意到,实现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类在上一步有给出,这里就不再重复给出。

    <span style="font-size:16px;">// ==============发送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");  
    </span>  

    四、全局变量

    如果一些特殊的应用级别的参数,不方便使用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方法。

    <span style="font-size:16px;">public class MyApp extends Application{  
        private String globalVariable;  
        public String getGlobalVariable() {  
            return globalVariable;  
        }  
        public void setGlobalVariable(String globalVariable) {  
            this.globalVariable = globalVariable;  
        }  
    }  
    </span>  

    2.        在manifest中申明一下这个类,这时Android就为此建立一个全局可用的实例。其实就是在原来仅有的一个application标签上为application制定一个名字为这个全局实例。

     

    <span style="font-size:16px;"><application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name"></span>  

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

    <span style="font-size:16px;">// ============使用全局变量传递参数==============  
    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();  
    </span>  

    通过上述关于传递Object对象、List类型、List<Object>类型和全局变量等的介绍,希望能够给大家提供一些帮助。

  • 相关阅读:
    BZOJ3752 : Hack
    XIV Open Cup named after E.V. Pankratiev. GP of SPb
    XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
    BZOJ2087 : [Poi2010]Sheep
    BZOJ2080 : [Poi2010]Railway
    BZOJ2082 : [Poi2010]Divine divisor
    Moscow Pre-Finals Workshop 2016. National Taiwan U Selection
    XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
    XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
    XIII Open Cup named after E.V. Pankratiev. GP of SPb
  • 原文地址:https://www.cnblogs.com/lbangel/p/3504861.html
Copyright © 2011-2022 走看看