Sub Thread to update main Thread (UI)  2

Handler.post(somethread);

Handler.sendMessage("Msg");

 import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
 
public class HandlerActivity extends Activity {
     
    Button btnStart,btnEnd;
    ProgressBar proBar;
     
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        //通过控件的ID来实例化控件对象
         btnStart = (Button)findViewById(R.id.start);
        btnEnd = (Button)findViewById(R.id.end);
        proBar = (ProgressBar)findViewById(R.id.pBar);
         
        //开始按钮触发事件
        btnStart.setOnClickListener(new View.OnClickListener() {
             
            @Override
            public void onClick(View v) {
                proBar.setVisibility(View.VISIBLE);
                <span style="color: #ff0000;">updateBarHandler.post(updateBarThread);</span>
            }
        });
         
        //结束按钮触发事件
        btnEnd.setOnClickListener(new View.OnClickListener() {
             
            @Override
            public void onClick(View v) {
                <span style="color: #ff0000;">updateBarHandler.removeCallbacks(updateBarThread);</span>
            }
        });
    }
     
     
     //创建一个Handler对象
     Handler updateBarHandler = new Handler(){
 
        @Override
        public void handleMessage(Message msg) {
            proBar.setProgress(msg.arg1); //REPEAT
             updateBarHandler.post(updateBarThread);
        }
         
    };
     
    //更新ProgressBar的线程对象
    Runnable updateBarThread = new Runnable() {
        int i = 0;
        @Override
        public void run() {
            i = i + 10;
            Message msg = updateBarHandler.obtainMessage();
            msg.arg1 = i;
            try{
                Thread.sleep(2000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            updateBarHandler.sendMessage(msg);
            if(i == 100){
                updateBarHandler.removeCallbacks(updateBarThread);
            }
        }
    };
}

解释:

使用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对象进行处理。

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

  1. Sub Thread to update main Thread (UI)

    Sub Thread to update main Thread (UI) main Thread :   A  has Hander.HandleMessage() to process the & ...

  2. Does Daemon Thread Exit with Main Thread?

    主线程(进程)退出后,主线程创建的守护线程也会退出吗? 通过下面的代码测试: Demo1: 进程创建普通线程 #!/usr/bin/python3 # FileName: daemonThread.p ...

  3. iOS开发,在main thread以外的thread更新UI

    如果需要在异步任务(Async Task)中更新UI,若直接设置UI,会导致程序崩溃. 例如,在异步block中去更改UI: NSOperationQueue *queue=[[NSOperation ...

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

    Xcode打印栏出现如下警告: Main Thread Checker: UI API called on a background thread 这个是什么错误呢? 其实这并不一定是错误,也可以理解 ...

  5. iOS 报错:(子线程中更新UI)This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

    今天在写程序的时候,使用Xcode 运行工程时报出下面的错误错信息,我还以为是什么呢,好久没遇到过这样的错误了. **ProjectName[1512:778965] This application ...

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

    今天花费了一天的时间来解决这个bug. 这种在程序运行期间出现的问题比较棘手,如果再没有规律的话就更难解决. 还好这个bug是由规律的,也就是说在程序执行半个小时左右后就会因为此异常而导致程序退出:那 ...

  7. reloadData should be in main thread

    reloadData should be called in main thread, so if you call it in work thread, you should call it as ...

  8. APP崩溃提示:This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

    崩溃输出日志 2017-08-29 14:53:47.332368+0800 HuiDaiKe[2373:1135604] This application is modifying the auto ...

  9. 在Main Thread中使用异步

    Whenever you first start an Android application, a thread called "main" is automatically c ...

随机推荐

  1. logstash-shipper.conf

    input { file { path => '/data/rsyslog/*/*/*.log' start_position => 'beginning' sincedb_path =& ...

  2. javascript取前n天的日期两种方法

    方法一: var d = new Date(); d = new Date(d.getFullYear(),d.getMonth(),d.getDate()-n); 方法二: var now = ne ...

  3. ActiveMQ maven

    http://outofmemory.cn/java/mq/apache-activemq-demo

  4. 洛谷 P3914 染色计数

    P3914 染色计数 题目描述 有一颗NN个节点的树,节点用1,2,\cdots,N1,2,⋯,N编号.你要给它染色,使得相邻节点的颜色不同.有MM种颜色,用1,2,\cdots,M1,2,⋯,M编号 ...

  5. git checkout -b 报错

    有时候在git中checkout -b 出现如下报错 $ git checkout -b test --track origin/master fatal: Cannot update paths a ...

  6. 7、java封装、继承、聚合组合

    1封装:封装的是属性,封:private 装:set.get‘ 可以看做将属性和get/set方法捆绑的过程. 优点:1.防止对封装数据的未经授权的访问,提高安全性.使用者只能通过事先预定好的方法来访 ...

  7. mysql-过程与函数

    一.过程与函数简介 过程与函数是命名的PL/SQL块(也是用户的方案对象),被编译后存储在数据库中,以备执行.因此,其他PL/SQL块可以按名称来使用他们.所以可以将商业逻辑.企业规划写成函数或过程保 ...

  8. nginx 1.5 支持websocket

    proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set ...

  9. mongodb官网文档阅读笔记:与写性能相关的几个因素

    Indexes 和全部db一样,索引肯定都会引起写性能的下降,mongodb也没啥特别的,相对索引对读性能的提示,这些消耗通常是能够接受的,所以该加入的索引还是要加入.当然须要慎重一些.扯点远的,以前 ...

  10. lightoj--1214--Large Division(大数取余)

    Large Division Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Submit ...