内容简介:Android中,当需要进行一些耗时操作时,常常需要开启一个多线程来进行耗时操作,但是当要进行UI操作时则需要在主线程中进行,因此这就涉及到了进程间的切换.主线程定义Handler,并重写handlerMessage()方法,当开启一个线程并对其进行耗时操作结束后,要想跳转到主线程进行UI操作时,则需要定义一个Message消息,然后用handler把消息发出去,并在handlerMessage()中进行接收处理,从而实现异步.asyncTask是Android提供的一个方便我们在子线程中进行UI操作的工具
Android中,当需要进行一些耗时操作时,常常需要开启一个多线程来进行耗时操作,但是当要进行UI操作时则需要在主线程中进行,因此这就涉及到了进程间的切换.
1.1 异步消息处理机制(Handler)
主线程定义Handler,并重写handlerMessage()方法,当开启一个线程并对其进行耗时操作结束后,要想跳转到主线程进行UI操作时,则需要定义一个Message消息,然后用handler把消息发出去,并在handlerMessage()中进行接收处理,从而实现异步.
解析异步消息处理机制:
- Message:在线程之间传递的消息,可携带少量的信息,在线程之间进行数据交流
- Handler:处理者,用来发送和处理消息
- MessageQueue:消息队列,用来存放所有通过Handler发送的消息,这些消息会被一只存放在消息队列中,等待被处理,每个线程只有一个消息队列
- Looper:是每个消息队列的管家,当调用Looper的loop()方法后,就会进入一个无限循环中,每当发现消息队列中存在一个消息,就会把它取出来,并传递到Handler的handlerMesseage()方法中,进行消息的发出,每个线程中只会有一个Looper对象
1.2 使用AsyncTask
asyncTask是Android提供的一个方便我们在子线程中进行UI操作的工具,它背后实现的原理也是基于异步消息处理机制,只是Android为我们做了一个很好的封装.
使用时继承AsyncTask,并重写相应的方法,如下:
/** * AsyncTask方便在子线程中执行UI操作,基于异步消息处理机制 * 泛型参数一:执行AsyncTask时需要传递的参数 * 泛型参数二:后台执行任务时,要显示的进度单位 * 泛型参数三:执行完毕后的返回值单位 */ public class MyDownloadTask extends AsyncTask<String, Integer, Integer>{ /** * 会在后台任务开始执行前调用,通常用来执行一些界面上的初始化工作,如显示一个进度条对话框等等 */ @Override protected void onPreExecute() { super.onPreExecute(); } /** * 后台处理耗时任务,在子线程中进行,不可以进行UI操作 * * @param strings 继承AsyncTask时的第一个泛型参数 * @return 将任务的执行结果返回 */ @Override protected Integer doInBackground(String... strings) { return 0; } /** * 当在后台任务中调用了publicProgress方法后,会得到调用 * 在此方法中可以进行UI操作 * * @param values 后台任务传递的参数 */ @Override protected void onProgressUpdate(Integer... values){ } /** * 当任务执行完毕并通过return返回时,会得到调用 * 不在子线程中,可以进行UI操作 * * @param integer return返回的数据 */ @Override protected void onPostExecute(Integer integer) { } } 复制代码
2 服务(主要讨论与活动的交流)
服务也属于四大组件之中的一种,所以创建一个服务时也要在清单文件中注册才能够进行使用
2.1 开启服务
-
startService:开启服务,服务开启后就与活动无关了,会在后台一直运行,除非手动调用了stopService()才能停止服务
-
bindService:绑定服务,通过绑定服务可以将活动与服务联系起来,并进行通信,通过Binder和ServiceConnection实现;
2.2 实现服务与活动的交流
- 首先在服务中创建一个继承Binder的类实例,并在这个类中定义想要跟活动进行交流 的方法,并通过服务重写的onBind()方法返回这个binder实例给活动
private DownloadBinder mBinder = new DownloadBinder(); /** * 通过Binder实现服务与活动的信息交流 */ public class DownloadBinder extends Binder{ //想要和服务进行交流的方法 public void startDownload() { } } @Nullable @Override public IBinder onBind(Intent intent) { //把创建的binder传到活动,使得活动可以调用 return mBinder; } 复制代码
- 在要进行交流的活动中创建一个ServiceConnection对象,并重写onServiceConnecte d()方法(当服务与活动成功进行绑定后调用),然后在此方法中通过服务传过来的IBi nder对象向下转型得到我们想要的binder对象
/** * 服务与互动进行交流的工具 */ private MyDownloadService.DownloadBinder downloadBinder; private MyServiceConnection myServiceConnection = new MyServiceConnection(); /** * 用做服务与活动进行交流的桥梁 */ class MyServiceConnection implements ServiceConnection { /** * 当服务与活动成功进行绑定时调用 * * @param service 所绑定的服务对应的Binder */ @Override public void onServiceConnected(ComponentName name, IBinder service) { //获得Binder对象,便可以进行与服务的交流 downloadBinder = (MyDownloadService.DownloadBinder) service; } /** * 当服务与活动断开连接时调用 */ @Override public void onServiceDisconnected(ComponentName name) { } } 复制代码
- bindService()时需要把ServiceConnection对象也传入进去
//绑定服务,参数三:当绑定成功后自动创建服务的标志 bindService(intent, myServiceConnection, BIND_AUTO_CREATE); 复制代码
- 通过binder对象便可以调用服务中写好的方法,从而实现服务与活动的交流
downloadBinder.startDownload(); 复制代码
以上所述就是小编给大家介绍的《学习笔记(一)多线程与服务的一般操作》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 操作系统学习笔记-8:线程
- 阿里面试官问我 Java 线程和操作系统线程什么关系
- Kotlin Coroutines Flow(四):线程操作
- 详解操作系统内核对线程的调度算法
- iOS拾遗——为什么必须在主线程操作UI
- .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。