为了线程安全,android在子线程中是不允许对界面元素进行刷新的,比如
final ImageButton button = (ImageButton)this.findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { textView.setText("更改文本内容"); } }).start(); } });
是会报错:Only the original thread that created a view hierarchy can touch its views.
如果要在子进程刷新界面的话,可以使用android的handler机制,正确的使用方法如下:
final ImageButton button = (ImageButton)this.findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { button.post(new Runnable() { @Override public void run() { tv.setText("click"); } }); } }).start(); } });
此列中button.post只所以不会报错是因为他的父类View中有一个handler的引用,相当于是handler.post,
android中有一个保护机制,就是当界面在刷新时超过一段时间无响应时(20秒左右)程序就会退出,所以一般进行比较耗时的操作时必须另起一个线程,比如下载资源时,在整个过程中,我们一般同时还需要刷新下载的进度,如果是直接在子线程中刷新界面的话就会出现上面类似的错误。这个时候我们就需要使用到handler。具体列在如下:
handler = new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case 1: tv.setText("剩余下载时间:" + msg.arg1); break; case 2: tv.setText("下载完成"); break; } } }; final ImageButton button = (ImageButton)this.findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { int time = 10000; while(time > 0){ try { Thread.sleep(1000); time -= 1000; Message msg = new Message(); msg.what = 1; msg.arg1 = time; //也可以发送对象 //msg.obj = obj; handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } //下载完成,发送一个空消息 handler.sendEmptyMessage(2); } }).start(); } });
相关推荐
### MFC子线程中更新控件内容的两种办法 #### 概述 在MFC应用程序开发中,经常需要在子线程中处理耗时任务,以提高程序的响应速度和执行效率。然而,直接在子线程中更新UI控件可能会导致程序崩溃或不稳定,这是...
本文将深入探讨如何在VS2017的MFC环境中,通过全局函数的方式安全地在子线程中更新控件内容。 首先,理解Windows的消息队列和线程模型是关键。主线程负责处理应用程序的用户界面交互,包括处理消息队列中的消息。当...
总结来说,子线程中更新UI线程主要有Handler+Looper、Runnable+runOnUiThread以及AsyncTask这三种方式。Handler提供了更灵活的消息机制,适合复杂的同步需求;Runnable+runOnUiThread则更为简洁,适合快速实现简单的...
// 子线程中通过UI线程上下文更新UI } private void SetLabelText(object text) { this.label1.Text = text.ToString(); } ``` 在这个例子中,`Post`方法会异步地执行`SetLabelText`方法,确保UI更新在正确的...
在MFC(Microsoft Foundation Classes)框架中,子线程与主线程交互并操作用户界面(UI)时,可能会遇到一些特定的问题,特别是当涉及到退出、死锁或超时的情况。以下是对这些知识点的详细说明: 1. **MFC 子线程**...
例如,如果要更新一个`CEdit`控件的文本,可以定义一个自定义消息`WM_USER_UPDATE_CTRL`,然后在子线程中调用: ```cpp LRESULT lResult; WPARAM wParam = static_cast(控件的ID); LPARAM lParam = reinterpret...
创建一个新的Windows窗体,添加一个Label控件,然后在子线程中调用`WorkerThreadMethod`,即可看到UI控件的更新。 总之,通过合理使用委托、`Invoke`或`BeginInvoke`,我们可以安全地在子线程中操作UI控件,提高...
Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码...
"QT子线程更新主线程"这个主题涉及到如何在后台线程(子线程)执行耗时操作,并将结果安全地传递到用户界面线程(主线程),以避免阻塞UI,保持其流畅性。 Qt库提供了QThread类来支持多线程编程。子线程通常用于...
本文将深入探讨如何在Android环境中实现两个子线程之间的通信。 首先,理解Android线程模型至关重要。主线程,也称为UI线程,负责处理用户界面的更新和事件响应。为了不阻塞主线程,我们通常会在子线程中执行耗时...
在编程领域,特别是涉及到用户界面(UI)的开发时,多线程技术是不可或缺的一部分。在Windows编程中,MFC(Microsoft Foundation Classes)是一个用于构建C++应用的库,它提供了一种简单的方式来处理线程。本文将...
本文将深入探讨在子线程中更新UI的三种有效方法,并同时讲解如何在Android中获取和处理Message,这是异步通信的关键。 1. **Handler-Looper机制** Handler、Looper和Message是Android系统提供的异步通信框架,用于...
在Android应用开发中,由于主线程负责用户界面的更新与交互,因此对于耗时操作,如网络请求和图片加载,必须在子线程中执行,以免阻塞UI导致应用无响应(ANR)。本主题主要关注如何在Android中利用子线程加载URL上的...
在编程领域,尤其是在GUI(图形用户界面)应用开发中,"子线程创建界面组件"是一个重要的主题。这个话题涉及到多线程技术以及如何在非主线程中安全地构建和更新用户界面。以下是对这个主题的详细解释: 1. **线程与...
然而,由于GUI(图形用户界面)组件的设计原则,子线程不能直接修改主UI(用户界面)元素,因为这可能导致界面的不稳定性。为了解决这个问题,Qt提供了一种安全的方式来实现子线程与主线程之间的通信,确保UI的正确...
本实例主要探讨如何在子线程中更新View,通过两种方式:Post方式和Handler方式。 一、Post方式 Post方式主要是利用View类中的post()方法,这个方法会在View的关联的消息队列中添加一个Runnable任务,当消息循环运行...
4. **避免阻塞**:子线程中的定时器任务不应长时间运行或阻塞,否则会影响子线程的事件循环,导致其他定时器或事件无法正常处理。 以下是一个简单的示例,展示了如何在子线程中创建和使用`QTimer`: ```cpp // ...
//子线程中通过UI线程上下文更新UI } private void SetLabelText(object text) { this.label1.Text = text.ToString(); } ``` 在上面的代码中,我们首先获取UI线程的同步上下文,然后在子线程中使用Post方法...
C# winform 多线程 让子线程也能操作界面的方法 源代码