android中线程和进程工作原理

2024-01-22 14:58

本文主要是介绍android中线程和进程工作原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android中默认情况下,同一应用中的所有组件运行在同一个进程和线程中。你的应用中没有其他组件在运行,那么Android将会给你开启一个新的Linux的进程,然后运行一个main线程来运行你的应用。如果你应用中已经有其他组件在运行,你再开启你的应用时,开启的应用会使用之前正在运行的线程和进程。

下面介绍一个应用中的线程和进程是如何工作的。

一、进程。

默认情况下,同一应用程序的所有组件运行在相同的进程,大多数应用程序不应该改变这种情况。然而,如果你发现你需要控制某一组件属于同一进程,你可以在manifest文件中进行实现。

在<activity>这些标签中都支持Android:process属性这样用户可以指定某些组件运行在哪一个具体的进程上。具有相同 的Linux 用户ID并且在相同的证书下开发的不同应用中的组件可以运行在相同的进程中。通过上述的熟悉就可以实现。

<application>也支持该属性,给应用设置默认的运行的进程。

1.进程的声明周期。当系统资源紧张或者内存使用量较高的时候,Android会选取当前的一些进程予以关闭,进而提高你的设备的运行性能。Android中主要有5中级别的进程。

1)前台进程。下面五种情况说明是前台进程。在一个给定的时间内前台进程的数量是很少的,其基本不会被系统关闭。

(1)用户正在与其交互(调用onResume方法重新开始)。

(2)一个绑定到Activity的Service,并且用户正在于其进行交互。

(3)一个Service但是调用了startForeground方法。

(4)一个调用onCreate onStart onDestory的Service回调方法。

(5)一个Broadcast Receiver正在调用onReceive方法。

2)可见进程。

不是前台进程但是对用户当前可见的界面还是有影响的进程。

(1)一个Activity调用了onPause方法。

(2)一个绑定了可见或者前台进程的Service。

3)服务进程。

      调用了startService的Service,但是没有绑定到可见和前台进程上。当内存过低的时候,服务可能会被停掉来保证可见和前台进程的正常运行。

4)后台进程。

     对用户当前没有任何的响应,可以随时关闭的进程。系统中会存在大量的后台进程,并且使用LRU算法对这些进程进行维护来提高系统的运行效率。当Activity中调用onstop方法,进程就成为了后台进程。

5)空进程。

    空进程不会持有任何活动应用的组件,空进程存在的目的是为了缓存,以提高下次组件启动的速度。操作系统会对进程的缓存和内核内部的缓存进行衡量,是系统运行最优。

上述,优先级从高到底,主要是按照进程的重要程度进行分类的。

二、线程。

当一个应用开启的时候,操作系统会为应用创建一个main线程来运行应用。这个线程非常重要,其负责管理将所有的事件派发到适当的用户接口工具中,包括drawable事件。该线程并负责与Android UI工具包中的组件进行交互,所以该线程又被称为UI线程。同一个组件的实例将会运行在相同的线程中,运行在系统进程中的组件都是由同一个UI线程实例化的。故所有的响应系统的回调函数如onKeyDown都会运行在进程中的UI线程中。UI线程还需要负责和UI工具包进行交互。

这里以点击Button从新绘制当前View为例进行说明;

       当用户点击一次Button按钮时,你应用的UI线程会将你的点击事件派发到widget,widget反过来会设置按压状态然后发送一个invalidate事件到事件队列,你的UI线程随后将从事件队列中取出事件,然后通知widget需要重新绘制当前View。

       当你的应用要执行用户交互敏感的操作的时候,如网络访问,数据库查询,其操作可能会很耗时,很可以能导致ANR,这时会给用户很差的使用体验。并且UI工具包是不安全的,你需要使用worker线程对UI进行维护,并且你需要维护其和UI线程交互的所有操作。下面有两条建议:

(1)不要阻塞UI线程。否则事件将不会派发,然后就出现了ANR。

(2)不要再UI线程之外访问AndroidUI工具包。

故,关键不要阻塞UI线程。对于耗时的线程可以放到其他的线程中进行处理。如下面的操作

public void onClick(View v) {new Thread(new Runnable() {public void run() {Bitmap b = loadImageFromNetwork("http://example.com/image.png");mImageView.setImageBitmap(b);}}).start();
}
但是,这违背了第(2)条准则。Android提供了下面的三种方式来解决上述问题。

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
public void onClick(View v) {new Thread(new Runnable() {public void run() {final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");mImageView.post(new Runnable() {public void run() {mImageView.setImageBitmap(bitmap);}});}}).start();
}
上述代码完成了网络请求操作和主线程的分离,并且将对UI工具包的访问又放到了main线程中进行。

但是,随着操作的复杂上述代码是不太好维护的。可以在worker Thread中使用Handler对来自UI线程中的消息进行派发。但是,或许最好的方式就是进程AsynTask类,能够简化Worker Thread和UI之间的交互。

AsynTask的使用方式:

public void onClick(View v) {new DownloadImageTask().execute("http://example.com/image.png");
}private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {/** The system calls this to perform work in a worker thread and* delivers it the parameters given to AsyncTask.execute() */protected Bitmap doInBackground(String... urls) {return loadImageFromNetwork(urls[0]);}/** The system calls this to perform work in the UI thread and delivers* the result from doInBackground() */protected void onPostExecute(Bitmap result) {mImageView.setImageBitmap(result);}
}
使用上述方式,你的代码的安全性就比较高了,因为其将两个线程分离开。

AsynTask使用综述:

1)可以使用泛型来指定参数类型,进度值和最终值。

2)doInBackground会在Worker Thread中自动调用。而onPostExecute onPreExecute  onProgessUpdate会自动的在UI线程中调用。

3)doInbackgroudn的返回值会发送到哦你PostExecute方法。

4)你可以在doInbackground方法中任意的调用publishProgess方法来执行UI线程中的onProgessUdapte方法。

3)你可以在任何线程中,在任何时间取消该任务。


但是如果在运行期间发生了,运行时配置改变的时候,你的Worker Thread可能会被中断的。



IPC简介

Android中提供了一种远程过程调用(RPC)的机制用来处理IPC过程。RPC机制中,当一个Activity或者应用程序的其他的组件调用了RPC中的方法,该方法会在别的进程(远端进程)中执行然后将返回值返回给调用者。这就需要将方法调用和数据分解到一个操作系统可以理解的水平,并且能够将其从本地进程和地址空间中传递到远程的进程和地址空间,然后再重新组装和定制调用。返回值会以相反的方向传递返回给本地。Android中已经提供了实现IPC的所有的代码,因此程序员只需要关注和实现RPC编程接口。

如果想要使用IPC,那么你的应用必须要绑定到Service上,即调用bi



翻译自:Android官方文档。


这篇关于android中线程和进程工作原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633330

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于