`
CshBBrain
  • 浏览: 654866 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
B7d9bf34-126e-301f-819e-81f2615b5a2a
开源WebSocket服务...
浏览量:145950
Group-logo
HTML5移动开发
浏览量:138795
社区版块
存档分类
最新评论

Android画面UI中的线程约束

 
阅读更多

转自:http://blog.csdn.net/yihui823/article/details/6722784

 

这是我自己提炼的一句简单说法:

在非UI主控线程中,不得修改UI的显示。

 

主要的意思,就是在UI主控线程中,我们的代码可以随意改变UI各个对象的显示效果,包括文字、是否可见、大小等等属性。

 

什么是主控线程?

    这么简单的说吧,进入onCreate、onResume等系统调用的函数的时候,这个时候就是主控线程。

    当然是系统调用进来的,不是我们自己的代码调用onCreate等函数。

这也包括按钮等控件的事件监听,例如onClick函数等。

那么相对应的,不在这些函数里调用的代码,执行进来的就不是UI主控线程。

这个时候,系统会抛出异常:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

 

这个限制在java本身的swing中也是存在的。如果允许了任意线程去改变UI的显示,那么画面一定会乱套的。

以下是一个错误的代码:

 

 

[java] view plaincopy
  1. public class TemppjActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.    
  7.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  8.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  9.          
  10.         setContentView(R.layout.main);  
  11.          
  12.         final Button btn = (Button) findViewById(R.id.btn);  
  13.         btn.setOnClickListener(new OnClickListener() {  
  14.            @Override  
  15.            public void onClick(View v) {  
  16.               btn.setText("I Clicked!");  
  17.            }  
  18.         });  
  19.          
  20.         final DateFormat f = DateFormat.getDateTimeInstance();  
  21.          
  22.         TimerTask t = new TimerTask() {  
  23.            @Override  
  24.            public void run() {  
  25.               <span style="color:#ff0000;">btn.setText(f.format(new Date()));</span>  
  26.            }  
  27.         };  
  28.          
  29.         Timer ti = new Timer();  
  30.         ti.schedule(t, 05000);  
  31.     }  
  32. }  



 

 

看红色的这一行,就是在一个定时运行的线程中去控制按钮的显示文本。这个程序运行就会有CalledFromWrongThreadException异常出现。

 

那么,如果我们有这个需求怎么办?能不能做到呢?当然是可以做到的。这个时候,就需要用到:Handler

我们先看代码需要改成什么样:

 

 

[java] view plaincopy
  1. public class TemppjActivity extends Activity {  
  2.      
  3.     private Handler handle;  
  4.      
  5.     /** Called when the activity is first created. */  
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.    
  10.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  11.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  12.          
  13.         setContentView(R.layout.main);  
  14.    
  15.         final Button btn = (Button) findViewById(R.id.btn);  
  16.         final DateFormat f = DateFormat.getDateTimeInstance();  
  17.          
  18.         handle = new Handler() {  
  19.          public void handleMessage(Message msg) {   
  20.                btn.setText(f.format(new Date()));  
  21.              };  
  22.         };  
  23.          
  24.         btn.setOnClickListener(new OnClickListener() {  
  25.            @Override  
  26.            public void onClick(View v) {  
  27.               btn.setText("I Clicked!");  
  28.            }  
  29.         });  
  30.          
  31.          
  32.         TimerTask t = new TimerTask() {  
  33.            @Override  
  34.            public void run() {  
  35.               handle.sendEmptyMessage(0);  
  36.            }  
  37.         };  
  38.          
  39.         Timer ti = new Timer();  
  40.         ti.schedule(t, 05000);  
  41.     }  
  42. }  



 


也就是说,我们在非UI主控线程中,如果需要修改UI,则向UI主界面发送一个消息。

handle.sendEmptyMessage(0);

消息可以很复杂,我们这里只是发送一个空消息过去。

在主控线程中,会由handler来处理这些消息,收到消息后来处理各个控件的改变。

在handleMessage函数中我们可以具体控制UI应该如何改变。

分享到:
评论

相关推荐

    Android源码——UI界面源码.zip

    8. **异步更新UI**:由于Android的UI线程不能长时间阻塞,所以涉及耗时的操作(如网络请求)应放在后台线程执行。通过Handler、AsyncTask或LiveData等工具,可以安全地在后台线程完成工作并更新UI。 9. **可访问性...

    Android-UI.zip_android 注册_android 注册 界面_android注册

    通过阅读"Android UI.pdf",开发者将能够深入理解如何在Android环境中创建一个完整且用户友好的注册界面,包括设计原则、实现方法以及可能遇到的问题和解决方案。这份文档应该涵盖以上提到的多个方面,帮助开发者...

    Android高级开发实战 UI、NDK与安全

    《Android高级开发实战 UI、NDK与安全》是一本针对Android开发者进阶的权威指南,中文版的出版使得更多的国内开发者能深入理解Android平台的高级技术。本书主要涵盖了三个核心领域:用户界面(UI)设计与优化、原生...

    五、Android用户界面(UI)-Android开发与实践

    在Android开发中,用户界面(UI)设计是至关重要的,因为它直接影响到用户的体验和应用程序的易用性。本章节将深入探讨Android UI的基础知识,包括控件使用、布局管理、菜单操作以及事件处理。 1. **用户界面基础**...

    Android UI-最新版糗事百科布局,带简单数据加载

    7. **异步处理**:由于数据加载通常涉及网络操作,因此需要在后台线程进行,避免阻塞UI线程。可以使用AsyncTask、Handler、Runnable配合Looper,或者使用现代的协程(Coroutines)来实现。 8. **适配器(Adapter)*...

    Litho:在 Android 上构建高效 UI 的声明式框架-开源

    通过将其布局系统与传统的 Android View 系统解耦,Litho 可以摆脱 Android 强加的 UI 线程约束。 Litho 使用 Yoga 进行布局并自动减少您的 UI 包含的 ViewGroup 的数量。 除了 Litho 的文本优化之外,这还允许更小...

    android中文帮助文档

    12. **多线程与异步处理**:由于Android应用的UI线程不允许执行耗时操作,因此需要理解线程和Handler、AsyncTask等异步处理机制。 13. **网络编程**:介绍如何进行HTTP请求,使用OkHttp或Volley库,以及WebSocket...

    Android应用源码之高仿360云盘UI.zip

    在本压缩包“Android应用源码之高仿360云盘UI.zip”中,包含了一个针对Android平台的源码项目,旨在实现一个类似于360云盘的应用用户界面(UI)。这个源码实例对于学习Android开发,尤其是界面设计和交互逻辑的...

    Android 仿360恶意广告拦截扫描UI效果源码.zip

    7. **异步处理(AsyncTask or LiveData)**:为了保持UI的流畅,扫描操作通常应在后台线程中执行,可以使用AsyncTask或者结合MVVM架构的LiveData实现。 8. **UI/UX设计原则**:遵循Android Material Design指南,...

    Android应用源码Adroid UI 界面绘制原理分析.zip

    9. **多线程绘制**:虽然通常UI绘制都在主线程中进行,但为了提高性能,可以使用`postInvalidate()`或`postDelayed()`方法异步更新UI。然而,必须注意避免在非主线程中直接修改UI,以免引发运行时错误。 10. **...

    android 经典代码例子

    Android支持线性布局、相对布局、约束布局等多种布局方式,帮助开发者构建不同复杂度的UI。 4. **Fragment**:Fragment是Android 3.0引入的概念,它允许开发者在Activity中添加和管理多个独立的UI部分。这对于在...

    Android UI界面漂亮的天气预报源码.zip

    - **布局管理器**:源码中可能使用了线性布局(LinearLayout)、相对布局(RelativeLayout)、帧布局(FrameLayout)或约束布局(ConstraintLayout)来组织界面元素。 - **自定义View**:为了实现独特的天气展示...

    Android UI开发专题(四) View自绘控件

    如果需要立即更新,可以使用`postInvalidate()`,这将在UI线程的下一个循环中触发绘制。 ```java // 更新指定区域 invalidate(left, top, right, bottom); // 更新整个View invalidate(); // 在非UI线程中更新 ...

    Android代码-[安卓开源]高仿微信5.2内测版UI项目.zip

    【Android代码】与【安卓开源】的结合,指的是在Android平台上...通过这个项目,开发者不仅可以提升Android UI设计和实现能力,还能掌握到实际项目开发中的许多最佳实践,为自己的Android开发技能树增添宝贵的经验。

    Android应用源码之奇艺高清UI界面源代码-IT计算机-毕业设计.zip

    通过这个毕业设计项目,学习者不仅能掌握Android应用开发的基本技能,还能深入理解UI设计原则,以及如何在实际项目中应用这些知识。通过阅读和分析源码,可以提升编程技巧,为未来的职业发展打下坚实基础。

    Android中View绘制流程以及invalidate()

    当调用`invalidate()`时,Android系统会把该View添加到待绘制队列中,稍后在UI线程的空闲时间进行重绘。这个过程会重新执行上述的测量、布局和绘制三个步骤。`invalidate()`可以接受一个Rect参数,用来指定需要重绘...

    android实现贪吃蛇源码

    总的来说,"android实现贪吃蛇源码"项目能让你深入理解Android开发中的许多关键概念,包括UI设计、事件处理、多线程、动画效果、游戏逻辑以及数据管理等。通过对`SnakesGame`的分析和学习,初学者能够快速提升自己的...

    Android应用源码之高仿微信5.2内测版UI项目-IT计算机-毕业设计.zip

    这个项目的主要目的是让学生在实践中学习和理解Android应用的开发流程,尤其是涉及到用户界面(UI)的设计和实现。通过分析和研究这个源码,我们可以深入探讨以下几个关键知识点: 1. **Android Studio使用**:作为...

    Android程序研发源码模仿UC等软件启动画面加载时闪烁点的样式.zip

    在Android应用开发中,启动画面(Splash Screen)是用户打开应用程序时首先看到的界面,它通常用来展示品牌标识、加载应用程序资源或者进行初始化操作。UC浏览器等软件在启动时会显示一个带有闪烁点的加载动画,这样...

    android编程实例

    通过实例,你可以学习如何发送GET和POST请求,处理JSON或XML数据,实现异步加载以避免阻塞UI线程。 除此之外,Android的通知系统也是关键功能。开发者可以使用NotificationCompat类来创建通知,并通过...

Global site tag (gtag.js) - Google Analytics