一、相关的一些基本概念
1. Android进程(该段内容来自网络参考)
当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默 认的情况下,所有该程序的组件都将在该进程和线程中运行。同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足时,Android 会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要 性,Android会首先停止那些不重要的进程。
按照重要性从高到低一共有五个级别:
前台进程
前台进程是用户当前正在使用的进程。只有一些前台进程可以在任何时候都存在。他们是最后一个被结束的,当内存低到根本连他们都不能运行的时候。一般来说, 在这种情况下,设备会进行内存调度,中止一些前台进程来保持对用户交互的响应。
可见进程
可见进程不包含前台的组件但是会在屏幕上显示一个可见的进程是的重要程度很高,除非前台进程需要获取它的资源,不然不会被中止。
服务进程
运 行着一个通过startService() 方法启动的service,这个service不属于上面提到的2种更高重要性的。service所在的进程虽然对用户不是直接可见的,但是他们执行了用 户非常关注的任务(比如播放mp3,从网络下载数据)。只要前台进程和可见进程有足够的内存,系统不会回收他们。
后台进程
运 行着一个对用户不可见的activity(调用过 onStop() 方法).这些进程对用户体验没有直接的影响,可以在服务进程、可见进程、前台进 程需要内存的时候回收。通常,系统中会有很多不可见进程在运行,他们被保存在LRU (least recently used) 列表中,以便内存不足的时候被第一时间回收。如果一个activity正 确的执行了它的生命周期,关闭这个进程对于用户体验没有太大的影响。
空进程
未运行任何程序组件。运行这些进程的唯一原因是作为一个缓存,缩短下次程序需要重新使用的启动时间。系统经常中止这些进程,这样可以调节程序缓存和系统缓 存的平衡。
Android 对进程的重要性评级的时候,选取它最高的级别。另外,当被另外的一个进程依赖的时候,某个进程的级别可能会增高。一个为其他进程服务的进程永远不会比被服 务的进程重要级低。因为服务进程比后台activity进程重要级高,因此一个要进行耗时工作的activity最好启动一个service来做这个工 作,而不是开启一个子进程――特别是这个操作需要的时间比activity存在的时间还要长的时候。例如,在后台播放音乐,向网上上传摄像头拍到的图片, 使用service可以使进程最少获取到“服务进程”级别的重要级,而不用考虑activity目前是什么状态。broadcast receivers做费时的工作的时候,也应该启用一个服务而不是开一个线程。
2、MessageQueue
一个消息队列,采用先进先出的原则管理消息。每一个线程最多只可以拥有一个MessageQueue数据结构。 创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。
主线程创建时,会创建一 个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,需要的时候,通过调用prepare函数来实现。
3、Message
消息对象,Message Queue中的存放的对象,handler接收和处理的对象。一个Message Queue中包含多个Message。 Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例, 而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例, 则用给定的参数创建一个Message对象。调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。除了上面这 种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。
4、Looper
每个线程只能有一个Looper。
Looper是MessageQueue的管理者,负责读取MessageQueue中的消息,读取到消息就交给handler进行处理。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。
通过调用Looper.myLooper()可以获得当前线程的Looper对象,创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接收Message。如需要接收,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
Looper 的prepare()方法保证每个线程最多只有一个Looper对象,然后通过loop()方法启动,loop()方法使用一个死循环不断的从MessageQueue中取出消息,并将取出的消息分给该消息对应的handler进行处理。
5、Handler
消息的处理者,负责发送消息和处理消息。程序使用handler发送消息,被handler发送的消息必须被送到指定的MessageQueue(通过looper)。
发送消息:
handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现; 将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
接收处理消息:
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法 对其进行处理。
6、消息处理
Handler消息传递机制通过Thread、Handler、Looper、MessageQueue来实现:
Looper、MessageQueue结合实现Message的管理、存放;
Handler负责消息的发送、处理;
Thread负责提供Handler、Looper运行的环境;
二、代码示例
1、通过其他线程来与UI线程进行通信,设置UI组件属性时
UI线程接收消息、调用handler处理;(handleMessage)
其他线程则通过handler发送特定消息给UI线程;(sendMessage)
UI线程默认自带Looper;直接设置handler处理即可。 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_base_handler); iv_handler_image = (ImageView) findViewById(R.id.iv_handle_image); final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x12) { if (currId > imageIds.length - 1) { currId = 0; } iv_handler_image.setImageResource(imageIds[currId++]); } } }; new Timer().schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub handler.sendEmptyMessage(0x12); } }, 0, 1000); }
2、不同线程通过handler进行消息传递
调用方:
启动线程(或者预先启动),并sendMessage;
处理方:
实现handler,handleMessage
自定义线程,在该线程中定义Looper,并且将Looper与Handler绑定 一个线程只能定义一个Looper public class MyHandlerThread implements Runnable { MyHandler handler=null; Looper mylooper=null; @Override public void run() { Looper.prepare(); mylooper=Looper.myLooper(); handler=new MyHandler(mylooper); Looper.loop(); } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); mylooper.quit(); } }
Handler处理过程;处理完成后可以通过广播方式往外传递消息 public class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { Log.i("myhandler", msg.getData().getString("data")); } }
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_base_handler); iv_handler_image = (ImageView) findViewById(R.id.iv_handle_image); final MyHandlerThread mythread=new MyHandlerThread(); //启动线程 new Thread(mythread).start(); new Timer().schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub Bundle bundle=new Bundle(); bundle.putString("data", "我是数据"); Message mess=new Message(); mess.setData(bundle); mythread.handler.sendMessage(mess); } }, 0, 1000); }
相关推荐
Android的Handler、Looper和Message机制可以帮助开发者在主线程和工作线程之间传递消息。 7. **数据序列化**:在网络传输过程中,游戏状态需要被序列化为可传输的数据格式,如JSON或protobuf。这需要了解并使用相关...
Handler机制是Android系统中用于处理消息和线程通信的重要组成部分。它主要由四个核心组件组成:`Looper`、`Handler`、`MessageQueue` 和 `Thread`。 #### 二、核心组件解析 1. **Looper** - **定义**:`Looper`...
"Speak-To-Me" 是一个基于Android平台的项目,它主要关注的是语音识别与合成技术的应用。这个项目可能是一个小型的语音助手应用,允许用户通过语音进行交互,比如执行命令、查询信息等。在Android开发中,语音功能的...
开发者可能使用了`AsyncTask`、`Handler`或`Retrofit`等异步处理技术来处理网络请求。 4. **权限管理**:由于涉及到网络访问,应用可能需要在AndroidManifest.xml文件中声明`INTERNET`权限。此外,如果涉及到读取或...
10. **Handler/Looper/Message**: Android的消息传递机制,用于在主线程和子线程之间同步通信,更新UI。 11. **Service**: Android的后台运行组件,可以长时间运行,即使用户离开应用。在这个项目中,可能会使用到...
- **Broadcast**和**BroadcastReceiver**:Broadcast是全局的消息传递机制,BroadcastReceiver用于接收Broadcast,执行相应的操作,如处理系统广播或自定义广播。 理解并熟练掌握这些基本概念和实践,是成为一名...
为了更新UI,需要使用Handler或AsyncTask进行消息传递。 **五、发现局域网内的设备** 1. **IP扫描**:可以通过发送广播包到局域网内所有可能的IP地址,然后接收响应来找到其他设备。 2. **Bonjour/Zeroconf**:使用...
Intent用于在Activity之间传递数据和启动操作,是Android系统中重要的通信机制。 3. **布局设计**:Android使用XML文件来定义用户界面布局,如LinearLayout、RelativeLayout或ConstraintLayout。LumaQQ源码会展示...
6. **消息同步机制**:为了保持不同设备上的聊天记录同步,需要设计一套消息同步策略,例如使用消息ID、时间戳来判断新旧消息,或者使用增量同步来减少网络传输。 7. **界面设计与用户体验**:仿QQ的聊天界面需要...
- **Handler/Looper**:用于在后台线程和UI线程间传递消息,更新UI。 9. **推送通知** - **Firebase Cloud Messaging (FCM)**:可能用于实现离线消息推送,即使应用不在后台运行,也能收到新消息的通知。 10. **...
12. **异常处理与日志记录**:源码可能会有全局的异常捕获机制,如使用UncaughtExceptionHandler,以及使用Logcat进行日志记录,便于调试和问题定位。 通过研究这个毕业设计项目,学生不仅可以掌握Android应用开发...
### Android技术面试资料整理 #### 1. Android的四大组件及其作用 - **Activity**:是Android应用程序中负责用户交互的主要部分。一个Activity通常对应着一个屏幕,展示UI元素并与用户进行交互。当一个Activity被...
Android提供了AsyncTask、Handler/Looper机制以及现代的LiveData和Coroutines等工具来处理异步任务。熟悉这些工具的使用是提高应用性能的关键。 6. **推送通知**:微信会实时推送消息,这需要用到Google的Firebase ...
### Android技术面试整理知识点 #### 1. Android的四大组件及其作用 - **Activity**:作为用户界面的主要组成部分,Activity负责展示UI并处理用户输入。每个Activity代表一个屏幕,可以包含多个视图(View),用于...
Android 编程规范的重要知识点,包括目录命名规则、JSON 解析、类成员初始化、Int 类型常量、Activity 接受参数与模块化、AndroidStudio 工程目录组织、Handler 的封装、List 的数据更新、Activity 与 Fragment 之间...
可以使用AsyncTask或者Handler/Looper机制来处理这类操作。 8. **权限请求**: - 自Android 6.0(API级别23)起,运行时权限管理成为强制要求。应用需要在运行时动态请求权限,而不是在安装时一次性获取。 9. **...
在Android平台上实现基于Socket的聊天应用,涉及到许多关键的技术点和步骤。首先,我们要理解Socket的概念,它是网络通信中的一个重要组件,允许两台设备通过TCP/IP协议进行双向数据传输。在Android聊天应用中,...
"android学习中记录"这个压缩包文件似乎包含了一系列的学习资料,适合初学者入门,同时也为有一定经验的开发者提供了参考。让我们深入探讨一下这些知识点。 首先,Android是Google主导的开源移动操作系统,主要应用...
这个keycode随后通过Binder机制传递到Android系统的InputSystemService。 在Android 9.0和10.0中,InputSystemService接收到keycode后,会将其封装成一个KeyEvent对象。这个对象包含了按键的所有信息,如时间戳、...
21. **Android事件传递机制** - Android事件传递涉及触摸事件、按键事件等,通过ViewTreeObserver等类处理。 22. **线程间操作List** - 在多线程环境下操作List时需要考虑线程安全问题。 - 可以使用Collections....