先看两个链接:

1、http://www.2cto.com/kf/201404/290494.html

2、

链接1:

android 的多线程实际上就是java的多线程。android的UI线程又称为主线程。

首先是Thread 和 Runnable:

Thread才是一个线程,而Runnable可以理解为一个任务。这个任务只是一个接口。具体的任务执行是在 run()方法执行。

Thread thread = new Thread(Runnable);

那么就是把一个Runnable任务放到线程里面。当调用thread.start() 的时候,系统新开一个线程去执行,这个runnable任务是在多线程执行的。是在新开的线程执行的。

但是thread.run() ,这样子实际上只是在UI线程执行了Runnable 并没有实现多线程。系统也没有新开一个线程。

如果直接 new Runnable().run();那么实际上是直接在UI线程执行了这个任务没有进行一个多线程的操作。

总结:runnable()只是一个任务的抽象,并不是多线程。Thread.start()。才是新开一个多线程。并且在新开的线程执行Thread你们的run()方法。

来看看android 的多线程通信机制的产物 Handler。

下面这3个方法的hanlder实际上是不涉及多线程的。

post(Runnable) 让当前线程执行Runnable任务。如果是在主线程调用,那么就是在UI线程执行Runnable。实际上没有多线程执行runnable。
postAtTime(Runnable,long) 也是让当前线程在 时间点long 执行Runnble
postDelayed(Runnable long) 让当前线程延时 long 后执行Runnable。

这3个方法实际上可以把handler看着是一个任务调度器,而不是一个多线程相关的。

sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long) 发出消息的方法

handleMessage(Message msg)处理消息 这才是android 的hanlder的多线程通信用到的,看下图

可以看到3个线程共用一个消息队列Message Queue,一个消息循环器,这是有一个static的线程池对象。这个进程内共用的线程池。(不知道是不是所有android程序都共用这个线程池。。求大神现身。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public final AsyncTask<params, progress,="" result=""> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }
public final AsyncTask<params, progress,="" result=""> executeOnExecutor(Executor exec,
            Params... params) {
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                case RUNNING:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task is already running.");
                case FINISHED:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task has already been executed "
                            + "(a task can be executed only once)");
            }
        }
         
        //状态标记为后台线程正在运行
        mStatus = Status.RUNNING;
         
        //执行 用户继承的初始化操作
        onPreExecute();
         
        //运行的参数放到任务中
        mWorker.mParams = params;
        //用线程池去执行
        exec.execute(mFuture);
 
        return this;
    }
</params,></params,>

这样子线程池执行任务mWorker

1
2
3
4
5
6
7
8
9
10
mWorker = new WorkerRunnable<params, result="">() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
 
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
        //线程池 运行这个任务。并且postResult把结果发出去
                return postResult(doInBackground(mParams));
            }
};</params,>

可以看到这个任务执行了doInBackground()方法。这个任务是通过线程池在多线程的环境下执行的。也就是说doInBackground()也是多线程执行的。

1
2
3
4
5
6
7
private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<result>(this, result));
        message.sendToTarget();
        return result;
    }</result>

通过Hanlder + message把结果result传递出去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private static class InternalHandler extends Handler {
        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    result.mTask.finish(result.mData[0]);//处理结果
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);//处理中间数据
                    break;
            }
        }
    }
private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

这个hanlder处理接收到的消息。

可以看到调用了finish() 并在finish中调用onPostExecute 让用户去使用结果。

最后总结Java的多线程是Thread实现,跟runnable没有太大关系。

android中因为需要多线程交换数据出现了handler+message+thread实现多线程数据通信。就hanlder本身而言并不是实现多线程。

因为handler+message+thread手写比较负载,所以android提供AsyncTask去实现多线程,并且拥有多线程数据同步的能力。

AsyncTask的本质就是handler+message+thread(线程池)的实现。因此要是简单的使用多线程,android中使用asyncTask就足够了。

链接2:

http://www.jb51.net/article/43360.htm:

android Handler详细使用方法实例

链接3:http://www.jb51.net/article/37465.htm

Android开发笔记之:Handler Runnable与Thread的区别详解

链接4:http://www.cnblogs.com/dawei/archive/2011/04/09/2010259.html

Android的Handler总结

理解:runnable是用来写任务的一个接口,要启动这个任务需要借助thread(runnable).start()方法来启动一个新线程(在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)),可以实现资源共享,如果一个runnable任务比较大,可以多开几个线程来实现这一个任务,例如卖票那个例子。当然handler也可以接收runnable,只是这样执行任务不是新创建的线程,而是延时在创建handler的那个线程里执行这个任务,例如计数器就是这样实现(见尾部)。Thread是线程类,可以接受runnable接口来启动任务,也可以自己在类中覆盖run()方法,调用start()或者run()方法来执行线程,但注意这个只有调用start()方法才能调用系统资源,才相当于新开了一个异步线程。否则仍然是运行在创建这个thread的线程里运行。runnable 和Thread 都可以另开线程(其中runnable必须借助thread),但是runnable比thread有优势:避免单继承的局限,一个类可以继承多个接口,另外runnable适合于资源的共享。

cookie1:【【【

一、Handler的定义:
          主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
          解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button, Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了来解决这个复杂的问题,由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

二、Handler一些特点
        handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
        它有两个作用: (1):  安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
      
        Handler中分发消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)
        以上post类方法允许你排列一个Runnable对象到主线程队列中,
        sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

】】】

cookie2【【【

1. 定义一个Handler类

  1. Handler handler=new Handler();
  2. Runnable runnable=new Runnable() {
  3. @Override
  4. public void run() {
  5. // TODO Auto-generated method stub
  6. //要做的事情
  7. handler.postDelayed(this, 2000);
  8. }


2. 启动计时器

  1. handler.postDelayed(runnable, 2000);//每两秒执行一次runnable.



3.停止计时器:

handler.removeCallbacks(runnable);

】】】

android 多线程Thread,Runnable,Handler,AsyncTask的更多相关文章

  1. 第39天学习打卡(多线程 Thread Runnable 初始并发问题 Callable )

    多线程详解 01线程简介 Process与Thread 程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念. 进程则是执行程序的一次执行过程,它是一个动态的概念.是系统资源分配的 ...

  2. Android多线程通信之Handler

    主线程 public class MainActivity extends ActionBarActivity { private Handler handler; // private Thread ...

  3. Android多线程机制和Handler的使用

    参考教程:iMooc关于Handler,http://www.imooc.com/learn/267 参考资料:Google提供Android文档Communicating with the UI T ...

  4. Android多线程:深入分析 Handler机制源码(二)

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 接下来,深入分析 Handler机制的源码,希望加深理解 目录 1. Handler 机制简介 定义一套 Android 消息 ...

  5. Android多线程编程<二>Handler异步消息处理机制之Message

      Message(消息):       一. Message的字段:    在Android中,Message作为线程之间(主要是子线程和UI主线程之间)数据交换的载体,通过Handler去传递.它 ...

  6. java 多线程--- Thread Runnable Executors

    java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...

  7. [java多线程] - Thread&Runnable运用

    负载是一个很大的话题,也是一个非常重要的话题.不管是在大的互联网软件中,还是在一般的小型软件,都对负载有一定的要求,负载过高会导致服务器压力过大:负载过低又比较浪费服务器资源,而且当高请求的时候还可能 ...

  8. Android多线程异步处理:AsyncTask 的实现原理

    AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法.注意继承时需要设定三个泛型P ...

  9. 【Android多线程】异步任务AsyncTask类

    https://www.bilibili.com/video/av65170691?p=9 (本文为此视频观看笔记) 一.为什么需要此类 Handler繁琐 二.理解AsyncTask 2.1 参数( ...

随机推荐

  1. linux 命令实现原理

    我们知道有些Linux的命令涉及到一些高效率的算法,在此做出一个积累吧,不是系统的. 1.tail命令打印一个文件的最后num行 2.grep命令从文本中匹配字符串 基于正则表达式的匹配很快. it ...

  2. Magento首页显示产品

    Magento首页显示产品     经常用的比较琐碎,上官网发现一个稍微全一点的不过没有针对 具体使用过程中遇到的情况进行修正  这边只做一个备忘吧   (细节问题 按个别情况进行修改即可) New  ...

  3. Android Studio ADB响应失败解决方法(2CTo.com)

    当启动Android Studio时,如果弹出 adb not responding. you can wait more,or kill "adb.exe" process ma ...

  4. hdu_5145_NPY and girls(莫队算法+组合)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5145 题意:给你n,m,共有n个女孩,标号为1—n,n个数xi表示第ith个女孩在第xi个教室,然后下 ...

  5. html5中拨打电话代码

    <a href="tel:18600000000">给我打电话</a>   <a href="sms:18600000000"&g ...

  6. cisco 密码重置

    密码重置 分类: 转贴技术资料 2007-12-28 16:38 http://www.cisco.com/en/US/products/hw/routers/ps259/products_passw ...

  7. 为什么MVC不是一种设计模式? ---比较Backbone和Ext4.x在MVC实现上的差异

    为什么MVC不是一种设计模式? ---比较Backbone和Ext4.x在MVC实现上的差异 大漠穷秋 前言 圣人云:不想做妈咪的小姐不是好码农. 每一个码农的心中都有一个终极理想,那就是有一天不用再 ...

  8. 【floyd】 poj 2240

    #include <iostream> #include <map> #include <string> #include <memory.h> usi ...

  9. 深入浅出Ajax(四)

    function initPage() { btn.onmouseover = buttonOver; btn.onmouseover = buttonOut; } 如上,浏览器只会运行指定的最后一个 ...

  10. HDU 5547 暴力

    Sudoku Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...