当应用组件启动且没有运行其他组件时,Android系统会使用单个执行线程为应用启动新的Linux进程。默认情况下,同一应用的所有组件在主线程中运行。若某个应用组件启动且应用已存在进程,则该组件会在此进程内启动并使用相同的执行线程。

默认情况下,同一应用的所有组件都在相同进程中进行,但若需要控制某个组件所属的进程,则可以在清单文件中执行进行控制进程。

各类组件元素的清单文件条目<activity><service><receive><provider>均支持android:process属性,可以指定该组件在哪个进程运行。可以设置此属性,使每个组件在各自的进程中运行,或者使一些组件共享一个进程,还可以使不同的应用组件在相同的进程中进行,前提是这些应用共享相同的Linux用户ID并使用相同IDE证书进行签署。<appication>元素还支持android:process属性,以设置适用于所有组件的默认值。

进程生命周期

进程的重要性层次结构:(层次越低越容易在回收内存时,被移除)

1.前台进程---用户当前操作的必须的进程:

托管用户正在交互的Activity(已调用Activity的onResume()方法)

托管某个Service,后者绑定到用户正在交互的Activity

托管正在”前台“运行的Service(服务已调用startForeground())

托管正在执行一个生命周期回调的Service(onCreate(), onStart(), onDestroy())

托管正执行onReceive()方法的BroadcastReceiver

2.可见进程---没有前台组件,但仍会影响用户在屏幕上所见内容的进程

托管不在前台,但仍对用户可见的Activity(调用onPause())

托管绑定在可见Activity的Service

3.服务进程

正在运行startService()方法启动的服务

4.后台进程

目前对用户不可见的Activity进程(已调用Activity的onStop())

5.空进程

不含任何活动应用组件的进程,保留这种进程的唯一目的就是用作缓存,以缩短下次在其中运行组件启动的时间。

线程

启动应用时,系统会为应用创建一个”主线程“,负责将事件分派给相应的用户界面小部件,其中包括绘图事件,主线程也是应用与AndroidUI工具包组件进行交互的线程,故主线程有时也被成为UI线程。

不能通过工作线程操纵UI,而只能通过UI线程操纵用户界面,故Android的单线程模式必须遵守两条规则:

1.不要阻塞UI线程

2.不要在UI线程之外访问AndroidUI工具包

工作线程

要保证应用UI 的响应能力,关键是不能阻塞UI线程,若执行的操作不能很快完成,则应该确保在单独的线程中运行。

如,一个点击侦听器从单独的线程下载图像并将其显示在ImageView中

public void onCLick(View v){ new Thread(new Runnable(){ public void run(){ Bitmap b = loadImageFromNetWork("http://example.com/image.png");           
                mImageView.setImageBitmap(b);}}).start();
}

创建了一个新线程来处理网络操作,但上述代码违反了单线程模式第二条规则,它从工作线程(而不是UI线程)修改了ImageView,可能导致出现不明确、不可预计的行为,而跟踪此行为困难又费时。

为解决此问题,Android提供了几种途径从其他线程访问UI线程:

Activity.runOnUiThread(Runnable)

View.post(Runnable)

View.postDelayed(Runnable, long)

例如,可以使用View.post(Runnable)方法:

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线程中操作ImageView。

不过,操作越来越复杂,就需要通过工作线程处理更复杂的交互,可以在工作线程中使用Handler处理来自UI线程的消息,最好的解决办法是扩展AsyncTask类,此类简化了与UI进行交互所需执行的工作线程任务。

使用AsyncTask

AsyncTask允许对用户界面执行异步操作,它会先阻塞工作线程中的操作,然后在UI线程中发布结果,而无需亲自处理线程或处理程序。

使用时,必须创建AsyncTask的子类并实现doInBackground()回调方法,该方法将会在后台线程池中运行,要更新UI,应该实现onPostExecute()以传递doInBackground()返回的结果并在UI线程中运行,以便安全地更新UI,随后即可通过UI线程调用execute()来运行任务。

public void onCLick(View v){new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{protected Bitmap doInBackground(String... urls){return loadImageFromNetwork(urls[0]);}protected void onPostExecute(Bitmap result){mImageView.setImageBitmap(result);}
}

现在UI是安全的,代码也简化,由于任务被分解成两部分,一部分在工作线程中完成,一部分在UI线程中完成。

简要概述AsyncTask的工作方法:

可以使用泛型指定参数类型,进度值和任务最终值

方法doInBackground()会在工作线程上自动执行

onPreExecute(), onPostExecute(), onProgressUpdate()均在UI线程中调用

doInBackground()返回的值将发送到onPostExecute()

可以随时在doInBackground()中调用publishProgress(), 以在UI线程中执行onProgressUpdate()

可以随时取消任何线程中的任务
进程间的通信

Android 利用远程过程调用 (RPC) 提供了一种进程间通信 (IPC) 机制,通过这种机制,由 Activity 或其他应用组件调用的方法将(在其他进程中)远程执行,而所有结果将返回给调用方。 这就要求把方法调用及其数据分解至操作系统可以识别的程度,并将其从本地进程和地址空间传输至远程进程和地址空间,然后在远程进程中重新组装并执行该调用。 然后,返回值将沿相反方向传输回来。 Android 提供了执行这些 IPC 事务所需的全部代码,因此您只需集中精力定义和实现 RPC 编程接口即可。

要执行IPC,必须使用bindService()将应用绑定到服务上。

android中线程和进程相关推荐

  1. python中线程和进程_python中线程和进程的简单了解

    一.操作系统.应用程序 1.硬件:硬盘.cpu.主板.显卡........ 2.装系统(本身也是一个软件): 系统就是一个由程序员写出来的软件,该软件用于控制计算机得硬盘,让他们之间进行互相配合. 3 ...

  2. Linux中线程和进程的区别

    Linux中线程和进程的区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,它是系统进行资源分配和调度的一个独立单位.例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括 ...

  3. Android中的跨进程通信方法实例及特点分析(二):ContentProvider

    1.ContentProvider简单介绍 在Android中有些数据(如通讯录.音频.视频文件等)是要供非常多应用程序使用的.为了更好地对外提供数据,Android系统给我们提供了Content P ...

  4. linux中线程和进程的区别深度剖析底层实现

    文章目录 前言 Linux中进程和线程的共性 Linux中进程的创建 Linux中线程的实现 总结 前言 在没有仔细了解过Linux的进程和线程实现机制之前,看过很多关于进程和线程的博客,从这些博客中 ...

  5. C#中线程和进程的区别

    线程和进程的区别 进程是程序和调度的独立单元 线程是CPU调度的基本单元 一个进程包含一个或多个线程 线程是轻量级的进程

  6. android运行的线程中,android中线程是否运行在单独的进程中?

    android sdk中的描述 Caution:A service runs in the main thread of its hosting process-the service doesnot ...

  7. Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息...

    先看简单示例:点击按钮,2s之后,TextView改变内容. package cn.lixyz.handlertest;import android.app.Activity; import andr ...

  8. java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...

    之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...

  9. Android中的跨进程调用技术AIDL

    什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用 ...

最新文章

  1. JavaScript 数组排序及查找数组中最大值最小值方法
  2. GPU神经网络和JAVA神经网络速度对比
  3. 如何搭建一个指标体系
  4. python变量生命周期_python 变量定义及变量生命周期
  5. 2Sigma OA prepare: Longest Chain
  6. Oracle索引状态查询与索引重建
  7. Android开发笔记(一百七十五)利用Room简化数据库操作
  8. Java String到int,Java int到String
  9. java读取文件封装的一个类(有部分代码借鉴别人的)
  10. 联想笔记本腾讯会议摄像头灰屏或黑屏问题解决
  11. git用户名和密码保存文件_GitHub 本地保存用户名和密码方法
  12. 尴尬!亚马逊的AI情绪识别软件竟然混淆情感表达
  13. 001潜入大数据Hadoop框架的世界
  14. 【无监督】自编码器(Autoencoder)
  15. 何登成对Innodb加锁的分析
  16. 考研C语言复习02(小甲鱼版本)
  17. linux服务器如何设置双网卡,linux服务器设置(双网卡共享上网)
  18. 学物生地对以后学计算机有影响吗,江苏高考改革后的第一届学生选考物生地,有什么问题吗?...
  19. NSIS脚本文件格式
  20. 听说reStructuredText不错

热门文章

  1. 使用字节缓冲流在文件中写内容
  2. 转载-如何应对在线故障
  3. HTML5游戏开发pdf
  4. SpringMVC - SpringMVC的概述
  5. 什么是Hack技术?
  6. 【剑指Offer】俯视50题之31 - 40题
  7. USB基础---设备、配置、接口、端点和字符串描述符
  8. Adb shell命令打电话测试4G
  9. 高通平台Tag精确寻找进阶教程
  10. 使用Silverlight for Embedded开发绚丽的界面(4)