组件之间的数据传输
之前我们已经学习了组件之间的跳转,其实我们也尝试过数据之间的传输对吧!
在第一节课的时候,我们学习了怎么跳转,并且把数据传递到下一个界面,也就是我们登录那个例子,把登录的信息传到下一个界面.
接下来我们则系统进学习一下如何把数据传到下一个界面。大家也不要局限于Activity之间的数据传递,也就是说,这是组件与组件之间的数据传递,也适用于后面我们学到的服务,广播接收者…
四大组件,对吧!
理论知识我们可以传递什么类型的数据呢:
主要分两大类:基本数据类型和引用数据类型,引用数据类型的话也就是我们所说的对象。
基本数据类型有那些呢?复习一下java基础吧:
怎么把基本数据类型的数据传输到下一个组件呢?
基本数据类型的传输
前面我们要跳转的话需要创建一个意图对象,也就是Intent。这个Intent其实就是我们数据的载体,我们把数据扔intent里面。
所以就有了:
前面的String name是key,也就是这里put,另外一边则是get了。get的时候需要传入key,这样才能获取到对应的值。
一般来说,这个key定义为一个常量,并且两个组件都能访问到。
另外一边则是获取数据是吧!
首先我们要拿到意图对象,也就是Intent
通过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);
}
}
}
执行结果是怎么样的呢?我们点击一下按钮如下:
引用数据类型的数据传输
前面已经说了如何传输基本数据类型,那么后面的话我们说一说怎么传递对象。
前面我们看到可以传String呢?String呢不是基本数据类型,它是引用数据类型。
String是已经实现了序列化的接口的:
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());
运行起来,结果如下:
除了这样传以外,还可以怎么传呢?其实我们可以以协议的形式来传数据的呢:
实际的列子有那些呢?比如说我们第三应用发短信,第三方应用要调用电话拨号器。这个时候就需要去看它的意图过滤器了:
<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封装数据的大小限制
有的时候,我们传的数据是挺大的。比如说,我们要传一张图片的时候,就很大了,是吧。那么它的现实是多大呢?我们可以看看官方的文档。
那怎么办呢?可以写到SD卡上,把路径传过去就可以。对于IPC来说,有好多种方式。IPC就是跨进程通迅啦,后面我们学习到服务的时候 ,我们也会学到AIDL,这也是IPC的一种方式。
从上面的文章我们可以知道,它限制的大小为1M,这块其实是共享内存来的。也就是Blundle.详细请看我们的视频课程吧!
数据回传
这节课我们讲的是怎么把数据传到下一个界面 ,下一节课的话我们会学习如何在第一个界面让第二个界面返回结果。比如说我们做web的时候,充值跳转。
还是再解释一下吧,当我们跳转到另外一个界面了,需要把值返回来,这个时候就是数据回传了。
我不写了,还是看视频吧,嘻嘻!!!
视频后面更新,今天是12月1日,估计会在这周更新哦!
在线视频教程
https://www.sunofbeach.net/c/1443881236287311874