Sub Thread to update main Thread (UI) 2

Sub Thread to update main Thread (UI)  2

Handler.post(somethread);

Handler.sendMessage("Msg");

 1 import android.app.Activity;
 2     import android.os.Bundle;
 3     import android.os.Handler;
 4     import android.os.Message;
 5     import android.util.Log;
 6     import android.view.View;
 7     import android.widget.Button;
 8     import android.widget.ProgressBar;
 9      
10     public class HandlerActivity extends Activity {
11          
12         Button btnStart,btnEnd;
13         ProgressBar proBar;
14          
15         /** Called when the activity is first created. */
16         @Override
17         public void onCreate(Bundle savedInstanceState) {
18             super.onCreate(savedInstanceState);
19             setContentView(R.layout.main);
20              
21             //通过控件的ID来实例化控件对象
22              btnStart = (Button)findViewById(R.id.start);
23             btnEnd = (Button)findViewById(R.id.end);
24             proBar = (ProgressBar)findViewById(R.id.pBar);
25              
26             //开始按钮触发事件
27             btnStart.setOnClickListener(new View.OnClickListener() {
28                  
29                 @Override
30                 public void onClick(View v) {
31                     proBar.setVisibility(View.VISIBLE);
32                     <span style="color: #ff0000;">updateBarHandler.post(updateBarThread);</span>
33                 }
34             });
35              
36             //结束按钮触发事件
37             btnEnd.setOnClickListener(new View.OnClickListener() {
38                  
39                 @Override
40                 public void onClick(View v) {
41                     <span style="color: #ff0000;">updateBarHandler.removeCallbacks(updateBarThread);</span>
42                 }
43             });
44         }
45          
46          
47          //创建一个Handler对象
48          Handler updateBarHandler = new Handler(){
49      
50             @Override
51             public void handleMessage(Message msg) {
52                 proBar.setProgress(msg.arg1);
53
54                 //REPEAT
55                  updateBarHandler.post(updateBarThread);
56             }
57              
58         };
59          
60         //更新ProgressBar的线程对象
61         Runnable updateBarThread = new Runnable() {
62             int i = 0;
63             @Override
64             public void run() {
65                 i = i + 10;
66                 Message msg = updateBarHandler.obtainMessage();
67                 msg.arg1 = i;
68                 try{
69                     Thread.sleep(2000);
70                 }catch (InterruptedException e) {
71                     e.printStackTrace();
72                 }
73                 updateBarHandler.sendMessage(msg);
74                 if(i == 100){
75                     updateBarHandler.removeCallbacks(updateBarThread);
76                 }
77             }
78         };
79     }
80      

解释:

使用Handler的大致流程:

1.首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Hander类,重写HandleMessage方法来创建Handler对象

2.在监听器中,调用Handler的post方法,将要执行的线程对象加到线程队列当中。此时将会把线程对象添加到handler对象的线程队列中

3.将要执行的操作写在线程对象的run方法中,一般一个Runnable对象,复写其中的run方法就可以了。

Handler包含了两个队列,其中一个是线程队列,另外一个是消息队列。使用post方法会将线程对象放到该handler的线程队列中,使用sendMessage将消息放到消息队列中。

如果想要在这个流程一直执行的话,可以在run方法内部执行postDelayed或者post方法,再将该线程对象添加到消息队列中,重复执行。想要线程停止执行,调用Handler对象的removeCallbacks方法,从线程队列中移除线程对象,是线程停止执行。

Handler为Android提供了一种异步消息处理机制,当向消息队列中发送消息(sendMessage)后就立即返回,而从消息队列中读取消息时会阻塞,其中消息队列中读取消息时会执行Handler中的public void handleMessage方法,因此在创建Handler时,应该使用匿名内部类重写该方法,在该方法中写上读取到消息后的操作,使用Handler的obtainMessage()来获得消息的对象。

Handler与线程的关系:

使用Handler的post方法将Runable对象放到Handler的线程队列中后,该Runnalbe的执行其实并未单独开启线程,而是仍然在当前Activity线程中执行的,Handler只是调用了Runable对象的run方法。

如何让Handler执行Runnable时打开新的线程:

1.首先生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序架构提供。

HandlerThread handlerThread=new HandlerThread(“handler_thread”);

2.在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();

3.根据这个HandlerThread对象得到其中的Looper对象。

4.创建自定义的继承于Handler类的子类,其中实现一个参数为Looper对象的构造方法,方法内容调用父类的构造函数即可。

5.使用第三步得到的Looper对象创建自定义的Handler子类的对象,再将消息发送到该Handler的消息队列中,Handler复写的handleMessage()将会执行来处理消息队列中的消息。

消息,即Message对象,可以传递一些信息,可以使用arg1,arg2,Object传递一些整形或者对象,还可以使用Message对象的setData(Bundle bundle)来将Bundle对象传递给新创建的线程,新创建的线程在执行handleMessage时可以从message中利用getData()提取出Bundle对象进行处理。

时间: 2024-11-06 03:34:31

Sub Thread to update main Thread (UI) 2的相关文章

Sub Thread to update main Thread (UI)

Sub Thread to update main Thread (UI) main Thread :   A  has Hander.HandleMessage() to process the "Msg" from subthread B; Sub Thread :    B  use  Hander.sendMessage(Msg)  to main Thread A; 1 import java.util.Timer; 2 import java.util.TimerTask;

Does Daemon Thread Exit with Main Thread?

主线程(进程)退出后,主线程创建的守护线程也会退出吗? 通过下面的代码测试: Demo1: 进程创建普通线程 #!/usr/bin/python3 # FileName: daemonThread.py # Author: lxw # Date: 2016-02-25 import threading import time def show(num): time.sleep(3) print("In show(): {0}".format(num)) with open("

MFC data forwarding to main thread via PostMessage

MFC data forwarding to main thread via PostMessage          up vote3down votefavorite 3 I have a C++/MFC application I need to restructure. The app used to process most of the data on the main thread, therefore blocking the input, and now I want to c

iOS Main Thread Checker: UI API called on a background thread的解释

Xcode打印栏出现如下警告: Main Thread Checker: UI API called on a background thread 这个是什么错误呢? 其实这并不一定是错误,也可以理解为一种警告,说他不是错误,是因为它不一定会影响你的代码功能,可能对你的实现功能毫无影响. 那么它的含义是这样: 这是Xcode 9的新特性:主线程检测器(Main Thread Checker). 出现的时候意味着:本来需要在主线程执行的代码 被你放在了子线程里边执行. 那么我们解决的话,只需要检查

主线程任务太多导致异常退出(The application may be doing too much work on its main thread)

今天花费了一天的时间来解决这个bug. 这种在程序运行期间出现的问题比较棘手,如果再没有规律的话就更难解决. 还好这个bug是由规律的,也就是说在程序执行半个小时左右后就会因为此异常而导致程序退出:那么在网上找了下原因,无非是说一下几点: 1.把业务放在子线程中去完成,然后通过handler来更新界面 2.通过runOnUiThread的方法来实现 再补充一点就是:优化代码,将不需要重复执行的代码执行一次就ok了,特别是需要绘制UI的代码更不能随便放在重复执行的地方 一.bug现场还原 我的程序

Service 是否在 main thread 中执行, service 里面是否能执行耗时的操作?

默认情况,如果没有显示的指 service 所运行的进程, Service 和 activity 是运行在当前 app 所在进程的 main thread(UI 主线程)里面.service 里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让 service 在另外的进程中执行 <service android:name="com.baidu.location.f" android:enabled=&quo

在Main Thread中使用异步

Whenever you first start an Android application, a thread called "main" is automatically created. The main thread, also called the UI thread, is very important because it is in charge of dispatching the events to the appropriate widgets and this

main Thread ,worker Thread

哪个线程创建了view,哪个线程才能对这个view进行访问 一般是主线程创建的 view,所以,对view的访问:设置.读取,都是在主线程中完成的 特例:progressBar.setProgress方法可以在worker Thread中调用. ----每一个应用程序中,主线程通常用于接收用户的输入 ,以及将运算的结果反馈给用户 因此主线程一般是不能使用阻塞代码的.(比如耗时较长的操作-读取大文件,sleep等) 对于一些可能会产生阻塞的操作,必须放置在worker Thread当中. 于是产生

main thread starting…

执行结果例如以下: main thread starting- Thrad 2 staring- Thrad 2 end- Thrad 4 staring- Thrad 4 end- Thrad 1 staring- Thrad 1 end- Thrad 3 staring- Thrad 3 end- Thrad 5 staring- Thrad 5 end- main thread end- CountDownLatch方式代码例如以下: package com.test.thread; im