0
点赞
收藏
分享

微信扫一扫

android学习之远程回调原理 与 ansyncTask 实现流程


   昨晚上整理多线程知识的时候,有两个问题没有解决。 

    一就是,基于远程的回调是如何实现的?  常见的应用场景如: 微信支付宝支付收款;   第三方登陆的应用场景如csdn 的 qq登陆; 以及我们平时用的 浏览器的请求回调码的获得等;   

    二就是,asyncTask如何在主线程中,通过调用线程池然后生成的子线程,并且如何完成主线程与子线程的转换?   线程池的生命周期是什么?  

    先来解决第一个问题,由于我的知识水平受限,所以只能去互联网上查找相关的知识,于是这里一直阻塞中....

    -----------------------------------------------

    在众多的资料中摸索,总算找到一个让自己还算满意的一个知识点:  由于过于经典,因此直接贴图:  地址

android学习之远程回调原理 与 ansyncTask 实现流程_线程池

    结合自己的理解总结谈谈看法:

         一,同步调用,通常也是单线程的模式,符合我们的编程习惯。

         二,回调的方式,即可用单线程方式实现,(但是由于是单线程的,回调很奇怪,有点像 goto 的感觉)。但是用的多的应该还是多线程场景下,因为这样的场景下才有这样的需求。

         三,异步调用,相当于作为主体的A,被客体B 调用不是实时的。   其应该是客体B,经由某种触发(可能是自身的定时器,也可能是外界的)后,放入事件队列,根据自身的策略在适当的时机调用主体A。   这样就构成了异步调用。    异步调用可以简单的理解为 非同步的回调。。(因为从实用性考虑,主体肯定对客体的动作要有预期才行,因此它必须要承担一个触发器的作用)。

         四,android的事件处理机制与之相结合的理解:     

                    假设UI 线程是主体A,  那么 UI 线程对View 的初始化,以及主动调用 JNI 来实现渲染都是同步调用。

                    回调的实现:   A被渲染完成后,会将View的 相应的回调接口暴露给android,同时,在该接口种定义好了自己的业务逻辑。    当用户通过硬件触发中断,android通过主动调用的回调接口,执行里面的代码,对UI线程来说,完成了一次回调。

                     异步调用:   如果View的回调函数返回值为false, 那么本次中断事件将以 类似于广播的形式 向外传递。   本次广播的传递者为UI线程。   广播传递出去后,它就会去执行其它的业务逻辑去了。  这时候会有监听器监听到这个广播,而且这个监听器内部可能还有一些其它的事件待处理。。 这样根据先入先出的逻辑,最终会执行到刚刚进入的那个事件,然后调用UI 线程,处理监听器种重写的逻辑。   这样对于UI 线程来说,就是一次  非同步的回调,也就是异步调用。
-----------------------------------------------------------------------------

  结合上面的知识,我感觉理解方面已经是够了,下面贴一下刚看到的用于远程调用方面的技术:

          1.Java RMI(远程方法调用),是jdk提供的一个功能。

          2.EJB远程接口调用

          3.WebService,常见的有: jax-ws,axis,xfire,cfx

          4.Hessian 和  Spring HttpInvoker

   另外我纠正自己的一个误区:  进程间不能互相调用,而客户机与服务器之间的通信,本质上是两个端进程间的通信,因此应该也不能直接调用。 所以它们应该是通过进程间通信传递的信息来标志状态。

    so,又要发挥自己的想象力,推测一下 qq第三方登陆的场景的实现:

        以csdn 为例,我点击登陆,点击第三方账号登陆,点击快捷登陆(这个快捷登陆应该是存在我电脑浏览器的缓存中)--->  点击后触发一个标志该请求信息的唯一标志号(可能包括我 qq的账号)传递给csdn服务器,在csdn服务器中接收到该服务,在业务层中将之发送给qq的服务端,并在此时阻塞等待。。。。。      qq服务端接收到消息,向我的手机端qq发送一个消息通知(它如何知道我的位置?   我们知道tcp协议是面向连接的协议,当通信双方建立连接后即可互相发送信息。  因此我们登陆状态下,服务端第一知道我们在线,第二,可以通过tcp连接的那个ip地址给我们发信息,但是这个ip地址是网关的ip,消息发到网关那里后,则需要在这个局域网内找到我们的局域网ip,然后发给我们的进程)  同时,在发送消息通知后,开启监听,是否有特定的消息回传,当收到同意的消息后,将成功信息发送给csdn官方,csdn那个阻塞得以执行,然后向我的浏览器发送反馈信息。。。      整个过程中,都是借助了回调,或者说异步调用的思路,但是却不是回调,而是通过消息的传递达到目的。。。

   但是我转念又一想,同一个进程内部的线程间的相互调用,不也是通过消息机制吗???????OMG,自己在一个不是问题的问题上绕了这么久,不过我认为值得。。。不后悔。()

   最后总结一句话:   调用的核心是消息机制。

------------------------------------------------------------------------------------------------------------------------

看了看时间,发现时间已经过去了不少,于是赶紧进入调试模式,查看一下AnsyncTask 是如何实现的吧!

首次执行主线程的时候,通过查看它的运行堆栈可以知道:

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_02

   android的系统开始main方法,程序的执行逻辑 ------>  然后经过反射,调用了 ActivityThread这个线程的main方法。   (那么这个ZygotelInit,应该是系统进程了)。  ---->   实例一个Looper与该主线程绑定,以及其它的业务处理(图上没有,因为已经出栈了) ---->  Looper.loop()方法接收到消息。----> 通过处理回调分发  ---->  分发消息,由于是ListView的事件,因此被分发到了AbsListView中----->   执行回调代码 ----> 执行到断点。。。 

    

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_03

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_04

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_05

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_06

   在AsyncTask 初始化期间,在静态块和静态属性中获得了一些硬件参数如cpu核心数等,同时生产了新的线程,以及新的线程池执行器。。  接着是执行:

   

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_07

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_08

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_09

  FutureTask的结构关系:

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_10

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_11

  WrokRunnable的结构:

   

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_12

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_13

执行器的结构:

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_14

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_15

  线程池执行器是AsyncTast的静态类属性,所有的AsyncTast共享一个线程池。。。   

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_16

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_17

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_18

  生成的线程的生命周期执行逻辑如下:

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_19

  通过刚刚线程池启动后,交由操作系统调度 --->   执行线程的run方法  --->    执行线程池对象中Worker的run方法  ---->    执行线程池对象的Runworker方法  ----->    执行SerialExecutor的run方法  ---->   执行FutureTask的run方法  ---->    执行AsyncTask的call 方法 ----然后到了DoInbackground方法。    也就是断点处。

    需要注意,第一,AsyncTask为官方提供的,具有系统无条件支持;  第二,上面的这些执行流程不是我们控制的,而是操作系统控制的。

   最后来看一看如何与主线程的通信:

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_20

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_21

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_22

android学习之远程回调原理 与 ansyncTask 实现流程_线程池_23

android学习之远程回调原理 与 ansyncTask 实现流程_异步调用_24

android学习之远程回调原理 与 ansyncTask 实现流程_主线程_25

  这说明,每个AsyncTask都绑定有一个Handler,  而且,这个Handler是与主线程通信的。。。。

  查看时间,发现一早上已经过去。。。 哭晕在厕所。。。。

举报

相关推荐

0 条评论