Android
Data objects
使用 Android 实现 Parse 数据类型解析、读取和保存
23 分
在android上解析数据类型 介绍 在本指南中,您将学习如何使用android解析数据类型。您将从android应用程序读取和保存back4app上的parse对象。 在parse上存储数据是围绕着 parseobject parseobject 每个 parseobject parseobject 包含json兼容数据的键值对。这些数据是无模式的,这意味着我们不需要提前指定每个 parseobject parseobject 上存在的键。我们可以设置我们想要的任何键值对,我们的后端将存储它们。例如,假设我们正在跟踪游戏的高分。一个单一的 parseobject parseobject 可能包含 1 分数 1337 , 玩家名称 "sean plott" , 作弊模式 false 键必须是字母数字字符串,值可以是: 字符串 字符串 => 字符串 字符串 数字 数字 (原始数值,例如 int int , double double ) 布尔值 布尔值 => boolean boolean 日期时间 日期时间 => java util date 空值 空值 => jsonobject null 数组 数组 =>jsonarray 文件 文件 => 解析文件 指针 指针 => 其他 parseobject 关系 关系 => parserelation 地理点 地理点 => parsegeopoint 每个 parseobject parseobject 都有一个类名,我们可以用它来区分不同类型的数据。例如,我们可以将高分对象称为 gamescore gamescore 。还有一些我们不需要指定的字段,它们作为便利提供 objectid objectid 是每个保存对象的唯一标识符。 createdat createdat 和 updatedat updatedat 表示每个对象在云中创建和最后修改的时间。 这些字段中的每一个在我们保存新的 parseobject parseobject 时由 back4app 自动填充。 我们建议您 nameyourclasseslikethis nameyourclasseslikethis (uppercamelcase) 和 nameyourkeyslikethis nameyourkeyslikethis (lowercamelcase),以保持您的代码美观。 本教程使用的是在 android studio 4 1 1 中创建的基本应用程序,使用 buildtoolsversion=30 0 2 buildtoolsversion=30 0 2 , compile sdk version compile sdk version = 30 0 2 30 0 2 和 targetsdkversion 30 targetsdkversion 30 您可以随时通过我们的 github 仓库访问完整的项目。 https //github com/templates back4app/android crud operations kotlin https //github com/templates back4app/android crud operations java 目标 我们的目标是创建一个可以处理 parse server 提供的所有数据类型的 android 应用程序。 以下是我们将要实现的内容的预览: 前提条件 要完成本教程,我们需要: https //developer android com/studio/index html 在 back4app 上创建的应用程序。 注意: 请遵循 https //www back4app com/docs/get started/new parse app 了解如何在 back4app 上创建 parse 应用程序。 一个连接到 back4app 的安卓应用程序。 注意: 请遵循 https //www back4app com/docs/android/parse android sdk 以创建一个连接到 back4app 的 android studio 项目。 一台运行 android 4 1(果冻豆)或更高版本的设备(或 https //developer android com/studio/run/managing avds html )。 了解我们的应用程序 您将创建一个应用程序,以更好地理解 parse 数据类型 数据类型 在这个 android android 应用程序中,您将创建一个名为 数据类型 数据类型 的类,并为该类的变量赋值。然后我们将读取和更新这些数据。 注意 数据类型 指针 指针 , 关系 关系 , 文件 文件 , 地理点 地理点 将在后面的具体指南中介绍。 让我们开始吧! 1 创建应用程序模板 在 mainactivity mainactivity 中定义以下变量,并用以下代码替换 oncreate oncreate 方法中的代码。 1 private progressdialog progressdialog; 2 private view popupinputdialogview; 3 private recyclerview recyclerview; 4 private string objectid; 5 private static final string tag = "mainactivity"; 6 7 @override 8 protected void oncreate(bundle savedinstancestate) { 9 super oncreate(savedinstancestate); 10 setcontentview(r layout activity main); 11 12 progressdialog = new progressdialog(mainactivity this); 13 14 button savedata = findviewbyid(r id savedata); 15 button readdata = findviewbyid(r id readdata); 16 button updatedata = findviewbyid(r id updatedata); 17 18 savedata setonclicklistener(savedataview > { 19 try { 20 savedatatypes(); 21 } catch (jsonexception e) { 22 e printstacktrace(); 23 } 24 }); 25 26 readdata setonclicklistener(readdataview > readobjects()); 27 28 updatedata setonclicklistener(updatedataview > updateobject()); 29 30 }1 private var progressdialog progressdialog? = null 2 private var objectid string? = null 3 private var popupinputdialogview view? = null 4 private var recyclerview recyclerview? = null 5 private val tag = "mainactivity" 6 7 override fun oncreate(savedinstancestate bundle?) { 8 super oncreate(savedinstancestate) 9 setcontentview(r layout activity main) 10 11 progressdialog = progressdialog(this\@mainactivity) 12 val savedata = findviewbyid\<button>(r id savedata) 13 val readdata = findviewbyid\<button>(r id readdata) 14 val updatedata = findviewbyid\<button>(r id updatedata) 15 16 savedata setonclicklistener { 17 try { 18 savedatatypes() 19 } catch (e jsonexception) { 20 e printstacktrace() 21 } 22 } 23 readdata setonclicklistener { readobjects() } 24 updatedata setonclicklistener { updateobject() } 25 } 在下一步之前,我们需要将 back4app back4app 连接到我们的应用程序。您应该保存 appid appid 和 clientkey clientkey 从 back4app back4app 到 string xml string xml 文件,然后在我们的 app java app java 或 app kt app kt 文件中初始化 parse parse 。 如果您不知道如何将 parse parse 初始化到您的应用程序中,请遵循 https //www back4app com/docs/android/parse android sdk 2 保存对象的代码 create 函数将在 back4app 数据库中创建一个新对象。我们定义了一个 savedatatypes savedatatypes 函数,我们在 oncreate oncreate 函数中调用它,并在此函数中使用以下代码。我们将使用此函数将所有数据类型保存到 datatypes 类对象中。 1 private void savedatatypes() throws jsonexception{ 2 parseobject parseobject = new parseobject("datatypes"); 3 4 parseobject put("stringfield", "string"); 5 parseobject put("doublefield", 1 5); 6 parseobject put("intfield", 2); 7 parseobject put("boolfield", true); 8 parseobject put("datefield", calendar getinstance() gettime()); 9 10 jsonobject myobject = new jsonobject(); 11 myobject put("number", 1); 12 myobject put("string", "42"); 13 14 parseobject put("jsonobject", myobject); 15 16 17 jsonarray myarray = new jsonarray(); 18 myarray put(myobject); 19 myarray put(myobject); 20 myarray put(myobject); 21 22 parseobject put("jsonarray", myarray); 23 24 25 list\<string> list = new arraylist<>(); 26 list add("string1"); 27 list add("string2"); 28 parseobject put("liststringfield", list); 29 30 list\<integer> listint = new arraylist<>(); 31 listint add(1); 32 listint add(2); 33 listint add(3); 34 parseobject put("listintfield", listint); 35 36 list\<boolean> listbool = new arraylist<>(); 37 listbool add(true); 38 listbool add(false); 39 parseobject put("listboolfield", listbool); 40 41 progressdialog show(); 42 parseobject saveinbackground(e > { 43 progressdialog dismiss(); 44 if (e == null) { 45 toast maketext(this, "object created successfully ", toast length short) show(); 46 objectid = parseobject getobjectid(); 47 } else { 48 objectid = null; 49 toast maketext(this, e getmessage(), toast length long) show(); 50 } 51 }); 52 }1 private fun savedatatypes() { 2 val parseobject = parseobject("datatypes") 3 4 parseobject put("stringfield", "string") 5 parseobject put("doublefield", 1 5) 6 parseobject put("intfield", 2) 7 parseobject put("boolfield", true) 8 parseobject put("datefield", calendar getinstance() time) 9 10 11 val myobject = jsonobject() 12 myobject put("number", 1) 13 myobject put("string", "42") 14 15 parseobject put("jsonobject", myobject) 16 17 val myarray = jsonarray() 18 myarray put(myobject) 19 myarray put(myobject) 20 myarray put(myobject) 21 22 parseobject put("jsonarray", myarray) 23 24 val list mutablelist\<string> = arraylist() 25 list add("string1") 26 list add("string2") 27 parseobject put("liststringfield", list) 28 29 val listint mutablelist\<int> = arraylist() 30 listint add(1) 31 listint add(2) 32 listint add(3) 33 parseobject put("listintfield", listint) 34 35 val listbool mutablelist\<boolean> = arraylist() 36 listbool add(true) 37 listbool add(false) 38 parseobject put("listboolfield", listbool) 39 40 progressdialog? show() 41 parseobject saveinbackground { 42 progressdialog? dismiss() 43 if (it == null) { 44 toast maketext(this, "object created successfully ", toast length short) show() 45 objectid = parseobject objectid 46 } else { 47 objectid = null 48 toast maketext(this, it message, toast length long) show() 49 } 50 } 51 } 3 读取对象的代码 我们将把在 objectid objectid 变量中赋值的 savedatatypes savedatatypes 函数作为参数传递给查询,并读取我们在 savedatatypes savedatatypes 函数中保存的数据,使用 readobjects readobjects 函数 1 private void readobjects() { 2 if (objectid == null) { 3 toast maketext(this, "no object click on the 'save data' button before ", toast length short) show(); 4 return; 5 } 6 7 parsequery\<parseobject> query = new parsequery<>("datatypes"); 8 9 progressdialog show(); 10 query getinbackground(objectid, (object, e) > { 11 progressdialog dismiss(); 12 if (e == null) { 13 list\<data> list = new arraylist<>(); 14 list add(new data("int list field",object get("listintfield") tostring())); 15 list add(new data("string field",object get("stringfield") tostring())); 16 list add(new data("double field",object get("doublefield") tostring())); 17 list add(new data("int field",object get("intfield") tostring())); 18 list add(new data("string list field",object get("liststringfield") tostring())); 19 list add(new data("date field",object get("datefield") tostring())); 20 list add(new data("bool field",object get("boolfield") tostring())); 21 list add(new data("list bool field",object get("listboolfield") tostring())); 22 list add(new data("json object field",object get("jsonobject") tostring())); 23 list add(new data("json array field",object get("jsonarray") tostring())); 24 25 showdatatypes(list); 26 27 } else { 28 toast maketext(this, e getmessage(), toast length short) show(); 29 } 30 }); 31 }1 private fun readobjects() { 2 if (objectid == null) { 3 toast maketext( 4 this, 5 "no object click on the 'save data' button before ", 6 toast length short 7 ) show() 8 return 9 } 10 11 val query = parsequery\<parseobject>("datatypes") 12 13 14 progressdialog? show() 15 query getinbackground( 16 objectid 17 ) { obj, e > 18 progressdialog? dismiss() 19 if (e == null) { 20 21 val list mutablelist\<data> = arraylist() 22 list add(data("int list field", obj get("listintfield") tostring())) 23 list add(data("string field",obj get("stringfield") tostring())) 24 list add(data("double field", obj get("doublefield") tostring())) 25 list add(data("int field", obj get("intfield") tostring())) 26 list add(data("string list field", obj get("liststringfield") tostring())) 27 list add(data("date field",obj get("datefield") tostring())) 28 list add(data("bool field", obj get("boolfield") tostring())) 29 list add(data("list bool field", obj get("listboolfield") tostring())) 30 list add(data("json object field", obj get("jsonobject") tostring())) 31 list add(data("json array field", obj get("jsonarray") tostring())) 32 showdatatypes(list) 33 } else { 34 toast maketext(this, e message, toast length short) show() 35 } 36 37 } 38 } 在本节中,我们创建了一个名为 数据 数据 的模型类。我们使用在 readobjects readobjects 函数中获取的数据来创建该模型类的对象。我们将这些对象作为元素提供给我们在 数据 数据 类型中创建的列表。然后,我们将这个列表作为参数传递给 showdatatypes showdatatypes 函数,并在 alertdialog alertdialog 中列出它。 这是 数据 数据 模型。 1 public class data { 2 private string type; 3 private string value; 4 5 public data(string type, string value) { 6 this type = type; 7 this value = value; 8 } 9 10 public string gettype() { 11 return type; 12 } 13 14 public data settype(string type) { 15 this type = type; 16 return this; 17 } 18 19 public string getvalue() { 20 return value; 21 } 22 23 public data setvalue(string value) { 24 this value = value; 25 return this; 26 } 27 }1 class data(val type\ string?=null,val value\ string?=null) { 2 3 } 这是 showdatatypes showdatatypes 函数。 1 private void showdatatypes(list\<data> list){ 2 alertdialog builder alertdialogbuilder = new alertdialog builder(mainactivity this); 3 alertdialogbuilder settitle("data types"); 4 alertdialogbuilder setcancelable(true); 5 initpopupviewcontrols(list); 6 //we are setting our custom popup view by alertdialog builder 7 alertdialogbuilder setview(popupinputdialogview); 8 final alertdialog alertdialog = alertdialogbuilder create(); 9 alertdialog show(); 10 } 11 12 private void initpopupviewcontrols(list\<data> list) { 13 layoutinflater layoutinflater = layoutinflater from(mainactivity this); 14 popupinputdialogview = layoutinflater inflate(r layout custom alert dialog, null); 15 recyclerview = popupinputdialogview\ findviewbyid(r id recyclerview); 16 itemadapter adapter = new itemadapter(list,this); 17 recyclerview\ setlayoutmanager(new linearlayoutmanager(this,linearlayoutmanager vertical,false)); 18 recyclerview\ setadapter(adapter); 19 }1 private fun showdatatypes(list list\<data>) { 2 val alertdialogbuilder = alertdialog builder(this\@mainactivity) 3 alertdialogbuilder settitle("data types") 4 alertdialogbuilder setcancelable(true) 5 initpopupviewcontrols(list) 6 //we are setting our custom popup view by alertdialog builder 7 alertdialogbuilder setview(popupinputdialogview) 8 val alertdialog = alertdialogbuilder create() 9 alertdialog show() 10 } 11 12 @suppresslint("inflateparams") 13 private fun initpopupviewcontrols(list list\<data>) { 14 val layoutinflater = layoutinflater from(this\@mainactivity) 15 popupinputdialogview = layoutinflater inflate(r layout custom alert dialog, null) 16 recyclerview = popupinputdialogview? findviewbyid(r id recyclerview) 17 val adapter = itemadapter(this\@mainactivity, list) 18 recyclerview? layoutmanager = linearlayoutmanager( 19 this, 20 linearlayoutmanager vertical, 21 false 22 ) 23 recyclerview? adapter = adapter 24 } 4 更新对象的代码 该 updateobject updateobject 函数负责更新在 savedatatypes savedatatypes 函数中创建的对象中的数据。我们再次使用 objectid objectid 来更新对象。 1 public void updateobject() { 2 if (objectid == null) { 3 toast maketext(this, "no object click on the 'save data' button before ", toast length short) show(); 4 return; 5 } 6 7 parseobject parseobject = new parseobject("datatypes"); 8 parseobject setobjectid(objectid); 9 parseobject put("intfield", 5); 10 parseobject put("stringfield", "new string"); 11 12 progressdialog show(); 13 14 parseobject saveinbackground(e > { 15 progressdialog dismiss(); 16 if (e == null) { 17 toast maketext(this, "object updated successfully ", toast length short) show(); 18 } else { 19 toast maketext(this, e getmessage(), toast length short) show(); 20 } 21 }); 22 }1 private fun updateobject() { 2 if (objectid == null) { 3 toast maketext( 4 this, 5 "no object click on the 'save data' button before ", 6 toast length short 7 ) show() 8 return 9 } 10 11 val parseobject = parseobject("datatypes") 12 parseobject objectid = objectid 13 parseobject put("intfield", 5) 14 parseobject put("stringfield", "new string") 15 16 progressdialog? show() 17 18 parseobject saveinbackground { 19 progressdialog? dismiss() 20 if (it == null) { 21 toast maketext(this, "object updated successfully ", toast length short) show() 22 } else { 23 toast maketext(this, it message, toast length short) show() 24 } 25 } 26 } 5 使用计数器 上述示例包含一个常见的用例。该 intfield intfield 字段可以是一个我们需要不断更新的计数器。上述解决方案有效,但它繁琐,并且如果我们有多个客户端尝试更新同一个计数器,可能会导致问题。parse 提供了原子性地递增任何数字字段的方法,以帮助存储计数器类型的数据。因此,相同的更新可以重写为: 1 parseobject parseobject = new parseobject("datatypes"); 2 parseobject setobjectid(objectid); 3 parseobject increment("intfield",1);1 val parseobject = parseobject("datatypes") 2 parseobject objectid = objectid 3 parseobject increment("intfield",1) 6 使用列表 parse 还提供了帮助存储列表数据的方法。可以使用三种操作原子性地更改列表字段: setadd setadd 和 setaddall setaddall 将给定对象附加到数组字段的末尾。 setaddunique setaddunique 和 setaddallunique setaddallunique 仅将不在数组字段中的给定对象添加到该字段。插入的位置不保证。 remove remove 和 removeall removeall 从数组字段中移除给定对象的所有实例。 6 1 使用 add 和 addall 的示例 liststringfield liststringfield 的值为 \["a","b","c","d","e","f","g","g"] 运行以下代码 1 parseobject parseobject = new parseobject("datatypes"); 2 parseobject setobjectid(objectid); 3 parseobject add("liststringfield","e"); 4 parseobject addall("liststringfield", arrays aslist("e", "f", "g", "g")); 5 parseobject save();1 val parseobject = parseobject("datatypes") 2 parseobject objectid = objectid 3 parseobject add("liststringfield", "e") 4 parseobject addall("liststringfield", arrays aslist("e", "f", "g", "g")) 5 parseobject save() 在此命令之后,stringlist 字段的结果将是 \["a","b","c","d","e","e","f","g","g"] 6 2 使用 addunique 和 addallunique 的示例 liststringfield liststringfield 的值为 \["a","b","c","d","e"] 运行以下代码 1 parseobject parseobject = new parseobject("datatypes"); 2 parseobject setobjectid(objectid); 3 parseobject addunique("liststringfield","e"); 4 parseobject addallunique("liststringfield",arrays aslist("c", "d", "e", "f")); 5 parseobject save();1 val parseobject = parseobject("datatypes") 2 parseobject objectid = objectid 3 parseobject addunique("liststringfield", "e") 4 parseobject addallunique("liststringfield", arrays aslist("c", "d", "e", "f")) 5 parseobject save() 在此命令之后, stringlist stringlist 字段的结果将是 \["a","b","c","d","e","f"] 没有值被重复 6 3 使用 removeall 的示例 liststringfield liststringfield 的值是 \["a","b","c","d","e","f"] 运行以下代码 1 parseobject parseobject = new parseobject("datatypes"); 2 parseobject setobjectid(objectid); 3 parseobject removeall("liststringfield",arrays aslist("c", "d", "e", "f")); 4 parseobject save();1 val parseobject = parseobject("datatypes") 2 parseobject objectid = objectid 3 parseobject removeall("liststringfield", arrays aslist("c", "d", "e", "f")) 4 parseobject save() 在此命令之后, stringlist stringlist 字段的结果将是 \["a","b"] 注意 目前无法在同一次保存中原子性地添加和删除数组中的项目。我们必须为每个不同的数组操作单独调用保存。 7 从parseobject中删除单个字段 您可以通过使用 remove remove 操作来删除对象中的单个字段 1 parseobject parseobject = new parseobject("datatypes"); 2 parseobject remove("stringfield"); 3 parseobject save();1 val parseobject = parseobject("datatypes") 2 parseobject remove("stringfield") 3 parseobject save() 完成! 在这一点上,我们已经学习了 parse 数据类型 parse 数据类型 在 android android