android学习之多线程编程

   本来昨晚想整理来着,结果竟然太累了直接睡着。。  尽管今天也比较累了,但是还是要咬牙坚持一下将这里的知识整理一下再去娱乐或者休息。。

   接触android后,我们知道,非UI线程不能操控UI。 android4.0以后,主线程还不能进行联网操作。  这使得我长期以来养成的编程思路完全找不到思路了。。 因为以前我的思路都是单线程的,即我的操作要么完成,要么抛错,要么阻塞的这样一种非黑即白的情况。     通过在实训的时候,我们学习到了Handler,就是处理这样一个问题的关键。。 

      先整理一下Handler相关的知识:

             Handler,中文释义处理器。 
             Handler作为一种中介者而存在于两个线程间。  它的核心类有:  Handler,Message,MessageQueue,Loop。 

             Handler线程间通信的方式通过对象实例,也就是地址的方式。

             Handler实例化在主线程中 与 其它线程中,它的使用方式是不一样的。

             通常Handler的执行方式:在主线程中实例化一个Handler对象;通过 参数传递,或者 地址共享(内部类,继承关系)传递给其它线程;其它线程通过该实例对象发送信息;  信息会先到主线程的MessageQueue等待; 由Looper 按照先进后出的方式从MessageQueue中取出Message,根据Message属性分发给对应的Handler进行处理!

              Message相当于一个容器,即可以包含普通消息,也可以包含对象。Message与Hander的关系是独立的。  理解上可以将Handler是对每个message处理的工作者。    也就是说,当一个Activity有较多的ui需要处理的时候,只需要定义一个Handler,然后通过Message的what属性来区别哪些是对应的操作。。   这也是推荐的做法。   还有一种就是,我当时使用的,对每个ui对象都生成一个Handler,每个Handler只对应一个Message。  在使用图中还出现了Hanler的嵌套,十分的难以理解。

              对同一个Handler,内部可以有多个Message,用以标志不同的操作。  不同的Handler之间的Message是独立的。

              对一个android 应用  主线程  进行断点调试的时候,经常会看到一个类和方法,Looper。 它是在其它的逻辑操作处理完后执行的语句。并且位置主线程不会因为执行完而被回收导致程序结束的。   同时它也是与Handler协作的关键。   子线程如果要用Handler,需要为线程绑定Looper。  绑定后开启loop方法,应该是在线程的结尾。

              handler的作用我的理解有俩点:  一,通过handler的消息传递机制,我们可以委托其它线程做一些操作;   二,通过handler的方式,我们可以从用户视角执行代码中的任意代码片段。。。!!!   具体是这样的,一般来说,我们代码在主线程的执行主要是通过语法支撑的 众多函数 连续调用跑起来的。(其本质也就是指令)。   那么我们可以将某个片段封装长一个方法,然后通过Handler执行。。  爽歪歪!  还有一种场景,就是我们可以在代码编译后还能动态修改属性,或者方法,甚至是修改代码,插入代码等等。   也很简单,就是封装成一个方法。   至于插入的代码,我们可以这样,写好一段文本,然后调用编译的方法,最后将编译后的地址传回。。。。       这不就是spring面向切面的思想吗??  不知道它是具体的实现时怎样的,但是我可以猜测一下,用一个注解代表代码的这个位置放了一个“Handler”,将该“Handler”的设置消息的方式以配置文件的方式开放已达到解耦的目的。  最后就能实现面向切面了。。 

               子线程使用Looper的步骤:  Looper.prepare();    线程逻辑;   Looper.loop();

接着来了解一下基于监听的事件处理机制,与基于回调的事件处理机制与多线程的逻辑:

       在早些时候,整理了一下android的两种事件处理机制,刚刚又整理了一下android的事件传递机制。   有了一些感悟与理解,特此记录:

       1.事件监听的事件处理机制,与回调的事件处理机制,应该都是多线程的。事件监听时,一个线程用于不断的监听状态的改变和一些简单逻辑的处理,另一个线程负责触发中断;    回调机制时,一个线程用于发出中断,另一个远程的进程,或者线程通过调用回调接口的方法,来实现回调。 

       2.android的视图组建的监听以及回调的逻辑:  用户触发硬件--> 硬件产生事件发送给操作系统-->  操作系统发送给Android--->  Android接收感受到事件,调用回调 --->   通过回调的属性判断处理后是否继续往外传 --->  若需要,则往外传--->   被管理器检测到事件,则看是否有注册监听,有则派发给相关监听器。 没有则传递给activity。

       3.视图的状态回调是本身的行为,是内部的。   监听器的设置是外部的,需要单独设置。  若相应的事件回调的返回值为false,则会继续往外传给监听器。  也就是说,同一个事件,应该即可以通过状态回调执行一次状态的改变,又可以通过监听的回调实现一些其它的逻辑。   Button控件根据状态 设置 <selector> 设置背景色很好的说明了这一点。  同时,可以看到状态回调的参数为 事件, 监听器的参数也是事件。

        4.多点触控通过事件来识别。  当前面已经存在按下实现,再发送按下事件,就会调用多点触控的事件。。 释放的时候也是同理。。

接着整理一下,关于TextView监听的两个实用的案例:

     关键类:TextWatcher,sdk官方的类。

     一,在文本输入框实现删除按钮:

          核心实现:setCompoundDrawableWithIntrinsicBounds(null,null,图片资源,null);  该方法应该是View提供的一个方法。

                           触发的事件的核心实现:new Rect().contains(event.getRawX(),event.getRawY());

       二, 在文本框中实现 密码的可见与隐藏:

            核心实现:  new EditText().setTransformationMethod(HideReturnsTransformationMethod.getInstance());

                             new EditText().setTransformationMethod(PasswordTransformationMethod.getInstance());

接下来整理关于多线程的最后一个处理类,AsyncTask的相关内容:

               一,android实现得异步的任务有三种:  一个是handler, 一个是 静态方法:Activity.runOnUiThread(Runnable)的使用。  还有一个就是AsyncTask。

                二,  AsyncTask第一次接触是在 java的 awt编程中有用到;  AsyncTask 相比起Handler显得更简单,快捷。

                三, 很多的第三方框架,如Volley, OkHttp, android-async-http,XUtills等都是基于AsyncTask的。

         四 , AsyncTast类中的方法,有一些是主线程调用的,有一些是其它线程调用的。 核心方法包括: DoInBackground(params ...);   onPostExecute(Result);    既然是在通过了多个线程调用,那么它们应该是通过回调机制实现的。

                五,注意事项:Task的实例,execute方法必须在主线程实例和使用。  task只能被执行一次,否则会出现异常。

                六. AsyncTast本身就代表了一个非ui线程。 但是它的实现是通过系统给实现的,所以在android层面看不到它的实现。

                七. AsyancTast具有三个泛型,<Params,progress,Result> ,Params指示 启动线程后,线程运行时需要以来的参数,是个集合;  Progress指示后台任务执行的百分比;   Result指示执行任务完成的返回值。

                它大概的实现过程: 

                                              

                                              

  看到Runnable,我悬着的心终于放下了。。接着调试看看结果:

最后来看一看,主线程是如何通过线程池新开一个线程:

   发现内容还是比较多的,要记录的话得找个时间仔细来看看,对自己的成长还是很有必要的。   找个时间,那就明天吧。。  嗯嗯 ,是时候去海皮海皮了!!

猜你喜欢

转载自blog.csdn.net/qq_36285943/article/details/82717777