Explicación detallada de Handler en Android y la diferencia con Thread
1. Definición de controlador:
Acepta principalmente datos enviados por subprocesos secundarios y utiliza estos datos para actualizar la interfaz de usuario junto con el subproceso principal.
Explicación: Cuando se inicia la aplicación, Android primero iniciará un hilo principal (es decir, el hilo de la interfaz de usuario). El hilo principal es el control de la interfaz de usuario en la interfaz de administración y distribuye eventos. Por ejemplo, si hace clic en un botón, Android distribuirá. el evento al Botón para responder a su operación. Si se requiere una operación que requiere mucho tiempo en este momento, como leer datos en línea o leer un archivo local grande, no puede colocar estas operaciones en el hilo principal. Si las coloca en el hilo principal, la interfaz aparecerá con una animación suspendida. Si no se completa en 5 segundos, recibirá un mensaje de error de "cierre forzado" del sistema Android. En este momento, debemos colocar estas operaciones que consumen mucho tiempo en un subproceso secundario, porque el subproceso secundario involucra la interfaz de usuario. actualizaciones, y el subproceso principal de Android no es seguro para el subproceso, es decir, la actualización de la interfaz de usuario solo se puede actualizar en el subproceso principal y las operaciones en subprocesos son peligrosas. En este momento, aparece el controlador para resolver este problema. Problema complicado. Dado que el controlador se ejecuta en el hilo principal (el hilo de la interfaz de usuario), él y el subproceso pueden transferir datos a través del objeto Mensaje. En este momento, el controlador es responsable de aceptar los datos del subproceso. El subproceso utiliza el método sedMessage (). Chuandi) Objeto de mensaje (que contiene datos), coloca estos mensajes en la cola del hilo principal y coopera con el hilo principal para actualizar la interfaz de usuario.
2. Algunas características de Handler
El controlador puede distribuir objetos Message y objetos Runnable al hilo principal. Cada instancia de Handler estará vinculada al hilo que la creó (generalmente ubicada en). Hilo principal),
Tiene dos funciones: (1): Organizar un mensaje o Runnable para que se ejecute en algún lugar de un hilo principal, (2) Organizar una acción para que se ejecute en un hilo diferente
p>Algunos métodos de distribución de mensajes en Handler
[html] ver copia simple
post(Runnable)
postAtTime(Runnable, long)
postDelayed(Ejecutable largo)
sendEmptyMessage(int)
sendMessage(Mensaje)
sendMessageAtTime(Mensaje, largo)
sendMessageDelayed(Message, long)
El método de clase de publicación anterior le permite organizar un objeto Runnable en la cola del hilo principal
El método de clase sendMessage le permite organizar. un objeto ejecutable con datos. El objeto Mensaje se coloca en la cola, esperando actualización.
3. Instancia de controlador
(1) Las subclases deben heredar la clase Controlador y anular la. método handleMessage (mensaje de mensaje) para aceptar datos de subprocesos
El siguiente es un ejemplo que implementa las siguientes funciones: Modificar el contenido del botón de interfaz a través de subprocesos
[html] vista simple copiar
clase pública MyHandlerActivity extiende Actividad {
Botón botón
MyHandler myHandler
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.handlertest);
botón = (Botón) findViewById(R.id.button);
myHandler = new MyHandler ();
// Cuando se crea una nueva instancia de Handler, se vinculará al hilo actual y a la cola de mensajes y comenzará a distribuir datos
// Hay dos funciones de controlador, (1): ejecutar objetos Message y Runnalbe con regularidad
// (2): permitir que una acción se ejecute en diferentes subprocesos
. // Programa mensajes y utiliza los siguientes métodos
// post(Runnable)
// postAtTime(Runnable, long)
> // postDelayed(Runnable, long)
// sendEmptyMessage(int)
// sendMessage(Message
// sendMessageAtTime(Mensaje, long); )
// sendMessageDelayed(Message, long)
// Los métodos anteriores que comienzan con post te permiten manejar objetos ejecutables
//sendMessage() permite procesas objetos de mensaje (el mensaje puede contener datos)
MyThread m = new MyThread()
new Thread(m).start(); }
/**
* Aceptar mensajes y procesar mensajes. Este controlador se ejecutará junto con el hilo principal actual
* */
<. p >class MyHandler extiende Handler {public MyHandler() {
}
public MyHandler(Looper L) {
super( L );
}
// Las subclases deben anular este método para aceptar datos
@Override
public void handleMessage(Mensaje mensaje ) {
// TODO Código auxiliar de método generado automáticamente
Log.d("MyHandler", "handleMessage...");
super.handleMessage (msg);
// La interfaz de usuario se puede actualizar aquí
Paquete b = msg.getData();
Color de cadena = b. ");
MyHandlerActivity.this.button.append(color);
}
}
clase MyThread implementa Runnable {
public void run() {
intenta {
Thread.sleep(10000
} catch (InterruptedException e) {
// TODO Aut
bloque de captura generado o
e.printStackTrace();
}
Log.d("thread.....", "mThread .. ......");
Mensaje msg = nuevo Mensaje();
Paquete b = nuevo Paquete(); // Almacenar datos
b.putString("color", "mi");
msg.setData(b);
MyHandlerActivity.this.myHandler.sendMessage(msg); al controlador y actualizar la interfaz de usuario
}
}
}
Caso de excepción:
[ html ] ver copia simple
paquete com.example.span.view;
importar java.util.LinkedList
importar android.app.AlertDialog < / p>
importar android.content.ComponentName;
importar android.content.Context;
importar android.content.DialogInterface
importar android. content.Intent;
importar android.graphics.Canvas;
importar android.graphics.Paint
importar android.graphics.Point;
importar android.graphics.RectF
importar android.os.Handler
importar android.os.Message
importar android.util . AttributeSet;
importar android.view.KeyEvent;
importar android.view.View
importar android.widget.Toast; >importar com.example.span.view.domain.Block
/**
* 2013-6-6 9:24:58 a. m.
*
* @author Qiao Xiaosong
*/
clase pública GameView extiende Vista {
bandera booleana estática pública = verdadero; /p>
público
c bloque de bloque estático;
controlador de controlador público
public static int dir = 2
public static final int DIRTOP = -1;
público estático final int DIRLEFT = -2;
público estático final int DIRDOWN = 1;
público estático final int DIRRIGHT = 2; descuento int estático = 2;
lienzo público
comida estática pública
Pointgt público; ;
public LinkedListlt; getPoints() {
puntos de retorno;
public void setPoints(LinkedListlt; Pointgt; puntos) {
this.points = puntos
}
public GameView(Contexto de contexto, AttributeSet attrs) {
super( contexto, atributos);
bloque = nuevo bloque (este);
for (int i = 0; i lt; 3; i) {
Punto punto = nuevo Punto(block.getCx(), block.getCy());
block.setCx(block.getCx() - 20
puntos.addLast(punto);
}
comida = nueva comida(esta);
controlador = nuevo controlador() {
@Override p> p>
public void handleMessage(Mensaje msg) {
super.handleMessage(msg
switch (msg.what) {
caso DIRLEFT:
if (msg.what descuento!= 0) {
descuento = -2;
block.moveLeft()
} else {
block.moveRight();
}
break;
case DIRRIGHT:
if (msg. ¡qué descuento! = 0) {
descuento = 2;
block.moveRight();
} else {
bloque. moveLeft();
}
break;
case DIRTOP:
if (msg.what descuento!= 0) {
descuento = -1;
block.giveUp();
} else {
block.downLoad(); >
}
descanso;
caso DIRDOWN:
if (msg.what descuento!= 0) {
descuento = 1;
block.downLoad();
} más {
block.giveUp(); >
ruptura;
caso -3:
Toast.makeText(getContext(), "Game Over", Toast.LENGTH_LONG)
.show()
new AlertDialog.Builder(getContext())
<; p> .setTitle("Consejo del juego").setMessage("Juego terminado")
.setPositiveButton("Salir",
nueva DialogInterface.OnClickListener () {
@Override
public void onClick(
cuadro de diálogo DialogInterface,
int cual) {
Thread.currentThread().stop();
}
})
.setNegativeButton("Volver al menú",
new DialogInterface.OnClickListener() {
@Override
public void onClick(
diálogo DialogInterface,
int cual) {
p>
Intención intención = nueva Intención();
intent.setAction("android.intent.action.MAI");
intent.addCategory("android.intent.category.LAUNCHER");
intent.setFlags (0x10200000);
intent.setComponent(new ComponentName(
"com.example.span",
"com.example.span.SpanActivity") );
getContext().startActivity(intención);
}
}).show(); /p>
}
}
};
nuevo hilo (nuevo Runnable() {
@Override p>
p>
public void run() {
while (bandera) {
prueba {
Thread.sleep(500)
handler.sendEmptyMessage(dir);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(-3
}
> }).start();
}
@Override
public boolean onKeyDown(int keyCode, evento KeyEvent) {
System.out.println(keyCode);
return super.onKeyDown(keyCode, evento
}
@Override
protegido vacío onDraw(lienzo de lienzo) {
super.onDraw(lienzo);
this.lienzo = lienzo
comida.chsw(lienzo); /p>
/*
* if (descuento == 2) { chsw(); else { if (points.contains(new
* Punto(40, 40))) { System.out.println("Come la comida,,.." } else { chsw() }
* }
;