Handler的使用
2016-06-28 20:54
246 查看
1、Handler的作用:
1)在Android中UI操作一般情况下不能放在子线程中进行操作,如果在子线程中操作会出现Only the original thread that created a view hierarchy can touch its views.错误,但是有的时候UI布局需要得到子线程的数据,这个时候就需要使用Handler来进行UI的操作。
2)如果UI布局还没有完成,这个时候是可以在子线程中进行UI的操作;代码如下:
原因是:android在编译的时候回先判断activity是否存在,如果存在了才会去判断后面的UI操作是否是在UI线程中进行的,如果不是就会出现错误,但是如果把子线程进行的UI操作写在前面,就会在activity还没有布局完成的时候就进行了UI操作,因为activity== null所以不会去判断该UI操作是否是在UI线程中进行的。但是这种操作没有什么意义,通常情况下都是activity已经存在,只是想得到子线程中的属性来给UI里面的控件进行更改,因此要使用Handler。
2、Handler的用法:
a.1:在UI线程中进行Handler的初始化,在把初始化后的结果传递到子线程中,把UI控件需要的值通过sendMessage()方法传递出来然后在UI线程中更改。这也是Handler最常用的方法;代码如下:
a.2 除此之外,其实我们还可以在子线程中定义Handler,通过把UI线程的Looper传递到子线程中来进行UI控件的操作设置;
代码如下:
UI线程代码:
子线程代码:
3、总结:
通过以上2中Handler的使用方法,我们可以发现不管在哪个线程进行Handler的定义,我们都可以完成UI控件的操作。是否能够进行UI控件的操作其实主要是看我们通过Handler把UI控件需要的子线程的哪个属性通过sendMessage()方法发送到了哪里,Handler发送的消息会被添加到被关联的MessageQueue中。我们就可以通过looper.loop()来遍历MessageQueue里面的信息只要MessageQueue是主线程的,那么这个信息就可以在主线程中得到就能够用得到的属性在UI线程中完成对控件的操作。
通过Handler的工作原理,我们可以直接写一个简单的自定义的Handler来完成对UI的操作;
代码如下:
自定义的Handler:
信息:
子线程:
主线程:
1)在Android中UI操作一般情况下不能放在子线程中进行操作,如果在子线程中操作会出现Only the original thread that created a view hierarchy can touch its views.错误,但是有的时候UI布局需要得到子线程的数据,这个时候就需要使用Handler来进行UI的操作。
2)如果UI布局还没有完成,这个时候是可以在子线程中进行UI的操作;代码如下:
public class MainActivity01 extends AppCompatActivity { TextView textview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textview = (TextView) findViewById(R.id.textview); AThread aThread = new AThread(textview); aThread.start(); } class AThread extends Thread { TextView textView; public AThread(TextView textView) { this.textView = textView; } @Override public void run() { String temp = "hahaha"; temp += "AAA"; textView.setText(temp); } } }
原因是:android在编译的时候回先判断activity是否存在,如果存在了才会去判断后面的UI操作是否是在UI线程中进行的,如果不是就会出现错误,但是如果把子线程进行的UI操作写在前面,就会在activity还没有布局完成的时候就进行了UI操作,因为activity== null所以不会去判断该UI操作是否是在UI线程中进行的。但是这种操作没有什么意义,通常情况下都是activity已经存在,只是想得到子线程中的属性来给UI里面的控件进行更改,因此要使用Handler。
2、Handler的用法:
a.1:在UI线程中进行Handler的初始化,在把初始化后的结果传递到子线程中,把UI控件需要的值通过sendMessage()方法传递出来然后在UI线程中更改。这也是Handler最常用的方法;代码如下:
public class MainActivity02 extends Activity implements View.OnClickListener { TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textview); textView.setOnClickListener(this); } @Override public void onClick(View v) { MyHandler myHanler = new MyHandler(); BThread bThread = new BThread(myHanler); bThread.start(); } class MyHandler extends Handler { @Override public void handleMessage(Message msg) { textView.setText(msg.obj.toString()); } } class BThread extends Thread { Handler handler; public BThread(Handler handler) { this.handler = handler; } @Override public void run() { String temp = "哈哈哈"; temp += "BBB"; Message message = handler.obtainMessage(); message.obj = temp; handler.sendMessage(message); } } }
a.2 除此之外,其实我们还可以在子线程中定义Handler,通过把UI线程的Looper传递到子线程中来进行UI控件的操作设置;
代码如下:
UI线程代码:
public class MainActivity04 extends Activity implements View.OnClickListener{ TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textview); textView.setOnClickListener(this); } @Override public void onClick(View v) { DThread cThread = new DThread(textView, Looper.myLooper()); cThread.start(); } }
子线程代码:
public class DThread extends Thread { TextView textView; Looper looper; public DThread(TextView textView, Looper looper) { this.textView = textView; this.looper = looper; } @Override public void run() { Looper.prepare(); MyHandler myHandler = new MyHandler(looper); Message message = myHandler.obtainMessage(); String temp = "DDD"; message.obj = temp; message.setTarget(myHandler); myHandler.sendMessage(message); // looper.loop(); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { textView.setText(msg.obj.toString()); } } }
3、总结:
通过以上2中Handler的使用方法,我们可以发现不管在哪个线程进行Handler的定义,我们都可以完成UI控件的操作。是否能够进行UI控件的操作其实主要是看我们通过Handler把UI控件需要的子线程的哪个属性通过sendMessage()方法发送到了哪里,Handler发送的消息会被添加到被关联的MessageQueue中。我们就可以通过looper.loop()来遍历MessageQueue里面的信息只要MessageQueue是主线程的,那么这个信息就可以在主线程中得到就能够用得到的属性在UI线程中完成对控件的操作。
通过Handler的工作原理,我们可以直接写一个简单的自定义的Handler来完成对UI的操作;
代码如下:
自定义的Handler:
public class MyHand { ArrayList<IMessage> arrayList; public MyHand(ArrayList<IMessage> arrayList) { this.arrayList = arrayList; } public void handleIMessage(IMessage iMessage){ } public void sendIMessage(IMessage iMessage){ arrayList.add(iMessage); } }
信息:
public class IMessage { Object object; MyHand target; }
子线程:
public class GThread extends Thread { MyHand myHand; public GThread(MyHand myHand) { this.myHand = myHand; } @Override public void run() { String temp = "哈哈哈"; temp += "GGG"; IMessage iMessage = new IMessage(); iMessage.target = myHand; iMessage.object = temp; myHand.sendIMessage(iMessage); } }
主线程:
public class MainActivity07 extends Activity implements View.OnClickListener{ TextView textView; Button button_check; IMessage iMessage; ArrayList<IMessage> arrayList; MyHand myHand ; boolean isFlag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textview); button_check = (Button) findViewById(R.id.button_check); textView.setOnClickListener(this); button_check.setOnClickListener(this); arrayList = new ArrayList(); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.textview: if (arrayList.size() > 0){ myHand = iMessage.target; myHand.handleIMessage(iMessage); } break; case R.id.button_check: GThread gThread = new GThread(new Ghand(arrayList)); gThread.start(); while (isFlag){ if (arrayList.size() > 0){ iMessage = arrayList.get(0); if (iMessage == null){ return; } isFlag = false; } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Ghand extends MyHand{ public Ghand(ArrayList<IMessage> arrayList) { super(arrayList); } @Override public void handleIMessage(IMessage iMessage) { textView.setText(iMessage.object.toString()); } } }
相关文章推荐
- >>> FilterDispatcher <<< is deprecated! Please use the new filters!
- Maven入门指南(一)
- POJ 2777 线段树
- android 6.28 第一行代码第5.5节broadcastBestreceiver
- Apache Tomcat Native Library
- 跳台阶(斐波那契数列)
- 最长公共子串问题
- HBuilder
- 肤色检测一例-使用rgb颜色模型
- Linux-ulimit命令
- 访问服务器地址中的某个文件链接,下载文件到客户端
- python强制类型转换(dpkt)
- unsigned long的一点应用
- session入库
- 为 Tomcat 安装 apr
- 吉布斯采样——原理及matlab实现
- Erasure Coding(纠删码)深入分析
- 算法之美--交换排序--冒泡排序
- Codeforces 545C Woodcutters
- SpiralOrderTraverse,螺旋遍历二叉树,利用两个栈