美文网首页
Android-Intent之复杂数据的传递、

Android-Intent之复杂数据的传递、

作者: 晴天ccc | 来源:发表于2022-02-28 18:52 被阅读0次

目录

  • 前言
  • Intent传递简单数据
  • Intent传递数组
  • Intent传递集合
    ---- List<基本数据类型或String>
    ---- List< Object>
    ---- Map<String, Object>,或更复杂的
  • Intent传递对象
  • Intent传递Bitmap
  • 传来传去不方便,直接定义全局数据
  • 单例模式传参

1.Intent传递简单数据

image

2.Intent传递数组

写入数组

//可把StringArray换成其他数据类型,比如int,float等等...
bd.putStringArray("StringArray", new String[]{"呵呵","哈哈"});

读取数组:

String[] str = bd.getStringArray("StringArray")

3.Intent传递集合

1)List<基本数据类型或String>

写入集合

intent.putStringArrayListExtra(name, value)
intent.putIntegerArrayListExtra(name, value)

读取集合

intent.getStringArrayListExtra(name)
intent.getIntegerArrayListExtra(name)

2)List< Object>

将list强转成Serializable类型,然后传入(可用Bundle做媒介)

写入集合

putExtras(key, (Serializable)list)

读取集合

(List<Object>) getIntent().getSerializable(key)

PS:Object类需要实现Serializable接口

3)Map<String, Object>,或更复杂的

解决方法是:外层套个List

//传递复杂些的参数 
Map<String, Object> map1 = new HashMap<String, Object>();  
map1.put("key1", "value1");  
map1.put("key2", "value2");  
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
list.add(map1);  

Intent intent = new Intent();  
intent.setClass(MainActivity.this,ComplexActivity.class);  
Bundle bundle = new Bundle();  

//须定义一个list用于在budnle中传递需要传递的ArrayList<Object>,这个是必须要的  
ArrayList bundlelist = new ArrayList();   
bundlelist.add(list);   
bundle.putParcelableArrayList("list",bundlelist);  
intent.putExtras(bundle);                
startActivity(intent); 

4.Intent传递对象

新建Model类,并Parcelable序列化

public class Student implements Parcelable {
    
    private String name;
    private int age;
    private boolean sex;

    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 boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }
    
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
        dest.writeByte(this.sex ? (byte) 1 : (byte) 0);
    }

    public void readFromParcel(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
        this.sex = source.readByte() != 0;
    }

    public Student() {
    }

    protected Student(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
        this.sex = in.readByte() != 0;
    }

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel source) {
            return new Student(source);
        }

        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };
}

界面跳转

        Intent intent = new Intent(mContext, DetailsActivity.class);
        Bundle bundle = new Bundle();
        bundle.putParcelable("BUNDLE_KEY_DETAILS", itemModel);
        intent.putExtra("BUNDLE", bundle);
        startActivity(intent);

数据接收

        // 通过Bundle获取外部传入数据
        Bundle bundle = getIntent().getBundleExtra("BUNDLE");
        Student student = bundle.getParcelable("BUNDLE_KEY_DETAILS");

5.Intent传递Bitmap

bitmap默认实现Parcelable接口,直接传递即可

Bitmap bitmap = null;
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putParcelable("BUNDLE_KEY_BITMAP", bitmap);
intent.putExtra("BUNDLE", bundle);

6.传来传去不方便,直接定义全局数据

如果是传递简单的数据,有这样的需求,Activity1 -> Activity2 -> Activity3 -> Activity4, 你想在Activity中传递某个数据到Activity4中,一个个页面传么?

  • 如果你想某个数据可以在任何地方都能获取到,你就可以考虑使用Application全局对象了!
  • Android系统在每个程序运行的时候创建一个Application对象,而且只会创建一个。
  • 所以Application 是单例(singleton)模式的一个类,而且Application对象的生命周期是整个程序中最长的,他的生命 周期等于这个程序的生命周期。
  • 如果想存储一些比静态的值(固定不改变的,也可以变),如果你想使用 Application就需要自定义类实现Application类,并且告诉系统实例化的是我们自定义的Application 而非系统默认的,而这一步,就是在AndroidManifest.xml中卫我们的application标签添加:name属性!

1)自定义Application类:

class MyApp extends Application {
    private String myState;
    private static MyApp instance;
    
    public static MyApp getInstance(){
        return instance;
    }
    
    
    public String getState(){
        return myState;
    }
    public void setState(String s){
        myState = s;
    }
    
    @Override
    public void onCreate(){
        onCreate();
        instance = this;
    }
 
}

然后在任意地方我们就可以直接调用:MyApp.getInstance()来获得Application的全局对象!

3)在需要的地方调用:

class Blah extends Activity {
    @Override
    public void onCreate(Bundle b){
        ...
    MyApp appState = ((MyApp)getApplicationContext());
    String state = appState.getState();
        ...
    }
}

注意事项:

Application对象是存在于内存中的,也就有它可能会被系统杀死,比如这样的场景:

  • 我们在Activity1中往application中存储了用户账号,然后在Activity2中获取到用户账号,并且显示!
  • 如果我们点击home键,然后过了N久候,系统为了回收内存kill掉了我们的app。这个时候,我们重新 打开这个app,这个时候很神奇的,回到了Activity2的页面,但是如果这个时候你再去获取Application 里的用户账号,程序就会报NullPointerException,然后Crash掉。
  • 之所以会发生上述crash,是因为这个Application对象是全新创建的,可能你以为App是重新启动的, 其实并不是,仅仅是创建一个新的Application,然后启动上次用户离开时的Activity,从而创造App 并没有被杀死的假象!所以如果是比较重要的数据的话,建议你还是进行本地化,另外在使用数据的时候 要对变量的值进行非空检查!还有一点就是:不止是Application变量会这样,单例对象以及公共静态变量 也会这样。

7.单例模式传参

上面的Application就是基于单例的,单例模式的特点就是可以保证系统中一个类有且只有一个实例。 这样很容易就能实现,在A中设置参数,在B中直接访问了。这是几种方法中效率最高的。

①定义一个单例类:

   public class XclSingleton {
       
       //单例模式实例  
       private static XclSingleton instance = null;

       //synchronized 用于线程安全,防止多线程同时创建实例  
       public synchronized static XclSingleton getInstance() {
           if (instance == null) {
               instance = new XclSingleton();
           }
           return instance;
       }

       final HashMap<String, Object> mMap;

       private XclSingleton() {
           mMap = new HashMap<String, Object>();
       }

       public void put(String key, Object value) {
           mMap.put(key, value);
       }

       public Object get(String key) {
           return mMap.get(key);
       }

   }

②设置参数:

XclSingleton.getInstance().put("key1", "value1");  
XclSingleton.getInstance().put("key2", "value2");  

相关文章

网友评论

      本文标题:Android-Intent之复杂数据的传递、

      本文链接:https://www.haomeiwen.com/subject/qcvfbqtx.html