本文实例讲述了Android编程实现使用handler在子线程中更新UI。...; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView..." tools:context="com.example.ui.MainActivity" <TextView android:textSize="40sp" android:...id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content".../ </RelativeLayout 更多关于Android相关内容感兴趣的读者可查看本站专题:《Android线程与消息机制用法总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总
本文介绍了Android 在子线程中更新UI的几种方法示例,分享给大家,具体如下: 方式一:Handler和Message ① 实例化一个Handler并重写handlerMessage()方法 private...setText("点击安装"); break; case 2: button1.setText("打开"); break; } }; }; ② 在子线程中获取或创建消息...} }); 方式三:在子线程中调用View的post()方法 myView.post(new Runnable() { @Override public void run()...{ // 更新UI myView.setText(“更新UI”); }}); 方式四:在子线程中调用View.PostDelayed(Runnabe,long) 对方式三对补充,long...参数用于制定多少时间后运行后台进程 方式五:Handler的post()方法 ① 创建一个Handler成员变量 private Handler handler = new Handler(); ② 在子线程中调动
~一个形象地例子,♪(^∇^*) 异步:和同步则是相对的,当我们执行某个功能后,我们并不需要立即得到结果,我们额可以正常地 做其他操作,这个功能可以在完成后通知或者回调来告诉我们;还是上面那个后台下载的例子...,后台下载, 我们执行下载功能后,我们就无需去关心它的下载过程,当下载完毕后通知我们就可以了~ 3) Android为很么要引入异步任务 因为Android程序刚启动时,会同时启动一个对应的主线程(Main...假如我们在非UI线程中,比如在主线程中new Thread()另外开辟一个线程,然后直接在里面修改UI控件的值; 此时会抛出下述异常: android.view.ViewRoot$CalledFromWrongThreadException...的AsyncTask,我们可以自己开辟一个线程,完成相关操作后,通过下述两种方法进行UI更新: 前面我们学的Handler,我们在Handler里写好UI更新,然后通过sendMessage()等的方法通知...UI 更新,另外别忘了Handler写在主线程和子线程中的区别哦~ 利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,更新UI时,把Runnable
1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现...首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。...此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。...的第三个参数 * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改 * 但是可以调用publishProgress方法触发onProgressUpdate...方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行 * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
在Android里面,后台的任务下载功能是非常常用的,比如在APP Store里面下载应用,下载应用时,需要跟用户进行交互,告诉用户当前正在下载以及下载完成等。...今天我将通过使用Android的原生控件 ProgressDialog 来实现一个“模拟后台下载”的效果。...实现思路如下: 用户点击按钮,模拟开始下载 显示一个进度框,并修改后台界面上的文字,告知用户当前正在下载、需要等待 开启一个线程,模拟后台下载任务,假设下载需要3秒钟完成,让该线程等待3秒 线程执行完成后...,关闭进度框,并更新界面上的文字,告知用户下载完成 源码如下: 1、主Activity public class ProgressDialogDemo extends Activity {...", true); // 设置文字内容,告诉用户当前正在后台计算 textView.setText
如果有特别指定(通过android:process),也可以让特定组件在不同的进程中运行。无论组件在哪一个进程中运行,默认情况下,他们都由此进程的主线程负责执行。...为什么会出现ANR Android希望UI线程能根据用户的要求做出快速响应,如果UI线程花太多时间处理后台的工作,当UI事件发生时,让用户等待时间超过5秒而未处理,Android系统就会给用户显示ANR...子线程为什么不能更新UI 因为UI访问是没有加锁的,在多个线程中访问UI是不安全的,如果有多个子线程都去更新UI,会导致界面不断改变而混乱不堪。...所以最好的解决办法就是只有一个线程有更新UI的权限,所以这个时候就只能有一个线程振臂高呼:放开那女孩,让我来!那么最合适的人选只能是主线程。...子线程也可以更新UI SurfaceView是 android 里唯一一个可以在子线程更新的控件。SurfaceView可以在主线程之外的线程中向屏幕绘图。
为了帮助他人在代码分析上减少花费时间,我将介绍内存泄漏的几个例子,阐述在Android Studio中如何检查它们,当然最重要的是如何将其解决。...其通用的体系结构,线程管理和代码示例的 HTTP 请求处理在真实的生产环境并不是理想的,这些示例仅仅为了说明一个问题:在Android中,内存泄漏是一件要考虑的事情。...在Android中,如果该对象是一个Activity对象,是特别麻烦的,因为他们往往拥有大量的数据。让我告诉你,可能是什么样子。...考虑后台服务等手段, Android提供了多种在非主线程工作的方法,如HandlerThread,IntentService和AsyncTask,它们每个都有自己的优缺点。...另外,Android提供了一些机制来传递信息给主线程以更新UI。譬如,广播接收器就可以很方便实现这一点。 不要一味依赖垃圾回收器。
(TextView.java:4204) at android.widget.TextView.setText(TextView.java:4179) 这应该就是大家熟悉的报错了吧,不允许在非...UI线程中更新UI线程 既然报这个错了,那就跟进去,看看 ViewRootImpl.java 为什么报这个错,之前分享过看源码的方式。...点我看源码 既然报错已经告诉我们在哪一行了,那我们就点进去看看,可以很容易的找到 在这里要说明一下,在Android2.2以后是用ViewRootImpl来代替ViewRoot的,用来连接WindowManager...同时会创建ViewRootImpl对象,在源码中可以看到 mThread 是在ViewRootImpl 的构造方法里这样初始化的。...那现在捋一下,从上面的错误栈里,可以看到调用的流程是: at android.widget.TextView.setText(TextView.java:4347) at android.widget.TextView.checkForRelayout
1 ) AsyncTask实现的原理 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作 使用的优点:简单,快捷,过程可控 使用的缺点:...在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来. 2 )Handler异步实现的原理 在Handler 异步实现时,主要是主线程启动Thread(子线程)并生成Message,传递给Handler...使用的优点:结构清晰,功能定义明确;对于多个后台任务时,简单,清晰 使用的缺点:在单个后台异步处理时,显得代码过多,结构过于复杂(相对性) 使用AsyncTask类最少要重写以下这两个方法:doInBackground...* 注意,在这个方法中是不可以进行UI 操作的, * 如果需要更新UI元素,可以调用publishProgress(Progress......在这个方法中可以对UI 进行操作, * 利用参数中的数值就可以对界面元素进行相应地更新。
在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则: 1....确保只在UI线程中访问Android UI工具包 当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件...比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText...可以在该方法中做一些准备工作,如在界面上显示一个进度条。 (b)doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。...这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
b、当点击目录上的条目时,动态更新详细信息面板; 效果图: 看了这个需求,我们传统的做法是: a、目录Fragment在onCreate中去开启线程去访问网络获取数据,获取完成以后,通过handler...为什么封装这么个类呢?会在之后的EventBus源码解析中说明。 到此我们的EventBus的初步用法就介绍完毕了。...,则直接执行,和发布在同一个线程中。...如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用。 Async 加入后台任务队列,使用线程池调用,注意没有BackgroundThread中的一个接一个。...4、题外话 大家可以利用EventBus尝试做以下操作: 当接收到某个广播,例如短信,在界面上显示。 开启一个Service,在服务器里面启动一个定时线程,不断更新ActivityUI。
Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时...在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。...在使用的时候,有几点需要格外注意: 1.异步任务的实例必须在UI线程中创建。 2.execute(Params... params)方法必须在UI线程中调用。...("loading..." + progresses[0] + "%"); } //onPostExecute方法用于在执行完后台任务后更新UI,显示结果...答案是:AsyncTask是对Thread+Handler良好的封装,在android.os.AsyncTask代码里仍然可以看到Thread和Handler的踪迹。
; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private int...private boolean running = false; //计时状态 private boolean wasRunning = false; //保存running的状态 //app进入后台...,因此不能在ui线程中调用sleep方法 * 只允许ui线程更新界面,不能在后台线程更新界面 * * ** 使用ui线程的Handler定时更新 ** * 将任务封装到...Runnable的run方法中 ,通过Handler的 * post(立即提交任务)或postDelayed(实现定时调度)方法提交到ui线程 */ private void...textView = findViewById(R.id.timeView); int hour = seconds /3600%24;
,在子线程的run方法里面我们可以加入我们想要做的事情的代码逻辑,但是值得注意的是:子线程里面是不可以更新UI的,如果要更新UI必须在UI线程(主线程)中完成。...直接更新肯定是不行的,Android为我们提供了一个类:Handler,这个类可以对子线程发出的消息进行处理,那么我们就能通过将Handler类对象定义在主线程中然后对子线程发来的消息进行处理(更新UI...我们来看一下这里面涉及到的一些东西: Message:其实就是一个普通的类,保存了一些数据,可以储存少量信息数据,在不同的线程中作为“通信者”的角色,可以用于不同的线程交换数据。...,里面的所有代码都会在Android新建的一个子线程中运行,并且这个方法不可以进行UI操作(这个方法是在子线程中执行的),我们可以调用publishProgress(Intger…)方法来调用专门的UI...并且LogCat 中打印的信息中我们可以发现 MyAsyncTask 和 MainActivity 确实不是在同一个线程之中(MyAsyncTask 的 doInBackground 方法在子线程中执行
看到这里,我想到了一个可能的原因: 那就是我的Toast是一个全局静态的Toast对象,然后第一次是在子线程的时候show出来,这个时候ViewRootImpl在初始化的时候就会将子线程的对象作为mThread...此时内心有个困惑: 如果是子线程弹出Toast,那我就需要写Looper.prepare方法和Looper.loop方法,为什么我自己一点印象都没有。...PS:本人还得吐槽一下Android,Android官方一方面明明宣称不能在主线程以外的线程进行UI的更新,另一方面在初始化ViewRootImpl的时候又不把主线程作为成员变量保存起来,而是直接获取当前所处的线程作为...mThread保存起来,这样做就有可能会出现子线程更新UI的操作。...《Android 开发相关源码精编解析》电子书文档领取方式: 以上内容均放在了开源项目:【github】 中已收录,里面包含不同方向的自学Android路线、面试题集合/面经、及系列技术文章等,资源持续更新中
现在到了自问自答环节: 为什么Android设计只能UI线程更新UI? ...①android的UI控件不是线程安全的,多线程并发访问可能导致UI控件处于不可预期状态,即UI界面更新混乱。 ...main线程,奇怪了,我明明是在子线程实例化handler的,run方法还没开始执行,子线程的Looper对象还没被创建,那么handler在构造方法中怎么不报错呢?...比如在Handler把消息处理完了后,但是页面销毁了,这个时候可能Handler会更新UI,但是比如TextView、ImageView之类的资源引用不见了,就会抛出异常。...对于上面的代码,用户在关闭Activity之后,就算后台线程还没结束,但由于仅有一条来自Handler的弱引用指向Activity,所以GC仍然会在检查的时候把Activity回收掉。
半小时前,我的 XRecyclerView 群里面,一位群友私聊我,问题是: 为什么我的子线程更新了 UI 没报错? 我叫他发下代码我看,如下,十分简单的代码。...onResponse(Response response) throws IOException { title.setText(response.body().string()); // 这里在子线程更新了...他用了 OkHttp 的异步 enqueue 的请求,并在成功后更新了 textView 的 text。 明确一点: okhttp 的同步异步的回调都是在子线程里面的。...嫌麻烦,你可以运行下下面这段通透的子线程更新UI代码 public class TestActivity extends Activity { private TextView title;...如果你的子线程更新代码在满足下面的条件下,那么它可以顺利运行: 修改应用层的 viewRootImpl.java 源码,解除限制 把你更新代码写在 onResume 之前,例如 onCreate 里面
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。...Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时...在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。...在使用的时候,有几点需要格外注意: 1.异步任务的实例必须在UI线程中创建。 2.execute(Params... params)方法必须在UI线程中调用。...("loading..." + progresses[0] + "%"); } //onPostExecute方法用于在执行完后台任务后更新UI,显示结果 @Override
重要方法 doInBackground(Params… params):必须重写的方法,后台任务就在这里执行,会开启一个新的线程。params为启动任务时传入的参数,参数个数不定。...onPreExecute():在主线程中调用,在后台任务开启前的操作在这里进行,例如显示一个进度条对话框。...onPostExecute(Result result):当后台任务结束后,在主线程中调用,处理doInBackground()方法返回的结果。...注意事项 (1)execute()方法必须在主线程中调用; (2)AsyncTask实例必须在主线程中创建; (3)不要手动调用doInBackground()、onPreExecute()、onPostExecute...()、onProgressUpdate()方法; (4)注意防止内存泄漏,在doInBackground()方法中若出现对Activity的强引用,可能会造成内存泄漏。
其中我们可以看到在“Android本地库 & Java运行环境层”中,Android 运行时中, Dalvik是Android中的java虚拟机,可支持同时运行多个虚拟机实例;每个Android应用程序都在自己的进程中运行...你可以在自己的子线程中创建Handler与UI thread通讯。 通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。...是UI线程创造的,它可以访问UI组件,因此就更新了页面。...可以在该方法中做一些准备工作,如在界面上显示一个进度条。 2) doInBackground(Params...),将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。...这里将主要负责执行那些很耗时的后台计算工作。 可以调用publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
领取专属 10元无门槛券
手把手带您无忧上云