android 只有UI线程可以刷新界面,其他副线程不行,这样就需要副线程通过通信消息修改刷新和修改界面。
有2种方式可以实现:
AsyncTask,Handle
AsyncTask
android提供的简单用于异步通讯的线程,有句话,越完善的东西使用越麻烦。
主要四个实现接口:
onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
调用注意
1) Task的实例必须在UI 线程中创建
2) execute方法必须在UI 线程中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。
4) 该task只能被执行一次,否则多次调用时将会出现异常。(很久之前的资料,可能不准)
5)doInBackground方法返回值和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。
可以看到这个线程有副线程的接口处理doInBackground,也有UI线程的接口处理onProgressUpdate,在启动线程时可以传入泛类参数。
实战注意点:
继承 class MyThread extends AsyncTask<String, Integer, Integer> 泛类对应的3个接口泛类参数
protected Integer doInBackground(String... params)
protected void onProgressUpdate(Integer... values)
protected void onPostExecute(Integer result)
Handler
Handler类可以看做工具类,用来向消息队列中插入消息的。实例化时自动绑定调用的线程Looper,当处理消息时在该线程中执行。利用这个特性,副线程发送消息,接受消息后在主线程处理,达到主线程和副线程的通讯。
Looper类是用来封装消息循环和消息队列的一个类。
(1) Looper类用来为一个线程开启一个消息循环。
默认情况下android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。)
Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。
(2) 通常是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。
默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,Handler在主线程中定义,那么它是与主线程的Looper绑定。
mainHandler = new Handler() 等价于new Handler(Looper.myLooper()).
Looper.myLooper():获取当前进程的looper对象,类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。
(3) 在非主线程中直接new Handler() 会报如下的错误:
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。
(4) Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。
注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。
(5) 基于以上知识,可实现主线程给子线程(非主线程)发送消息。
把下面例子中的mHandler声明成类成员,在主线程通过mHandler发送消息即可。
总结,一般都是绑定主线程的handler,达到通讯目的,在副线程中发送消息。若要创建副线程中绑定handler,则必须先创建副线程的looper,已达到循环发送消息的目的。有两种方式达到这个目的:
1、通过handler+Looper两个类。
2、通过HandlerThread这个类,这个是android提供的利用Looper和Handler继承Thread完成。
使用这个主意事项:
1、Looper.loop()导致run方法挂机,在收到消息时,会运行handler的handleMessage去处理消息。
2、在绑定Handler时需要判断Looper是否已经创建。
分享到:
相关推荐
在Android应用开发中,网络通信是必不可少的一部分,用于获取服务器数据或者发送用户操作到服务器。本资源提供的"android ...通过研究和使用这些源码,你可以更好地理解和掌握Android中同步与异步网络请求的实现原理。
在Android开发中,异步加载是一项至关重要的技术,主要用于解决UI线程阻塞问题,提升应用性能和用户体验。Android Studio是Google官方推出的Android应用程序开发集成开发环境(IDE),它为开发者提供了丰富的工具集...
本文将深入探讨Java和Android平台上的异步编程小技巧,并以"android业务异步编程小技巧.zip"和"java业务异步编程小技巧.zip"中的示例作为参考,讲解如何有效地进行异步任务处理。 首先,我们要理解Android应用中的...
以下是一个简单的示例,展示了如何同步下载百度首页的内容: ```java OkHttpClient client = new OkHttpClient.Builder() .readTimeout(5, TimeUnit.SECONDS) .build(); Request request = new Request.Builder()...
总之,Android网络图片异步加载是一个涉及多方面技术的复杂过程,包括线程池的使用、图片加载类的封装、缓存策略以及与主线程的同步。理解和掌握这些知识点对于提升Android应用的性能和用户体验至关重要。
这个库提供了丰富的功能,可以方便地在Android Studio项目中集成,使得图片的异步加载和缓存变得简单高效。 首先,我们要理解为什么需要图片异步加载。在Android设备上,如果直接在主线程中加载图片,尤其是大图或...
本篇文章将深入探讨Android和iOS在异步绘制与显示方面所使用的工具类。 在iOS中,异步绘制主要依赖于CALayer的子类,如CATiledLayer和YYAsyncLayer。CATiledLayer主要用于处理大图的分块加载和绘制,适用于地图或者...
4. **同步加载策略**:虽然异步加载是提高用户体验的关键,但在某些情况下,如列表项较少或者图片大小较小时,可以考虑同步加载,以避免乱序问题。 5. **监听加载状态**:通过监听图片加载库的事件回调,可以确保在...
AsyncTask_简单演示AsyncTask异步操作,写一个简单的AsyncTask异步操作解决上一篇文章提到的线程阻塞问题,对应我的博客《网易博客迁移:Android专题之AsyncTask(二)简单演示AsyncTask异步操作》,有问题欢迎留言...
因此,"Android异步操作数据库"是一个至关重要的知识点,它涉及到如何在后台线程中安全、高效地处理数据库事务,避免阻塞UI。 1. **AsyncTask** Android提供了一个内置的异步任务类`AsyncTask`,适用于短时间的...
本项目为基于Android Studio的OkHttp框架实现,包括同步/异步GET和POST请求设计源码,共计42个文件,涵盖17个XML配置文件、10个WebP图片文件、3个Git忽略文件、3个Gradle构建文件、3个Java源文件、2个属性文件、1个...
为了避免这个问题,可以将AsyncTask与Activity的生命周期绑定,或者使用其他更高级的异步处理机制,如IntentService、LiveData或Coroutines。 现在,让我们转向源码分析。在源码中,你会看到AsyncTask类是如何维护...
- **内存泄漏**:异步任务与创建它的Activity有隐式绑定,若不正确管理,可能导致Activity泄露。 - **生命周期同步**:当Activity被销毁时,需要取消正在执行的异步任务,避免资源浪费。 - **并发限制**:一个...
在Android应用开发中,图片异步下载是一项至关重要的技术,特别是在构建内容丰富的应用程序时,如社交媒体、电商或者新闻阅读应用。这些应用往往需要加载大量的图片,如果采用同步方式下载,可能会导致用户界面阻塞...
10. **多线程编程**:理解线程间的通信和同步机制,如Handler、Looper和Message,这对于正确实现异步加载至关重要。 通过这个"Android异步加载的学习demo",开发者可以深入学习上述技术,并通过实践提升自己的技能...
总结来说,Android中的多线程异步断点续传技术涉及了文件操作、网络请求、线程同步等多个方面,理解并掌握这些知识对于提升应用性能和用户体验至关重要。通过上述示例和解释,开发者可以更好地理解和实现这一功能。
在Android开发中,异步获取网络图片是一项基本且重要的任务,尤其在构建用户界面时,为了提高用户体验,避免UI线程被阻塞,通常会采用异步加载策略。本话题将深入探讨如何在Android中实现这个功能。 首先,我们要...
Android强制异步转同步方法,供大家参考,具体内容如下 Android系统中规定耗时任务需要在异步线程中进行,特别是网络请求必须在异步线程中进行否则会抛出NetworkOnMainThreadException,但是在一些特殊的情况我们需要...
在Android开发中,异步加载网络图片是一项常见的需求,特别是在数据密集型的界面如GridView中。这个Demo展示了如何实现这一功能,同时支持用户点击图片查看大图。以下将详细讲解这个Demo涉及的关键知识点。 首先,...