Eu sou novo no Android e estou tentando usar o UI-Thread, então escrevi uma atividade de teste simples. Mas acho que entendi errado algo, porque ao clicar no botão - o aplicativo não responde mais
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
Apenas envolva-o como uma função e chame-a de seu thread em segundo plano.
fonte
final
)Você tem de trás para frente. O clique no botão resulta em uma chamada para
runOnUiThread()
, mas isso não é necessário, pois o manipulador de cliques já está em execução no thread da interface do usuário. Em seguida, seu códigorunOnUiThread()
está iniciando um novo encadeamento em segundo plano, no qual você tenta executar operações da interface do usuário, que falham.Em vez disso, basta iniciar o thread em segundo plano diretamente do seu manipulador de cliques. Em seguida, envolva as chamadas para
btn.setText()
dentro de uma chamada pararunOnUiThread()
.fonte
runOnUiThread()
é desnecessária, mas deve ser inofensiva. O Javadoc para esse método diz "Executa a ação especificada no encadeamento da interface do usuário. Se o encadeamento atual for o encadeamento da interface do usuário, a ação será executada imediatamente. Se o encadeamento atual não for o encadeamento da interface do usuário, a ação será postada na fila de eventos do thread da interface do usuário ".fonte
Existem várias técnicas usando runOnUiThread (), vamos ver todas
Este é o meu thread principal (thread da interface do usuário) chamado AndroidBasicThreadActivity e vou atualizá-lo de um thread de trabalho de várias maneiras -
1.) Ao passar a instância de Activity como um argumento no thread de trabalho
2.) Usando o método de publicação da View (Runnable runnable) no thread de trabalho
3.) Usando a classe Handler do pacote android.os Se não temos o contexto (this / getApplicationContext ()) ou a instância da Activity (AndroidBasicThreadActivity.this), precisamos usar a classe Handler da seguinte forma:
fonte
Se estiver usando um fragmento, basta escrever
fonte
teu isto:
fonte
Usamos Worker Thread para tornar os aplicativos mais suaves e evitar ANRs. Talvez seja necessário atualizar a interface do usuário após o processo pesado no trabalho do Tread. A interface do usuário só pode ser atualizada no Thread da interface do usuário. Nesses casos, usamos Handler ou runOnUiThread, ambos possuem um método Runnable run que é executado no UI Thread. O método onClick é executado no thread da interface do usuário, portanto, não é necessário usar o runOnUiThread aqui.
Usando o Kotlin
Enquanto em atividade,
De Fragment,
Usando Java ,
fonte
Você pode usar a partir desta amostra:
No exemplo a seguir, usaremos esse recurso para publicar o resultado de uma pesquisa de sinônimos que foi processada por um encadeamento em segundo plano.
Para atingir a meta durante o retorno de chamada da atividade OnCreate, configuraremos onClickListener para executar searchTask em um thread criado.
Quando o usuário clica no botão Pesquisar, criaremos uma classe anônima Runnable que pesquisa a palavra digitada em R.id.wordEt EditText e inicia o thread para executar Runnable.
Quando a pesquisa for concluída, criaremos uma instância do Runnable SetSynonymResult para publicar o resultado novamente no sinônimo TextView sobre o thread da interface do usuário.
Essa técnica às vezes não é a mais conveniente, principalmente quando não temos acesso a uma instância de Activity; portanto, nos capítulos seguintes, discutiremos técnicas mais simples e limpas para atualizar a interface do usuário a partir de uma tarefa de computação em segundo plano.
Fonte :
programação android assíncrona Helder Vasconcelos
fonte
É assim que eu uso:
fonte
fonte
Tente o seguinte:
getActivity().runOnUiThread(new Runnable...
É porque:
1) o implícito na sua chamada para runOnUiThread está se referindo ao AsyncTask , não ao seu fragmento.
2) O fragmento não possui o runOnUiThread.
No entanto, a atividade faz.
Observe que Activity apenas executa o Runnable se você já estiver no thread principal, caso contrário, ele usa um Handler. Você pode implementar um manipulador em seu fragmento, se não quiser se preocupar com o contexto, é realmente muito fácil:
// Uma instância de classe
// em qualquer outro lugar do seu código
// ^ isso sempre será executado no próximo loop de execução no thread principal.
fonte