建设工程招聘网,网站建设 优化,无忧网站建设推荐,请解释网站开发的主要流程Activity之间传递可序列化的数据
Android应用开发会常常处理数据的序列化和传递。在Android中往往采用两种方式实现数据的可序列化#xff1a;#xff08;1#xff09;实现java.io.Serializable接口#xff08;2#xff09;实现android.os.Parcelable接口。 将类定义为an…Activity之间传递可序列化的数据
Android应用开发会常常处理数据的序列化和传递。在Android中往往采用两种方式实现数据的可序列化1实现java.io.Serializable接口2实现android.os.Parcelable接口。 将类定义为android.os.Parcelable接口的方式实际上是利用Parcel提供了一套机制将一个完整的对象进行分解而分解后的每一部分的数据都属于Intent支持的数据类型。可以将分解后的可序列化的数据写入到一个共享内存中其他进程通过Parcel可以从这块共享内存中读出字节流并反序列化成对象通过这种方式来实现传递对象的功能。因为这种数据传递方式效率更高成为Android进行可序列化传递数据的主要方式。 现在有一个简单实例就是从主活动MainActivity发送分别发送不同类型数据对象给两个不同的活动例如将Student类型的数据对象发送给FirstActivity和将Teacher类型的数据对象发送给SecondActivity. 运行效果如下图所示
一、定义实现Parcelable数据类
1.Student类
data class Student(val id:String,val name:String,val gender:String,val className:String):Parcelable{constructor(parcel: Parcel) : this(parcel.readString()!!,parcel.readString()!!,parcel.readString()!!,parcel.readString()!!)override fun describeContents(): Int0override fun writeToParcel(dest: Parcel, flags: Int) {dest.writeString(id)dest.writeString(name)dest.writeString(gender)dest.writeString(className)}companion object CREATOR : Parcelable.CreatorStudent {override fun createFromParcel(parcel: Parcel): Student {return Student(parcel)}override fun newArray(size: Int): ArrayStudent? {return arrayOfNulls(size)}}
}2.结合kotlin-parcelize插件简化数据类的定义
上述可序列化的数据类的定义形式非常复杂可以结合kotlin-parcelize插件简化数据类的定义。要使用kotlin-parcelize插件需要在模块对应的build.gradle.kts中增加kotlin-parcelize插件的处理 plugins { … id (“kotlin-parcelize”) } 同步配置后修改上述的Student类和Teacher类为如下形式 Student类修改为
Parcelize
data class Student(val id:String,val name:String,val gender:String,val className:String):Parcelable定义的Teacher类形式如下
Parcelize
data class Teacher(val id:String,val name:String,val gender:String):Parcelable二、结合JetPack Compose组件定义界面
1.定义MainActivity及其对应的界面
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MainScreen()}}
}Composable
fun MainScreen(modifier: Modifier Modifier) {val context LocalContext.currentBox(contentAlignment Alignment.Center){Column(horizontalAlignment Alignment.CenterHorizontally){Button(modifier Modifier.width(200.dp),onClick{val intent Intent(context,FirstActivity::class.java)intent.putExtra(data,Student(20234454,张三,男,计算机2231班))context.startActivity(intent)}){Text(text FirstActivity,fontSize 18.sp)Icon(imageVectorIcons.Filled.ArrowForward,contentDescription 第一个活动)}Button(modifier Modifier.width(200.dp),onClick{val intent Intent(context,SecondActivity::class.java)intent.putExtra(data,Teacher(20234458,李四,男))context.startActivity(intent)}){Text(text SecondActivity,fontSize 18.sp)Icon(imageVectorIcons.Filled.ArrowForward,contentDescription 第二个活动)}}}
}在MainActivity中通过两个按钮发送数据给不同的活动发送的数据对象所属的类各不相同。
2.以传统的方式接受传递的数据
传统的方式就是通过具体指定类型来接受指定类型的数据。 以FirstActivity接受数据为例
class FirstActivity : ComponentActivity() {RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{FirstScreen()}}
}RequiresApi(Build.VERSION_CODES.TIRAMISU)
Composable
fun FirstScreen(){val context LocalContext.current as Activityval receivedData context.intent.getParcelableExtra(data,Student::class.java)Box(modifier Modifier.fillMaxSize().background(Color.Green),contentAlignment Alignment.Center){Text( text 第一个界面,接受数据是${receivedData},fontSize30.sp,color Color.Yellow)}
}以SecondActivity为例
class SecondActivity : ComponentActivity() {RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SecondScreen()}}
}RequiresApi(Build.VERSION_CODES.TIRAMISU)
Composable
fun SecondScreen(){val context LocalContext.current as Activityval receivedData context.intent.getParcelableExtra(data,Teacher::class.java)Box(modifier Modifier.fillMaxSize().background(Color.Green),contentAlignment Alignment.Center){Text( text 第二个界面,接受数据是${receivedData},fontSize30.sp,color Color.Yellow)}
}观察上述两个活动对应的界面可以发现它们主要是处理1前后景颜色不同2接受传递的数据类型不同3显示文本的内容不同。其他的具体操作非常类似。因此考虑简化代码定义一个通用的界面函数。
3.定义通用界面简化处理
定义通用的界面组合函数SubScreen如下:
RequiresApi(Build.VERSION_CODES.TIRAMISU)
Composable
fun T:Parcelable SubScreen(title:String,preColor:Color,backgroundColor:Color,receivedDataType:ClassT){val context LocalContext.current as Activityval data context.intent.getParcelableExtra(data,receivedDataType)Box(modifier Modifier.fillMaxSize().background(backgroundColor),contentAlignment Alignment.Center){Text( text $title,接受数据是${data},fontSize30.sp,color preColor)}
}将两个界面不同的内容1前后景颜色不同2接受传递的数据类型不同以参数的方式进行传递。 在上述代码中T表示实现接口Parcelable的类型参数然后指定接受数据的类型参数receivedDataType设置为通用的表示Class。经过这样的处理在接受数据时就达到了不管发送方发送的数据对象所属类型到底是什么类型只要它实现了android.os.Parcelable接口就可以直接接受这样类型的对象实例。 val context LocalContext.current as Activity val data context.intent.getParcelableExtra(“data”,receivedDataType) 通过这样的处理代码会更简单。
4.不同活动调用通用界面
重新修改FirstActivity调用SubScreen函数定义界面代码如下
class FirstActivity : ComponentActivity() {RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SubScreen(title 第一个界面, backgroundColorColor.Green,preColor Color.Yellow, receivedDataType Student::class.java)}}
}重新修改SecondActivity,调用SubScreen函数定义界面代码如下
class SecondActivity : ComponentActivity() {RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SubScreen(title 第二个界面, backgroundColor Color.Blue,preColor Color.Yellow, receivedDataType Teacher::class.java)}}
}参考文献
**陈轶《Android移动应用开发微课版》[M] 北京清华大学出版社 2022