跳至主要內容

组件之间的数据传输


之前我们已经学习了组件之间的跳转,其实我们也尝试过数据之间的传输对吧!

在第一节课的时候,我们学习了怎么跳转,并且把数据传递到下一个界面,也就是我们登录那个例子,把登录的信息传到下一个界面.

接下来我们则系统进学习一下如何把数据传到下一个界面。大家也不要局限于Activity之间的数据传递,也就是说,这是组件与组件之间的数据传递,也适用于后面我们学到的服务,广播接收者…

四大组件,对吧!

理论知识我们可以传递什么类型的数据呢:

主要分两大类:基本数据类型和引用数据类型,引用数据类型的话也就是我们所说的对象。

基本数据类型有那些呢?复习一下java基础吧:

20171121_123435.png
20171121_123435.png

怎么把基本数据类型的数据传输到下一个组件呢?

基本数据类型的传输

前面我们要跳转的话需要创建一个意图对象,也就是Intent。这个Intent其实就是我们数据的载体,我们把数据扔intent里面。

所以就有了:

20171121_133036.png
20171121_133036.png

前面的String name是key,也就是这里put,另外一边则是get了。get的时候需要传入key,这样才能获取到对应的值。

一般来说,这个key定义为一个常量,并且两个组件都能访问到。

另外一边则是获取数据是吧!

首先我们要拿到意图对象,也就是Intent

20171121_133357.png
20171121_133357.png

通过get类型(key)的方法来获取到对应的内容,这样子就完成了数据内容的传输了。

例子:

package com.sunofbeaches.componentdatadeliver;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

/**
 * 虽然说我们这节课是组件之间的数据传递
 * 我们常说的组件有Activity,BroadcastReceiver,Service,ContentProvider
 * <p/>
 * 这里的话我们只学习Activity之间的数据传输,其实其他组件之间的数据传输也是一样的。
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    /**
     * 第一个按钮被点击了
     *
     * @param view
     */
    public void firstClick(View view) {
        //这样子写也是可以的哦!
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("booleanKey", true);
        intent.putExtra("charKey", 'a');
        intent.putExtra("byteKey", (byte) 1);
        intent.putExtra("shortKey", (short) 2);
        intent.putExtra("intKey", 3);
        intent.putExtra("longKey", 4l);
        intent.putExtra("floatKey", 0.5f);
        intent.putExtra("doubleKey", 0.6d);
        startActivity(intent);
    }


    /**
     * 第二个按钮被点击了
     */
    public void secondClick(View view) {

    }
}

第二个Activity

package com.sunofbeaches.componentdatadeliver;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

/**
 * Create by TrillGates 2017/11/23
 * 这是第二个界面,我们就在这个界面获取一个内容吧:
 */
public class SecondActivity extends Activity {

    private static final String TAG = "SecondActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /**
         * 拿到启动这个Activity的意图对象
         */
        Intent intent = getIntent();
        if (intent != null) {
            //前面的是key,后面的是默认值,假设获取不到的时候,就会返回默认值,也就是后面的那个值。
            //比如说我们把key写错了,这样子就获取不到值了。
            boolean booleanValue = intent.getBooleanExtra("booleanKey", false);
            //
            char charValue = intent.getCharExtra("charKey", '*');
            //
            byte byteValue = intent.getByteExtra("byteKey", (byte) 0);
            //
            short shortValue = intent.getShortExtra("shortKey", (short) 0);
            //
            int intValue = intent.getIntExtra("intKey", -1);
            //
            long longValue = intent.getLongExtra("longKey", 0l);
            //
            float floatValue = intent.getFloatExtra("floatKey", 0.0f);
            //
            double doubleValue = intent.getDoubleExtra("doubleKey", 0.0d);

            Log.d(TAG, "booleanValue = " + booleanValue);
            Log.d(TAG, "charValue = " + charValue);
            Log.d(TAG, "byteValue = " + byteValue);
            Log.d(TAG, "shortValue = " + shortValue);
            Log.d(TAG, "intValue = " + intValue);
            Log.d(TAG, "longValue = " + longValue);
            Log.d(TAG, "floatValue = " + floatValue);
            Log.d(TAG, "doubleValue = " + doubleValue);

        }
    }
}

执行结果是怎么样的呢?我们点击一下按钮如下:

20171123_183415.png
20171123_183415.png

引用数据类型的数据传输

前面已经说了如何传输基本数据类型,那么后面的话我们说一说怎么传递对象。

前面我们看到可以传String呢?String呢不是基本数据类型,它是引用数据类型。

String是已经实现了序列化的接口的:

Snip20171124_3.png
Snip20171124_3.png

Bitmap也就是位图,位图对象也是实现了序列化的接口的。

所以我们可以传位图对象,但是要注意的是它的大小 ,后面我们会讲到意图对象的传值的大小限制。

接下来,我们使用Intent来传一个对象:User

首先,我们要把User序列化。

package com.sunofbeaches.componentdatadeliver;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by TrillGates on 17/11/24.
 * God bless my code!
 */
public class User implements Parcelable {
    private String name;
    private int age;

    public User(String name, int age) {
        this.age = age;
        this.name = name;
    }

    protected User(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

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

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

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
}

实现Parcelable也行,Serializable也行。后者是Java的,前者是google写的类。两者的不同是前都比较高效,它是写到内存里的,后者是写到持久化存储单元里的。

然后呢?看代码吧:

   /**
     * 第二个按钮被点击了
     */
    public void secondClick(View view) {
        User user = new User("TrillGates", 25);
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("user", user);
        startActivity(intent);
    }

第二个Activity里的代码:

   User user = intent.getParcelableExtra("user");
   Log.d(TAG, "usr Name == " + user.getName());
   Log.d(TAG, "usr age == " + user.getAge());

运行起来,结果如下:

Snip20171124_5.png
Snip20171124_5.png

除了这样传以外,还可以怎么传呢?其实我们可以以协议的形式来传数据的呢:

实际的列子有那些呢?比如说我们第三应用发短信,第三方应用要调用电话拨号器。这个时候就需要去看它的意图过滤器了:

 <intent-filter>
                <action android:name="android.intent.action.CALL" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="tel" />
            </intent-filter>

我们可以看到,这其实就是约束,数据的约束,也就是说,我们要拨打电话的时候,是这样子的:

Intent intent = new Intent():

intent.addAction(“android.intent.action.CALL”);

intent.setCategory(“android.intent.category.DEFAULT”);

intent.setData(Uri.parse(“tel://10086”));

startActivity(intent);

这样能看明白吗?以上是纯手写的代码,没有开发工具也不知道单词有没写错。

OK,知道这个以后,我们就明白了,还可以通过setData来传数据,并且,在另外一个界面,通过getData来获取到。

获取到的是全部内容哦,包括约束:tel://10086

Intent封装数据的大小限制

有的时候,我们传的数据是挺大的。比如说,我们要传一张图片的时候,就很大了,是吧。那么它的现实是多大呢?我们可以看看官方的文档。

Snip20171201_17.png
Snip20171201_17.png

那怎么办呢?可以写到SD卡上,把路径传过去就可以。对于IPC来说,有好多种方式。IPC就是跨进程通迅啦,后面我们学习到服务的时候 ,我们也会学到AIDL,这也是IPC的一种方式。

从上面的文章我们可以知道,它限制的大小为1M,这块其实是共享内存来的。也就是Blundle.详细请看我们的视频课程吧!

数据回传

这节课我们讲的是怎么把数据传到下一个界面 ,下一节课的话我们会学习如何在第一个界面让第二个界面返回结果。比如说我们做web的时候,充值跳转。

还是再解释一下吧,当我们跳转到另外一个界面了,需要把值返回来,这个时候就是数据回传了。

我不写了,还是看视频吧,嘻嘻!!!

视频后面更新,今天是12月1日,估计会在这周更新哦!

Snip20171202_19.png
Snip20171202_19.png

在线视频教程

https://www.sunofbeach.net/c/1443881236287311874