安卓开发线程和进程讲解

  进程:组件运行的进程由manifest file控制。组件的节点<activity>, <service>, <receiver>, 和 <provider> 都包含一个 process 属性。这个属性可以设置组件运行的进程:可以配置组件在一个独立进程运行,或者多个组件在同一个进程运行。甚至可以多个程序在一个进程中运行——如果这些 程序共享一个User ID并给定同样的权限。 节点也包含 process 属性,用来设置程序中所有组件的默认进程。

  所有的组件在此进程的主线程中实例化,系统对这些组件的调用从主线程中分离。并非每个对象都会从主线程中分离。一般来说,响应例如 View.onKeyDown()用户操作的方法和通知的方法也在主线程中运行。这就表示,组件被系统调用的时候不应该长时间运行或者阻塞操作(如网络操 作或者计算大量数据),因为这样会阻塞进程中的其他组件。可以把这类操作从主线程中分离。

  当更加常用的进程无法获取足够内存,Android可能会关闭不常用的进程。下次启动程序的时候会重新启动进程。

  当决定哪个进程需要被关闭的时候, Android会考虑哪个对用户更加有用。如Android会倾向于关闭一个长期不显示在界面的进程来支持一个经常显示在界面的进程。

  线程:即使为组件分配了不同的进程,有时候也需要再分配线程。比如用户界面需要很快对用户进行响应,因此某些费时的操作,如网络连接、下载或者非常占用服务器时间的操作应该放到其他线程。

  线程通过java的标准对象Thread 创建. Android 提供了很多方便的管理线程的方法:— Looper 在线程中运行一个消息循环; Handler 传递一个消息; HandlerThread 创建一个带有消息循环的线程。

  远程调用Remote procedure calls

  Android有一个远程调用(RPCs) 的轻量级机制— 通过这个机制,方法可以在本地调用,在远程执行(在其他进程执行),还可以返回一个值。要实现这个需求,必须分解方法调用,并且所有要传递的数据必须是操 作系统可以访问的级别。从本地的进程和内存地址传送到远程的进程和内存地址并在远程处理和返回。返回值必须向相反的方向传递。Android提供了做以上 操作的代码,所以开发者可以专注于实现RPC的接口。

  一个RPC接口只能包含方法。所有的方法都是同步执行的(直到远程方法返回,本地方法才结束阻塞),没有返回值的时候也是如此。

  简单来说,这个机制是这样的:使用IDL (interface definition language)定义你想要实现的接口, aidl 工具可以生成用于java的接口定义,本地和远程都要使用这个定义。它包含2个类,见下图:

  inner类包含了所有的管理远程程序(符合IDL描述的接口)所需要的代码。所有的inner类实现了IBinder 接口.其中一个在本地使用,可以不管它的代码;另外一个叫做Stub继承了 Binder 类。为了实现远程调用,这个类包含RPC接口。开发者可以继承Stub类来实现需要的方法。

  一般来说,远程进程会被一个service管理(因为service可以通知操作系统这个进程的信息并和其他进程通信),它也会包含aidl 工具产生的接口文件,Stub类实现了远处那个方法。服务的客户端只需要aidl 工具产生的接口文件。

  以下是如何连接服务和客户端调用:

  ·服务的客户端(本地)会实现onServiceConnected() 和onServiceDisconnected() 方法,这样,当客户端连接或者断开连接的时候可以获取到通知。通过 bindService() 获取到服务的连接。

  · 服务的 onBind() 方法中可以接收或者拒绝连接,取决它收到的intent (intent通过 bindService()方法连接到服务). 如果服务接收了连接,会返回一个Stub类的实例.

  · 如果服务接受了连接,Android会调用客户端的onServiceConnected() 方法,并传递一个Ibinder对象(系统管理的Stub类的代理),通过这个代理,客户端可以连接远程的服务。

  以上的描述省略很多RPC的机制。请参见Designing a Remote Interface Using AIDL 和 IBinder 类。

  线程安全的方法

  在某些情况下,方法可能调用不止一个的线程,因此需要注意方法的线程安全。

  对于可以远程调用的方法,也要注意这点。当一个调用在Ibinder对象中的方法的程序启动了和Ibinder对象相同的进程,方法就在 Ibinder的进程中执行。但是,如果调用者发起另外一个进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中;它不会在进 程的主线程中运行。例如,一个service从主线程被调用onBind() 方法,onBind() 返回的对象(如实现了RPC的Stub子类)中的方法会被从线程池中调用。因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用 IBinder的方法。因此IBinder必须线程安全。

  简单来说,这个机制是这样的:使用IDL (interface definition language)定义你想要实现的接口, aidl 工具可以生成用于java的接口定义,本地和远程都要使用这个定义。它包含2个类,见下图:


  inner类包含了所有的管理远程程序(符合IDL描述的接口)所需要的代码。所有的inner类实现了IBinder 接口.其中一个在本地使用,可以不管它的代码;另外一个叫做Stub继承了 Binder 类。为了实现远程调用,这个类包含RPC接口。开发者可以继承Stub类来实现需要的方法。

  一般来说,远程进程会被一个service管理(因为service可以通知操作系统这个进程的信息并和其他进程通信),它也会包含aidl 工具产生的接口文件,Stub类实现了远处那个方法。服务的客户端只需要aidl 工具产生的接口文件。

  以下是如何连接服务和客户端调用:

  ·服务的客户端(本地)会实现onServiceConnected() 和onServiceDisconnected() 方法,这样,当客户端连接或者断开连接的时候可以获取到通知。通过 bindService() 获取到服务的连接。

  · 服务的 onBind() 方法中可以接收或者拒绝连接,取决它收到的intent (intent通过 bindService()方法连接到服务). 如果服务接收了连接,会返回一个Stub类的实例.

  · 如果服务接受了连接,Android会调用客户端的onServiceConnected() 方法,并传递一个Ibinder对象(系统管理的Stub类的代理),通过这个代理,客户端可以连接远程的服务。

  线程安全的方法

  在某些情况下,方法可能调用不止一个的线程,因此需要注意方法的线程安全。

  对于可以远程调用的方法,也要注意这点。当一个调用在Ibinder对象中的方法的程序启动了和Ibinder对象相同的进程,方法就在 Ibinder的进程中执行。但是,如果调用者发起另外一个进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中;它不会在进 程的主线程中运行。例如,一个service从主线程被调用onBind() 方法,onBind() 返回的对象(如实现了RPC的Stub子类)中的方法会被从线程池中调用。因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用 IBinder的方法。因此IBinder必须线程安全。

  简单来说,一个content provider 可以接收其他进程的数据请求。即使ContentResolver和ContentProvider类没有隐藏了管理交互的细 节,ContentProvider中响应这些请求的方法(query(), insert(), delete(), update(), and getType() )— 是在content provider的线程池中被调用的,而不是ContentProvider的本身进程。因为这些方法可能是同时从很多线程池运行的,所以这些方法必须要 线程安全。

时间: 2024-09-17 15:54:27

安卓开发线程和进程讲解的相关文章

线程-安卓开发中的notification问题

问题描述 安卓开发中的notification问题 开机启动一个service,在服务中启动一个线程不停的做某种规则检测 ,只要规则符合,且提示周期到了,(我设的周期为2小时),线程就要发送一个通知.但是我在测试的时候 发现,只有第一次通知是发出去的,当两个 小时过去后,规则符合,周期时间也符合,但是通知并没有发送.有没有人知道 这是怎么回事呢.第一个通知发送后,我会在程序中做些操作,完成后就能出程序.然后手机就进入待机状态,可是等不到下一次的通知. 解决方案 用广播试试,发送广播,接受广播做处

线程-安卓开发中用new Thread()的困惑?

问题描述 安卓开发中用new Thread()的困惑? 用listview从服务端取数据的方法用new Thread()并且用SystemClock.sleep延迟几秒,等数据准备完后再刷新listview.不理解为什么要另开一个线程和要延迟,如果在主线程中取数据会有什么问题? 解决方案 如果在主线程中进行网络请求,会造成ANR异常!同时从安卓版本高级版本,貌似是11开始,不能在主线程中进行网络请求,否则直接报异常!所以不能在主线程进行网络请求! 所以,一般进行网络请求都要新开一个线程进行访问!

android开发-如何理解安卓开发当中对多线程和多进程

问题描述 如何理解安卓开发当中对多线程和多进程 如何理解安卓开发当中对多线程和多进程 如何理解安卓开发当中对多线程和多进程 解决方案 线程是程序执行的最小单位,线程通讯比较简单,进程相对独立.一个程序就是一个进程,一个程序执行的时候的每个任务就是一个线程.一个进程至少有一个线程,也可以有多个线程. 解决方案二: 一个进程包含多个线程 解决方案三: 多线程 多进程应该是系统概念 跟其他环境中概念相同

安卓开发常用工具和第三方库汇总

本文讲的是安卓开发常用工具和第三方库汇总,我的名字叫 Ryan Cooke 我在 Pinterest 的核心体验团队工作.今天在这里我会谈论各种 Android 库:它们各自的优点,缺点和其他相关知识.目的是高效地概述尽可能多的库,这样,当你遇到一个问题的时候,你知道这是不是个已经解决的问题?什么样的方案更好?同时也能帮助你避免那些陷阱. 选择正确的库意味着你可以拥有一个已经成熟的更好的解决方案,而不是花费三个月来重新构建它.了解这些库是第一步. 我听到很多人想要实现第一个库, 我们难道不能用

java-用eclipse安卓开发时遇到的一个十分诡异的问题

问题描述 用eclipse安卓开发时遇到的一个十分诡异的问题 @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String filePath = ""/storage/sdcard0/DCIM/Camera/20130826_182939.jpg"&q

求安卓开发大牛讲讲学习经验

问题描述 求安卓开发大牛讲讲学习经验 10C 我现在是大三本科的学生,从大二开始对移动开发特别感兴趣,所以自己自学了java(看的韩顺平老师的视频) 掌握了一些基本的东西又自学了安卓的开发基础(也是通过看慕课网和极客学院的视频)现在就是感觉自己会了很多,又感觉自己什么都不会.自己想了一个app项目,做的时候也感觉很多东西没接触的,百度就可以.现在不知道是该搞搞理论,还是继续做项目,自己一个人做也没人指导.大牛们,希望你们能给我点建议. 解决方案 想必你的理论基础应该可以了."现在就是感觉自己会了

如何搭建安卓开发持续化集成环境(Ubuntu + Jenkins + SonarQube)

本文讲的是如何搭建安卓开发持续化集成环境(Ubuntu + Jenkins + SonarQube), 我最近换了一台新的 MacBook Pro 作为我的 Android 开发机.旧的 Mac BookPro (13英寸,2011款,16GB 内存,500G SSD,i5 内核 2.4GHz,64位)我并没有卖掉或丢掉,而是装了 MacOS-Ubuntu 双系统作为持续化集成环境服务器. 本文目标是总结安装步骤,以便广大开发者朋友和我自己将来在搭建自己的 CI 时参考,主要内容如下: 在全新的

求问大神一条安卓开发的问题

问题描述 求问大神一条安卓开发的问题 我写的一个app,每次打开后占用的内部存储空间都会成倍增长,但是我这只app并没有联网,在运行的时候并没有增加任何数据,只是每次打开时都从数据库里把一些图片,文字读出来并赋值,一开始的时候是2m多,按后退键退出后再打开,然后再退出,占了3m多,然后重复这样打开退出打开退出,每次app的占用内部存储空间都近乎两倍来增长,最后占了57m多的时候,就提示说出现oom了,请问这是怎么回事?为什么我没有往里面添加数据,它都会疯狂增长? 我从数据库里读取数据的时候使用a

android-java语言 安卓开发中的问题

问题描述 java语言 安卓开发中的问题 Pattern ptn=Pattern.compile("[(d{2}:d{2}.d{2})]"): Matcher mtn=ptn.matcher(line): 这两句是什么意思? 解决方案 正则表达式,匹配 [11:22.33]这样的字符串,d{2}表示2位数字. 解决方案二: Java语言是一种支持多线程的语言,它通过同步(互斥)和协作(等待和唤醒)来完成.这里聊聊同步. ? 线程不安全主要来自于类变量(静态变量)和实例变量,前者位于方法