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

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

MySQL中的MVCC底层原理解读

《MySQL中的MVCC底层原理解读》本文详细介绍了MySQL中的多版本并发控制(MVCC)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

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自动化框架,使用的是