您的位置:首页 > 移动开发 > Android开发

Android Runnable 运行在那个线程

2013-07-16 12:42 357 查看
Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:
Handler mHandler=new Handler();mHandler.post(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stub}});
官方对这个方法的解释如下,注意其中的:“The runnable will be run on the user interface thread. ”boolean android.view.View .post(Runnable action)Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.Parameters:action The Runnable that will be executed.Returns:Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.我们可以通过调用handler的post方法,把Runnable对象(一般是Runnable的子类)传过去;handler会在looper中调用这个Runnable的Run方法执行。Runnable是一个接口,不是一个线程,一般线程会实现Runnable。有关 Looper、Handler,Thread 关系可以看这篇博客:Android 的消息队列模型/article/4865502.html这里我们看代码 mHandler.post(new Runnable(){ 好像是new 了一个 interface, 其实是new的一个实现Runnable的匿名内部类(Inner Anonymous Class),这是很简练的写法。上面的代码可以看成是: new anonymousClass() implement interface{ [改写interface method]}Runnable是一个接口,不是一个线程,一般线程会实现Runnable。 所以如果我们使用匿名内部类是运行在UI主线程的,如果我们使用实现这个Runnable接口的线程类,则是运行在对应线程的。具体来说,这个函数的工作原理如下:View.post(Runnable)方法。在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。如下图,前面看到的代码,我们这里Message的callback为一个Runnable的匿名内部类这种情况下,由于不是在新的线程中使用,所以千万别做复杂的计算逻辑。参考资料:Android中的Handler, Looper, MessageQueue和Thread/article/4907558.htmlAndroid系列之Message机制的灵活应用http://tech.ddvip.com/2010-07/1280393505158258_3.html转载地址:/article/4865503.html

AsyncTask、View.post(Runnable)、ViewTreeObserver三种方式总结frame animation自动启动

在一些需求中,需要在程序运行时动画自动启动,我们也知道在android提供的Tween Animation和frame animation。但是当使用frame animation时候,启动FrameAnimation动画的代码anim.start();不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。现在问题是如何才能让程序启动时自动的启动动画?可以试一下在onStart方法中,但是结果同样不能如我们所愿。这样不行,继续尝试,使用Handler试一下!代码如下:
Handler handler=  new Handler();//在onCreate方法中:handler.postDelayed(new Runnable(){@Overridepublic void run() {frameAnim.start();}},1000);
总结的三种自动启动frame animation的方法:首先使用AsyncTask:Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。AsyncTask使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。对于AsyncTask这里就不多说了,也就是用到一点。
imageV.setBackgroundResource(R.anim.myframeanimation);frameAnim = (AnimationDrawable) imageV.getBackground();?class RunAnim extends AsyncTask<String, String, String>{@Overrideprotected String doInBackground(String... params) {if(!frameAnim.isRunning()){frameAnim.stop();frameAnim.start();}return "";}}//onCreate方法中执行RunAnim runAnim=new RunAnim();runAnim.execute("");
这样就能在是程序自动执行frame animation了。其次使用View.post(Runnable)的方式:?
imageV.post(new Runnable(){@Overridepublic void run() {frameAnim.start();}});
文档:boolean android.view.View .post(Runnable action)Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.即可把你的Runnable对象增加到UI线程中运行。这样也能正常启动frame Animation。第三就是使用ViewTreeObserver.OnPreDrawListener listener:当一个视图树将要绘制时产生事件,可以添加一个其事件处理函数:onPreDraw
OnPreDrawListener opdl=new OnPreDrawListener(){@Overridepublic boolean onPreDraw() {animDraw.start();return true;}};//onCreate方法中imageV.getViewTreeObserver().addOnPreDrawListener(opdl);
?以上即是总结的三种自动启动frame animation的方法,当然,对于android线程的处理,UI更新操作实现,肯定有其他的方法。以上描述中如有错误,还望多多包含与指教!!!转载地址:/article/5641916.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: