Implementação de Dados Parse no Android: Tutorial Técnico
24 min
tipos de dados do parse no android introdução neste guia, você aprenderá sobre os tipos de dados do parse usando android você irá ler e salvar os objetos parse no back4app a partir de um app android armazenar dados no parse é construído em torno do parseobject parseobject cada parseobject parseobject contém pares de chave valor de dados compatíveis com json esses dados são sem esquema, o que significa que não precisamos especificar antecipadamente quais chaves existem em cada parseobject parseobject podemos definir quaisquer pares de chave valor que quisermos, e nosso backend os armazenará por exemplo, digamos que estamos rastreando pontuações altas para um jogo um único parseobject parseobject poderia conter 1 pontuação 1337 , nomedojogador "sean plott" , modotrapaça falso as chaves devem ser strings alfanuméricas, e os valores podem ser string string => string string número número (valores numéricos primitivos como int int , double double ) bool bool => boolean boolean datetime datetime => java util date null null => jsonobject null array array =>jsonarray arquivo arquivo => parse file ponteiro ponteiro => outro parseobject relação relação => parserelation geoponto geoponto => parsegeopoint cada parseobject parseobject tem um nome de classe que podemos usar para distinguir diferentes tipos de dados por exemplo, poderíamos chamar o objeto de pontuação alta de gamescore gamescore também há alguns campos que não precisamos especificar que são fornecidos como conveniência objectid objectid é um identificador único para cada objeto salvo createdat createdat e updatedat updatedat representam o momento em que cada objeto foi criado e modificado pela última vez na nuvem cada um desses campos é preenchido automaticamente pelo back4app no momento em que salvamos um novo parseobject parseobject recomendamos que você nameyourclasseslikethis nameyourclasseslikethis (uppercamelcase) e nameyourkeyslikethis nameyourkeyslikethis (lowercamelcase), apenas para manter seu código bonito este tutorial usa um aplicativo básico criado no android studio 4 1 1 com buildtoolsversion=30 0 2 buildtoolsversion=30 0 2 , compile sdk version compile sdk version = 30 0 2 30 0 2 e targetsdkversion 30 targetsdkversion 30 a qualquer momento, você pode acessar o projeto completo através de nossos repositórios no github repositório de exemplo kotlin https //github com/templates back4app/android crud operations kotlin repositório de exemplo java https //github com/templates back4app/android crud operations java objetivo nosso objetivo é criar um aplicativo android que possa processar todos os tipos de dados fornecidos pelo parse server aqui está uma prévia do que vamos alcançar pré requisitos para completar este tutorial, precisamos android studio https //developer android com/studio/index html um aplicativo criado no back4app nota siga o tutorial de novo aplicativo parse https //www back4app com/docs/get started/new parse app para aprender como criar um aplicativo parse no back4app um aplicativo android conectado ao back4app nota siga o tutorial de instalação do sdk parse https //www back4app com/docs/android/parse android sdk para criar um projeto android studio conectado ao back4app um dispositivo (ou dispositivo virtual https //developer android com/studio/run/managing avds html ) rodando android 4 1 (jelly bean) ou mais recente entendendo nosso aplicativo você criará um aplicativo para uma melhor compreensão do parse tipos de dados tipos de dados neste android android aplicativo, você criará todos os tipos de dados em uma classe chamada datatypes datatypes e atribuirá valores às variáveis dessa classe em seguida, leremos e atualizaremos esses dados nota os tipos de dados ponteiro ponteiro , relação relação , arquivo arquivo , geoponto geoponto serão abordados mais tarde em guias específicos vamos começar! 1 criar modelo de aplicativo defina as seguintes variáveis na mainactivity mainactivity e substitua o código no método oncreate oncreate pelo seguinte código 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 } antes dos próximos passos, precisamos conectar back4app back4app ao nosso aplicativo você deve salvar o appid appid e clientkey clientkey do back4app back4app para o string xml string xml e então inicializar parse parse no nosso app java app java ou app kt app kt siga o novo tutorial de app parse https //www back4app com/docs/android/parse android sdk se você não souber como inicializar parse parse no seu aplicativo 2 código para salvar objeto a função create irá criar um novo objeto na base de dados do back4app definimos a savedatatypes savedatatypes função que chamamos na oncreate oncreate função e usamos o seguinte código nesta função iremos salvar todos os tipos de dados com esta função no objeto das classes 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 código para ler objeto nós vamos dar a objectid objectid variável que atribuímos na savedatatypes savedatatypes função como um parâmetro para a consulta e ler os dados que salvamos na savedatatypes savedatatypes função com a readobjects readobjects função 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 } nesta seção, criamos uma classe modelo chamada data data usamos os dados que obtemos na função readobjects readobjects para criar objetos a partir desta classe modelo damos esses objetos como elementos para a lista que criamos no tipo data data em seguida, passamos essa lista como um parâmetro para a função showdatatypes showdatatypes e a listamos no alertdialog alertdialog este é o data data modelo 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 } esta é a showdatatypes showdatatypes função 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 código para atualizar objeto a updateobject updateobject função é responsável por atualizar dados no objeto criado na savedatatypes savedatatypes função estamos usando objectid objectid novamente para atualizar o objeto 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 usando contadores o exemplo acima contém um caso de uso comum o intfield intfield campo pode ser um contador que precisaremos atualizar continuamente a solução acima funciona, mas é complicada e pode levar a problemas se tivermos vários clientes tentando atualizar o mesmo contador o parse fornece métodos que incrementam atomicamente qualquer campo numérico para ajudar a armazenar dados do tipo contador assim, a mesma atualização pode ser reescrita como 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 usando listas parse também fornece métodos para ajudar a armazenar dados de lista existem três operações que podem ser usadas para alterar um campo de lista atomicamente setadd setadd e setaddall setaddall anexa os objetos dados ao final de um campo de array setaddunique setaddunique e setaddallunique setaddallunique adiciona apenas os objetos dados que não estão contidos em um campo de array a esse campo a posição da inserção não é garantida remove remove e removeall removeall remove todas as instâncias dos objetos dados de um campo de array 6 1 exemplos com add e addall liststringfield liststringfield tem o valor \["a","b","c","d","e","f","g","g"] executando o código abaixo 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() após este comando, o resultado do campo stringlist será \["a","b","c","d","e","e","f","g","g"] 6 2 exemplos com addunique e addallunique liststringfield liststringfield tem o valor \["a","b","c","d","e"] executando o código abaixo 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() após este comando, o resultado do stringlist stringlist campo será \["a","b","c","d","e","f"] nenhum valor foi repetido 6 3 exemplos com removeall liststringfield liststringfield tem o valor \["a","b","c","d","e","f"] executando o código abaixo 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() após este comando, o resultado do stringlist stringlist campo será \["a","b"] nota que atualmente não é possível adicionar e remover itens de um array de forma atômica na mesma operação de salvamento teremos que chamar o salvamento para cada operação de array diferente que queremos realizar separadamente 7 remover um campo único do parseobject você pode deletar um único campo de um objeto usando a remove remove operação 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() está feito! neste ponto, aprendemos tipos de dados parse tipos de dados parse em android android