Então, seguinte
Tenho um método que faz o retorno dos dados que eu quero. Até aí, ele está retornando sim, mas eu preciso levar esses dados para outros lugares, para usar externo e da maneira como estou fazendo, não estou conseguindo. Alguém pode me ajudar a encontrar uma forma de escrever esse código para que eu possa levar os dados para outros lugares do projeto, que não sejam dentro desse método?
Basicamente, eu gostaria que o método deixasse de ser void e retornasse String, por exemplo
Eu sei que desta maneira que está escrita não dá, mas queria saber como posso fazer isso
Observação:
Essa função print é apenas um System.out.println. E o result.getString("name") está funcionando, é essa informação que eu quero fazer o método retornar.
publicList<String>onResponse(Callcall,Responseresponse)throwsIOException{try{if(response!=null){List<String>names=newArrayList<>();//Lista de namesStringjson=response.body().string();JSONObjectjsonObject=newJSONObject(json);JSONArrayjsonArray=jsonObject.getJSONArray("routes");for(inti=0;i<jsonArray.length();i++){JSONObjectresult=jsonArray.getJSONObject(i);list.add(result.getString("name"));}returnnames;}}catch(Exceptione){thrownewException(e);}}
C
Chaybelucas
Não posso, porque o método onResponse vem do Callback… Não posso alterá-lo
J
Jonathan_Medeiros
Não tinha me atentado nisso, e se caso você criar a lista externamente ao callback, declaração a nível de classe e só utilizá-la dentro do callback para recuperar os nomes ?
C
Chaybelucas
Cara, fui tentar isso, mas não funcionou.
Botei pra debugar, mostrou o ArrayList sendo preenchido, mas quando eu chamei ele, via método e atribuí a outro ArrayList, ele não exibiu nada.
J
Jonathan_Medeiros
Como você está fazendo o retorno da lista dentro do método ?
C
Chaybelucas
// no inicio da classe eu instancio o ListList<String>strLista=newArrayList<>();...publicList<String>getURLFrom(Stringurl)throwsException{//Requestrequest=newRequest.Builder().url(url).build();//okHttpClient.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(Callcall,IOExceptione){}@OverridepublicvoidonResponse(Callcall,Responseresponse)throwsIOException{try{if(response!=null){Stringjson=response.body().string();JSONObjectjsonObject=newJSONObject(json);JSONArrayresults=jsonObject.getJSONArray("results");//Bundlebundle=newBundle();for(inti=0;i<results.length();i++){JSONObjectroutes=results.getJSONObject(i);// no debug aparece a lista sendo preenchidastrLista.add(""+routes.getString("name"));// o print sai normalprint(" RESULTADO DO FOR [ "+i+" ]"+routes.getString("name"));}}}catch(Exceptione){e.printStackTrace();}}});returnstrLista;}
Mas me disseram que não vai funcionar assim. Resolvi tentar, de fato, ele nunca traz nada…
// o método fica dentro de uma classe chamada FrmDadosList<String>strLista=newArrayList<>();strLista=frmDados.getURLFrom(mUrl);// quando boto pra exibir, ele não traz nada. Nada mesmo, nem chega a exibir textofor(inti=0;i<strLista.size();i++){frmDados.print("Resultado da bagaça >>>>>>> "+strLista.get(i));}// nem o texto "Resultado da bagaça" não é exibido. Nada mesmo.
J
Jonathan_Medeiros1 like
Realmente é cabuloso o negócio
Cara, não consigo nem imaginar o que pode estar acontecendo.
C
Solucao aceita
Chaybelucas1 like
Resolvi assim…
Me rendi basicamente. Coloquei o método direto na classe que eu ia usá-lo. Separei o método em um Callback e fiz o método ali.
Chamei o runOnUiThread e nele eu adicionei o List (opcoes) no meu Adapter (adaptador) com o addAll. Em seguida, notifyDataSetChanged para a ListView saber que alterei algo
O que você quer é transformar um método assíncrono em um método síncrono. Uma forma de fazer isso é utilizar a classe CompletableFuture. Com essa classe você consegue fazer uma dataflow variable, um conceito de programação concorrente declarativa.
Em resumo, a ideia é que você vai bloquear a thread que está invocando o procedimento até que o callback seja chamado pelo método assíncrono. Esse callback vai entregar o resultado assíncrono à variável de fluxo, permitindo então que a thread principal seja liberada e o programa continue.
Tem um livro chamado Java Concurrency in Practice. Lá você vai aprender um monte de conceitos de programação concorrente usando Java, inclusive esse aqui que estamos discutindo. Vou deixar aqui um exemplo para você adaptar para o seu caso. Leia a documentação das classes para entender como funciona, e qualquer coisa pergunte.
importjava.util.function.Consumer;importjava.util.concurrent.*;publicclassProgram{// Esse método é o assíncrono, ele vai executar um procedimento em background e chamar o seu callback quando terminar.staticvoiddoSomethingAsync(Consumer<String>callback){newThread(()->{try{for(inti=0;i<5;i++){System.out.println(".");Thread.sleep(1000);}callback.accept("Magic Value");}catch(Exceptione){}}).start();}// Esse é o método que transforma o assíncrono em síncrono. Repare como o callback simplesmente repassa o resultado que recebeu para o synchronizer, e no return onde a thread principal fica travada até o .get() retornar.staticStringdoSomethingSync()throwsException{CompletableFuture<String>synchronizer=newCompletableFuture<>();doSomethingAsync((result)->{synchronizer.complete(result);});returnsynchronizer.get();}publicstaticvoidmain(String[]args)throwsException{Stringresult=doSomethingSync();System.out.println(result);}}
C
Chaybelucas
Pois é… Me falaram algo sobre Future. Mas eu REALMENTE não tenho conhecimento nenhum sobre isso… Obrigado pelo exemplo, com certeza vou pesquisar sobre isso! Muito obrigado mesmo!