仓酷云

标题: JAVA网页设计我了解的Hanlder--android动静传送机制仓酷云 [打印本页]

作者: 莫相离    时间: 2015-1-18 11:15
标题: JAVA网页设计我了解的Hanlder--android动静传送机制仓酷云
对于一个大型项目,如果用java来作,可能需要9个月,并且可能需要翻阅10本以上的书,但如果用ruby来作,3个月,3本书就足够了,而.net网页编程也不过3,4本书足以,这就是区别。每个进修Android的同砚城市以为Handler是一个奇妙的工具,我也一样,入手下手我觉得我懂了Handler的机制,厥后发明本人是一孔之见,今天想一想,我可否本人完成一个Handler,让子线程与ActivityUI线程通讯,假如可以本人完成一个Handler,那一定是对Handler的动静传送机制了解浸透了。
1、引进
  Android的UI是单线程把持的,实践上,乐成的UI框架都是基于单线程的,多线程的UI框架常常由于办理并发和逝世锁的困难而胎逝世腹中。只要UI线程能把持界面控件,但我们老是但愿子线程的数据能更新到UI上,因而就有了Handler,它匡助我们完成了非UI线程向UI线程之间的通讯,Handler的利用十分复杂。
  一个复杂的示例,让一个TextView静态显现秒数:  
JAVA网页设计我了解的Hanlder--android动静传送机制仓酷云
登录/注册后可看大图
  1. 1publicclassMainActivityextendsActivity{2privatestaticfinalintUPDATE_TAG=0x01;3privateTextViewtextView;45@Override6protectedvoidonCreate(BundlesavedInstanceState){7super.onCreate(savedInstanceState);8setContentView(R.layout.activity_main);9textView=(TextView)findViewById(R.id.textview);10//启动一个线程11newThread(newRunnable(){1213@Override14publicvoidrun(){15intcount=1;16while(true){17//发送计数值到handler18mHandler.obtainMessage(UPDATE_TAG,String.valueOf(count))19.sendToTarget();20try{21TimeUnit.SECONDS.sleep(1);22}catch(InterruptedExceptione){23e.printStackTrace();24}25}26}2728}).start();29}3031publicHandlermHandler=newHandler(){32publicvoidhandleMessage(Messagemsg){33switch(msg.what){34caseUPDATE_TAG:35//显现计数值36textView.setText((String)msg.obj);37break;38}39}40};41}
复制代码

  经由过程开启一个线程,线程每隔一秒发送一次计数给handler,让handler来更新TextView的内容,新开的子线程内里不克不及间接操控TextView,由于这违背了UI线程了单线程把持标准,假如你真要这么做,一运转就会失掉CalledFromWrongThreadException非常。
2、这不就是一个察看着形式么?
  最后本人了解的Handler就是一个典范的察看着形式。sendToTarget()这个办法必定以某种体例挪用了Handler的handleMessage(Messagemsg)办法,从而完成了我们指定的义务,因而我写了上面如许一个Handler和Message
  1. /****摹拟Android的Handler,声名一个供子类掩盖的办法和多个天生动静的办法*/publicclassHandler{/****子类掩盖本办法,完成想要的操纵**@parammsg*/protectedvoidhandleMessage(Messagemsg){}publicMessageobtainMessage(intwhat){Messagemsg=newMessage(this,what,-1,-1,null);returnmsg;}publicMessageobtainMessage(intwhat,Objectobj){Messagemsg=newMessage(this,what,-1,-1,obj);returnmsg;}publicMessageobtainMessage(intwhat,intarg1,intarg2,Objectobj){Messagemsg=newMessage(this,what,arg1,arg2,obj);returnmsg;}}
复制代码

  上去就是Message类:  
  1. /****摹拟Android的Message,这里为便利演示,只写了一个机关办法。机关办法中绑定了一个Handler*/publicclassMessage{privatefinalHandlertarget;publicfinalintwhat;publicfinalintarg1;publicfinalintarg2;publicfinalObjectobj;publicMessage(Handlertarget,intwhat,intarg1,intarg2,Objectobj){this.target=target;this.arg1=arg1;this.arg2=arg2;this.what=what;this.obj=obj;}/****使用OOP的多态,挪用子类的掩盖办法*/publicvoidsendToTarget(){target.handleMessage(this);}}
复制代码

  测试代码以下:  
JAVA网页设计我了解的Hanlder--android动静传送机制仓酷云
登录/注册后可看大图
ViewCode
  真想说下面的代码表现了一个复杂的察看着形式,下面的测试代码能运转。可是,可是如许的Handler能取代Android的Handler在Activity中利用吗,用下面的Handler往替换Android的handler,了局失掉是CalledFromWrongThreadException。
  这很明显的,下面的Handler能够只仿照到AndroidHandler的形,没有仿照到其神,它只是经由过程一个回调仿照了Handler的事情表面,使用多态的手段往挪用子类的handleMessage办法,设法是好的,但这终极相称于让子线程间接挪用了handleMessage,从而让子线程对界面控件举行了操控,违反了UI界面的单线程把持准绳,必需会报CalledFromWrongThreadException的非常。
3、子线程是怎样把动静传送给UI线程
  后面仿制的Handler让子线程经由过程Message利用了UI控件,因而会报错,那Android是怎样将子历程的动静发送给UI历程。实践上Handler的事情离不开以下几个组件:

  能够看到线程启动后,会Toast"beforeLooper.loop()",但不会立即Toast"afterLooper.loop()",只要当我们按下Button后才会显现"afterLooper.loop()",由于按下Button,会给子线程的Handler发送一个空动静,而我们界说Handler抵消息的处置是挪用looper的quit(),从而停止Looper.loop()。注重quit()并非复杂的停止Looper.loop(),而是设置MessageQueue的一个标记,让MessageQueue的next()办法前往null,从而停止Looper.loop(),概况请看MessageQueue源码,这里我们来看看loop()的源码:

  别的跟踪sendToTarget()发明终极挪用的办法是MessageQueue的enqueueMessage(Messagemsg,longwhen),这个办法只是把message放进行列中,并没有挪用动静动静办法,动静的分发处置是在Looper的loop()中举行的。
4、是甚么工具再帮UI线程跑Looper.loop()
  如今理清了后面的成绩又来了新的成绩,是谁在帮UI线程跑Looper.loop():

  假如既要满意UI线程的单线程把持标准,又要让逝世轮回Looper.loop()跑着不遗漏一个动静,还要呼应onCreate()、listener,只要一种举措,那就是对界面的一切的操纵都是由loop来驱动分发的,onCreate(),onResume()...各类listener都是Looper.loop()来挪用。
  实践上Android就是这么干的,要理清onCreate等各类办法绑定的Message的历程不简单,可是我们能够很复杂地考证我们的下面的假定,那就是在onCreate(),onResume(),和listener的呼应办法内里激发非常,然后看一下栈信息,我们在onCreate发放中加一句inta=1/0,看看非常的栈信息:
JAVA网页设计我了解的Hanlder--android动静传送机制仓酷云
登录/注册后可看大图

  当发明奇妙的Handler本来就是靠一个逝世轮回来保持的,统统就变得名顿开了。

Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流.
作者: 第二个灵魂    时间: 2015-1-20 18:52
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
作者: 不帅    时间: 2015-1-29 14:59
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
作者: 爱飞    时间: 2015-2-5 15:41
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
作者: 莫相离    时间: 2015-2-12 19:40
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
作者: 老尸    时间: 2015-2-12 19:49
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
作者: 冷月葬花魂    时间: 2015-3-3 04:45
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
作者: 飘灵儿    时间: 2015-3-11 05:33
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
作者: 兰色精灵    时间: 2015-3-19 11:56
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
作者: 深爱那片海    时间: 2015-3-27 21:12
是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言




欢迎光临 仓酷云 (http://ckuyun.com/) Powered by Discuz! X3.2