>

Fórum

Fórum da RL System, voltado para analistas, programadores etc. Tudo sobre linguagem de programação e desenvolvimento Full Stack: Banco de Dados, Android, C#, Java, .NET, PHP, Node, Javascript, TypeScript, Front, HTML e muito mais.



Como carregar listview dentro de uma Thread


Srs. Estou iniciando na programação em android e me deparei com o problema de carregar um ListView que está sendo passado o objeto do tipo List dentro de uma Thread. Bem, estou acompanhando as aulas do professor Rafael no curso dominando a API do android e me deparei com esse problema por que estou utilizando o android 4.3 e como já deve ser do conhecimento de vocês, na versão 4.3 existe um bloqueio que é justamente não permitir que acessos a redes seja dentro da Thread principal e por isso que implementei a classe Runnable na Classe Listar, mas, quando vou carregar a listview ocorre o seguinte erro:

05-05 21:59:01.690: E/AndroidRuntime(980): FATAL EXCEPTION: Thread-87
05-05 21:59:01.690: E/AndroidRuntime(980): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-05 21:59:01.690: E/AndroidRuntime(980): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:869)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4253)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.view.View.invalidate(View.java:10539)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.view.View.invalidate(View.java:10494)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.widget.AbsListView.resetList(AbsListView.java:1858)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.widget.ListView.resetList(ListView.java:505)
05-05 21:59:01.690: E/AndroidRuntime(980): at android.widget.ListView.setAdapter(ListView.java:445)
05-05 21:59:01.690: E/AndroidRuntime(980): at com.br.pdsn.cadastrodeclientes.Listar.run(Listar.java:238)
05-05 21:59:01.690: E/AndroidRuntime(980): at java.lang.Thread.run(Thread.java:841)

Abaixo está o código.


@Override
public void run() {
// TODO Auto-generated method stub
//Cria a url com os valores dos parametos dinamicamente
StringBuilder strUrl = new StringBuilder();
//strUrl.append("http://localhost/Clientes/inserir.php?nome=");
strUrl.append("http://172.25.4.64/clientes/listar.php");

try {
URL url = new URL(strUrl.toString());
HttpURLConnection http = (HttpURLConnection) url.openConnection();
InputStreamReader isr = new InputStreamReader( http.getInputStream() );
BufferedReader bf = new BufferedReader(isr);

List lista = new ArrayList();
String linhaRetorno = "";

while( (linhaRetorno = bf.readLine()) != null )
{
lista.add( linhaRetorno.split("\|")[0] );
}

ArrayAdapter ad = new ArrayAdapter(getBaseContext(), android.R.layout.simple_list_item_1, lista);
ltw.setAdapter(ad);

} catch (IOException e) {
// Código retirado devido a não ser uma coisa boa colocar parte gráfica dentro de threads
//Log.e("Erro: ", e.getMessage());
//e.printStackTrace();
//Toast.makeText(getBaseContext(), "Erro: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}


Alguém já passou por essa situação?
Alguém tem idéia de como eu resolvo isso.

Desde já agradeço.



2 Respostas


Srs. Poucos minutos após eu postar a dúvida acima, encontrei na net uma dica mencionada pelo Professor Rafael, que é referente a manipulação de objetos views dentro de Thread. Em uma Thread, não podemos alterar views, então, para resolver isso é só utiliza uma handler e manipular as views dentro da Handler.

Fica ai a dica para se no futuro alguém se deparar com essa dúvida.

Um abraço a todos.


@Override
public void run() {
// TODO Auto-generated method stub
//Cria a url com os valores dos parametos dinamicamente
StringBuilder strUrl = new StringBuilder();
//strUrl.append("http://localhost/Clientes/inserir.php?nome=");
strUrl.append("http://172.25.4.64/clientes/listar.php");

try {
URL url = new URL(strUrl.toString());
HttpURLConnection http = (HttpURLConnection) url.openConnection();
InputStreamReader isr = new InputStreamReader( http.getInputStream() );
BufferedReader bf = new BufferedReader(isr);

lista2 = new ArrayList();
String linhaRetorno = "";

while( (linhaRetorno = bf.readLine()) != null )
{
lista2.add( linhaRetorno.split("\\|")[0] );
}

//Como estamos dentro de uma thread, nenhuma manipulação de views pode acontecer dentro de uma thread. Para resolver isso
//é preciso criar um handler e ai sim manipular as views.
ad = new ArrayAdapter(getBaseContext(), android.R.layout.simple_list_item_1, lista2);
//ltw.setAdapter(ad);
handler.sendEmptyMessage(0);

} catch (IOException e) {
// Código retirado devido a não ser uma coisa boa colocar parte gráfica dentro de threads
//Log.e("Erro: ", e.getMessage());
//e.printStackTrace();
//Toast.makeText(getBaseContext(), "Erro: " e.getMessage(), Toast.LENGTH_SHORT).show();
}
}

private Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg) {
if ( msg.what == 0 )
{
ltw.setAdapter(ad);
}
else if ( msg.what == 1 )
{

Toast.makeText(getBaseContext(), "erro ao consultar no servidor. Tente novamente", Toast.LENGTH_SHORT).show();
}

}
};




Olá

Pedro

No curso de Android Best Practices, aqui na RL System, o Rafael também fala de Threads.