Activity通过setArguments传递到Fragment的Bundle数据是传引用还是传值?

编程入门 行业动态 更新时间:2024-10-23 17:39:43

Activity通过setArguments传递到Fragment的Bundle<a href=https://www.elefans.com/category/jswz/34/1771445.html style=数据是传引用还是传值?"/>

Activity通过setArguments传递到Fragment的Bundle数据是传引用还是传值?

在Android开发中,我们通过Intent/Bundle在组件之间(Activity/Services/ContentProvider/BroadcastReceivers)传递数据,由于组件之间通信方式是 IPC,因此只能通过数据流(byte[])的方式传递Bundle,所以目标组件所获取的数据是一个新对象,组件间传递的Bundle数据是传值。

那么,Activity通过setArguments传递到Fragment的Bundle数据是传引用还是传值?
答案是:
(1)绝大多数的情况下是传引用
由于Activity向Fragment发送参数并不是IPC过程,所以传递的Bundle数据是传引用,
Fragment从Bundle中获取到的对象与Activity所发送的对象就是同一对象。
(2)特殊情况下是传值
当内存不足等特殊情况下,Fragment在被销毁时将会以数据流(byte[])的方式保存Bundle,以便在Fragment重新恢复时重新创建Bundle,这种情况下,Activity向Fragment发送参数是传值。

传值场景

通常来说在页面之间传递数据有两种情况,Activity传递Activity、Fragment传递给Fragment。这两种情况都使用到了Bundle,只是使用的方式有一些差别。

传值方法
Activity To Activity:

Activity之间的调用需要通过Intent来实现,那么要传递的数据也需要封装到Bundle中,通过Intent传递到接收Activity中。例如如下代码:

SaveProject nTestObject = new SaveProject();  
Bundle nBundle = new Bundle();  
nBundle.putParcelable("PROJECT", nTestObject);  
nBundle.putString("NAME", nTestObject.toString());  
Intent nIteIntent = new Intent(FirstActivity.this, SecondActivity.class);  
nIteIntent.putExtras(nBundle);  
FirstActivity.this.startActivity(nIteIntent);  
Fragment To Fragment:

Fragment之间的调用就如同普通的类一样,直接调用构造方法来实例化Fragment对象即可。建议的传值方式是通过Bundle来传递,而不是直接作为构造参数传递。首先,官方建议在每个Fragment类中实现如下的构造方法:

public static SecondFragment getInstance(Bundle bundle) {  SecondFragment secondFragment = new SecondFragment();  secondFragment.setArguments(bundle);  return secondFragment;  
}

那么在需要调用某个Fragment时,执行类似如下代码:

SaveProject nTestObject = new SaveProject();  
Bundle nBundle = new Bundle();  
nBundle.putParcelable("PROJECT", nTestObject);  
nBundle.putString("NAME", nTestObject.toString());  
SecondFragment secondFragment = SecondFragment.getInstance(nBundle);  
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();  
transaction.replace(R.id.fragment_id, secondFragment);  
transactionmit();  

接收参数:

//在onActivityCreated(Bundle bundle)方法中
if(getArguments()!=null)
{tabid = getArguments().getInt("tabid");
}
差异现象

为了测试两种传输方式传递对象的方式是否相同,我分别通过Bundle传递了一个对象new SaveProject(),在接收到对象之后打印出传递前后对象的内存信息。参考以下打印内容不难发现,通过Intent传递的Bundle中包含的对象属于拷贝,即Activity_A中的对象通过Bundle传递给Activity_B,后者接收的对象与之前发送的对象不是同一个。而Fragment之间通过构造参数传递的Bundle中的对象传递的应该属于引用。

Activity:

12-10 16:32:47.953: D/bundle_test(14691): Activity_send = com.panda.bundledatatest.SaveProject@40fb3668
12-10 16:32:47.953: D/bundle_test(14691): ---------------------------
12-10 16:32:47.953: D/bundle_test(14691): Activity_get = com.panda.bundledatatest.SaveProject@40fbf180

12-10 16:33:20.935: D/bundle_test(14691): Fragment_send = com.panda.bundledatatest.SaveProject@40fd5e20
12-10 16:33:20.935: D/bundle_test(14691): ---------------------------
12-10 16:33:20.935: D/bundle_test(14691): Fragment_get = com.panda.bundledatatest.SaveProject@40fd5e20
差异分析

1、intent传递对象时,传递的是一个副本(深拷贝)。所以在android中,intent进行数据传递时,基本数据类型和对象传递的都是副本,改变传递过来的值,不会改变原来的值。

2、如果单纯的构造参数传值,Bundle的对象是相同的内存地址,也就是说接受者拿到的只是发送者的一个引用而已。

更多推荐

Activity通过setArguments传递到Fragment的Bundle数据是传引用还是传值?

本文发布于:2023-11-17 02:32:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1636311.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据   setArguments   Activity   Bundle   Fragment

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!