简单来说,Handler就是子进程用来向主线程传递消息的。
Handler可以当成子线程与主线程的消息传送的纽带。在安卓开发中,在子线程中无法刷新UI,是因为UI在子线程中刷新的话,是不安全的,就比如多个线程刷新UI,会造成UI更新冲突,这样是不安全的。
所以,Handler的作用就来了,子线程可以通过Handler来将UI更新操作切换到主线程中执行。
结合之前发的socket客户端例子来简单理解下:
目的:手机端按下温度,显示温度
客户端:MainActivity.java
package com.example.socketapp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
Handler handler ;
private TextView tx;
private click connect;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取温度控件的ID
tx=(TextView)findViewById(R.id.Temp);
handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//显示温度
tx.setText(connect.reTurnMes);
};
};
}
public void Click_cmd(View v)
{
int id=v.getId();
switch(id){
case R.id.openButton:
new click("open").Click_Button();
break;
case R.id.offButton:
new click("off").Click_Button();
break;
case R.id.getTemp:
connect = new click("getTemp",handler);
connect.Click_Button();
}
}
}
客户端:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/openButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开"
android:onClick="Click_cmd"
/>
<Button
android:id="@+id/offButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关"
android:onClick="Click_cmd"
/>
<Button
android:id="@+id/getTemp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取温度"
android:onClick="Click_cmd"
/>
<TextView
android:id="@+id/Temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20 degree"
android:onClick="Click_cmd"
/>
</LinearLayout>
客户端:Click.java
package com.example.socketapp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.Handler;
import android.widget.Toast;
public class Click {
public String cmd;
public String reTurnMes;
public Handler handler;
public Click(String cmd)
{
this.cmd=cmd;
}
public click(String cmd,Handler hangler)
{
this.cmd=cmd;
this.handler=hangler;
}
public void Click_Button(){
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Socket client = new Socket("192.168.1.29", 8787);
OutputStream out=client.getOutputStream();
out.write(cmd.getBytes());
System.out.println("-------发送完成---------");
if(cmd.equals("getTemp")){
InputStream in = client.getInputStream();
byte [] mes = new byte[128];
int len;
len = in.read(mes);
System.out.println("----------读取"+new String(mes,0,len));
reTurnMes = new String(mes,0,len);
handler.sendEmptyMessage(0);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
服务端:Server.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int PORT= 8787;
try {
ServerSocket server = new ServerSocket(PORT);
if(server!=null){
System.out.println("创建服务端成功");
}
while(true){
final Socket server_connect = server.accept();
System.out.println("-----开始连接-----");
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
InputStream in = server_connect.getInputStream();
byte[] mes = new byte[128];
int len ;
len=in.read(mes);
String message= new String(mes,0,len);
System.out.println(message);
System.out.println("数据接收完成");
if(message.equals("getTemp")){
OutputStream out = server_connect.getOutputStream();
out.write("30 degree".getBytes());
out.flush();
out.close();
}
in.close();
server_connect.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("服务器创建失败");
}
}
}).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}