Definição:
O princípio da comunicação entre threads do Android (principalmente comunicação entre subthreads e threads principais da UI, subthreads enviam mensagens para threads principais da UI e threads principais atualizam a interface de acordo) é baseado no Handler e é encapsulado no base de Handler.Handler
O
uso é o seguinte:
1. Implemente a classe Handler no Thread Principal
2. O subthread possui o objeto mHandler da classe Handler no Thread Principal
3. O subthread envia uma mensagem para o thread principal mHandler.sendMessage(Message msg)
4. Através do mecanismo de loop Looper, o thread principal O handleMessage (Message msg) na classe Thread Handler manipula os dados enviados pelo thread filho e
o uso de runOnUiThread()
-
runOnUiThread() é um método da classe Activity, usado para alternar do thread filho para o thread principal para realizar algumas operações que precisam ser executadas no thread principal.
-
O parâmetro de runOnUiThread() é Runnable.
Vejamos diretamente um exemplo para ver como ele é usado:
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.tv_test);
new Thread(new Runnable() {
@Override
public void run() {
//do something takes long time in the work-thread
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("test");
}
});
}
}).start();
}
}
Análise de princípio:
é fácil de usar e seu princípio também é muito simples. A camada inferior é na verdade implementada por um manipulador encapsulado. A seguir está o código-chave da classe Activity:
//=========Activity=========
final Handler mHandler = new Handler();
private Thread mUiThread;
final void attach(...){
......
mUiThread = Thread.currentThread();
......
}
/**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
*
* @param action the action to run on the UI thread
*/
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
mHander é uma variável membro de Activity. Ela também é inicializada quando Activity é instanciada. MainActivity herda de Activity. O looper usado por mHandler aqui é naturalmente o looper principal.
O método attachment também é chamado no thread principal e mUiThread representa o thread principal.
O entendimento do código-fonte de runOnUiThread (ação Runnable) é o seguinte:
Se o método estiver sendo executado no thread principal, o método run do Runnable será executado imediatamente; se não estiver no thread principal, será postado no MessageQueue de o looper do thread principal e colocado na fila para execução.
Por que o parâmetro é executável? Como converter Runnable em Message e enviar dados através do Handler?
Vamos dar uma olhada no código-fonte da função post do Handler da seguinte maneira:
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
@UnsupportedAppUsage
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
Como pode ser visto nos códigos dos dois métodos acima, o Runnable é convertido em uma Mensagem por meio do método getPostMessage e, em seguida, a Mensagem é enviada ao thread principal para execução por meio do método sendMessageDelayed.
Links de referência:
https://www.cnblogs.com/andy-songwei/p/12064596.html