Android进程详解

当一个应用启动的时候,如果这个应用没有其它组件已经在运行了,那么系统就会为这个应用启动一个新的Linux进程,这个进程只有一个线程,即我们熟知的main线程。默认情况下,一个应用的所有组件都运行在一个进程和线程(main)中。这点从Logcat的打印信息可以看出,Logcat视图中的Application那一栏,打印的是当前应用的进程的name值,而通常情况下是打印出的是manifes的package的值,这是因为我们的Application的标签没有设置progress的值,如果没有设置的话,系统默认使用package的值来作为当前应用的进程的名字。当然,你完全可以安排不同的组件运行于不同的进程中,并且你可以为任何程序创建另外的线程,这点我们在做异步操作更新界面的时候,如果使用Handler的方式的话,往往会新创建一个线程。如:

new Thread()

{

public void run()

{

…………………………………………..

mHandler.sendEmptyMessage(0);

}

}.start();

下面说一下,如何实现同一个应用的不同组件运行在不同的进程中:

默认下,同一个应用的所有组件都运行在同一个进程中并且大多数程序不必改变这种情况,如果你非要同一个应用的不同组件运行在不同的进程中,也可以通过manifest文件实现。

Manifest文件中的所有支持android:process属性的那些项(<activity>,<service>,<receiver>,和<provider>)都可以指定一个进程,设置该属性之后的组件将在该属性所对应的进程中运行。你可以设置这个属性使每个组件运行于其自己的进程或只是其中一些组件共享一个进程,你也可以设置android:process以使不同应用的组件可以运行于同一个进程。<application>元素也支持android:process属性,用于为所有的组件指定一个默认值。Android可能在某些时刻决定关闭一个进程,比如在内存不足的时候,系统会自动关闭一些其他应用的后台进程,以保持当前正在运行的进程的运行。

进程的生命周期:Android系统会尽量维持一个进程的生命,直到最终需要为新的更重要的进程腾出内存空间。为了决定哪个该杀哪个该留,系统会根据运行于进程内的组件和组件的状态把进程置于不同的重要性等级。当需要系统资源时,重要性等级越低的先被淘汰。Android重要性等级被分为5个等级(从高到低):(1)前台进程(2)可见进程(3)服务进程(4)后台进程(5)空进程.

进程的优先级:

当系统的内存不足时,android系统将根据进程优先级选择杀死一些不太重要的进程。进程优先级从高到低分别为:

1、  前台进程,以下进程为前台进程:

(1)进程中包含处于前台的正与用户交互的activity;

(2)进程中包含与前台activity绑定的service

(3)进程中包含了调用了startForeground()方法的service

(4)进程中包含正在执行onCreate(),onStart(),或onDestroy()方法的service

(5)进程中包含正在执行onReceive()方法的BroadcastReceiver

系统中前台进程的数量很少,前台进程几乎不会被杀死,只有当内存低到无法保证所有的前台进程同时运行时才会选择杀死某个前台进程。

2、  可见进程,以下进程为可见进程:

(1)进程中包含未处于前台但仍然可见的activity(调用了activity的onPause()方法),典型的情况是运行activity时弹出对话框,此时的activity虽然不是前台activity,但是其仍然可见。

(2)进程中包含于可见activity绑定的service

可视进程不会被系统杀死,除非为了保证前台进程的运行而不得已为之。

3、  服务进程:进程中包含已启动的service

4、  后台进程:进程中包含不可见的activity(onStop()方法调用后的activity)。后台进程不会直接影响用户体验,为了保证前台进程/可视进程/服务进程的运行,系统随时都有可能杀死一个后台进程。一个正确的实现了生命周期方法的activity处于后台时被系统杀死,可以在用户重新启动它时恢复之前的运行状态。

5、  空进程:不包含任何处于活动状态的进程是一个空进程,系统经常杀死空进程,这不会造成任何影响。空进程存在的唯一理由是为了缓存一些启动数据。

讲到这里理论部分已经讲完了,现在咱们通过一个Demo来加深一下理解。

首先看一下测试Demo的Manifest文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gc.testprogressdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
	<!-- android:process="newpackage.test"  设定此Demo的进程名字为newpackage.test,即此Demo所有
		组件默认都运行在该进程中
	 -->
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:process="newpackage.test"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--  android:process="NewProgress."  将NewProgress组件运行在NewProgress.进程里。
        	注意:android:process的值的格式须为:xxx.xxxx。这个必须含有一个“.”,否则编译通不过。
        	测试编译环境为5.0
        -->
        <activity
            android:name=".NewProgress"
            android:label="@string/app_name"
            android:process="NewProgress."
            />
        <activity
            android:name=".NowProgress"
            android:label="@string/app_name" 

            />
    </application>

</manifest>

大家都过上面代码可以看到,此Demo是运行在进程newpackage.test里的,NewProgress这个Activity是运行在NewProgress.这个进程里的,下面大家先看一下运行效果图,如下图所示:

下面给出获取当前进程的名字的代码,如下:

package com.gc.testprogressdemo.uitls;

import android.app.ActivityManager;
import android.content.Context;
/**
 * 返回当前进程的名字
 * @author Android将军
 *
 */
public class GetProgressName {

	public static String getCurrentProgressName(Context context)
	{
		int pid=android.os.Process.myPid();
		ActivityManager mActivityManager=(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
		for(ActivityManager.RunningAppProcessInfo appProcess:mActivityManager.getRunningAppProcesses())
		{
			if(appProcess.pid==pid)
			{
				return appProcess.processName;
			}
		}
		return null;

	}
}

由于此Demo比较简单,故不在过多的阐述,文章末尾会附上Demo的下载地址。

至于如何判断当前进程是哪一个级别的进程,可以将上面的函数返回代码修改为

return appProcess.processName+"级别"+appProcess.importance;

其中importance是反应进程优先级的属性,具体请查看下表:

在实际开发中,如果大家想获得进程的状态可以通过查看你想知道的进程的importance属性。

在此我在Demo中重写了MainActivity与NewProgress的生命周期方法,Logcat的打印日志如下:

12-10 13:05:13.083: I/System.out(1452): MainActivity所在进程onCreate:newpackage.test级别100               前台进程

12-10 13:05:13.091: I/System.out(1452): MainActivity所在进程onStart:newpackage.test级别100                  前台进程

12-10 13:05:13.095: I/System.out(1452): MainActivity所在进程onResume:newpackage.test级别100            前台进程

12-10 13:06:30.335: I/System.out(1452): MainActivity所在进程onPause:newpackage.test级别100                前台进程

12-10 13:06:30.595: I/System.out(1471): NewProgress所在进程onCreate:NewProgress.级别100              前台进程

12-10 13:06:30.595: I/System.out(1471): NewProgress所在进程onStart:NewProgress.级别100                 前台进程

12-10 13:06:30.599: I/System.out(1471): NewProgress所在进程onResume:NewProgress.级别100           前台进程

12-10 13:06:30.923: I/System.out(1452): MainActivity所在进程onStop:newpackage.test级别130                可见进程(经典场景:Activity弹出对话框)

12-10 13:07:46.199: I/System.out(1471): NewProgress所在进程onPause:NewProgress.级别100             前台进程

12-10 13:07:46.207: I/System.out(1452): MainActivity所在进程onRestart:newpackage.test级别100             前台进程

12-10 13:07:46.211: I/System.out(1452): MainActivity所在进程onStart:newpackage.test级别100                  前台进程

12-10 13:07:46.211: I/System.out(1452): MainActivity所在进程onResume:newpackage.test级别100          前台进程

12-10 13:07:46.647: I/System.out(1471): NewProgress所在进程onStop:NewProgress.级别400                后台进程

12-10 13:07:46.647: I/System.out(1471): NewProgress所在进程onDestroy:NewProgress.级别400             后台进程

要讲的就这么多,如果大家有什么不明白的可以回复提问,如果有不对之处,也请大家指出。

Demo下载地址:http://download.csdn.net/detail/gc_gongchao/8245593

转载请注明出处:http://blog.csdn.net/android_jiangjun/article/details/41851139

时间: 2024-08-09 22:00:27

Android进程详解的相关文章

[gitbook] Android框架分析系列之Android Binder详解

请支持作者原创: https://mr-cao.gitbooks.io/android/content/android-binder.html Android Binder详解 Table of Contents 1. binder简介 2. binder的实现 2.1. IBinder类简介 2.2. IInterface类简介 2.3. BpBinder和BBinder简介 2.4. ProcessState和IPCThreadState简介 2.5. ServiceManager简介 2.

Android 签名详解

在Android 系统中,所有安装 到 系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个 permission的protectionLevel为signature,那么就只有那些跟该permission所在的程序拥有同一个数字证书的应 用程序才能取得该权限.Android使用Java的数字证书相关的机制来 给apk加盖数字证书,要理解android的数字证书,需要先了解以下数字证书的概念和java的数字证书机制.Android系统要求每一个

android WebView详解,常见漏洞详解和安全源码(下)

上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑. 上篇:android WebView详解,常见漏洞详解和安全源码(上) 转载请注明出处:http://blog.csdn.net/self_study/article/details/55046348 对技术感兴趣的同鞋加群 544645972 一起交流. WebView 常见漏洞 WebView 的漏洞也是不少,列举一些常见的漏洞,实时更新,如果有其他的常见漏洞,知会一下我-- WebView

Android+手势识别详解

今天就来把以前的学习文章与经验简单总结中出来吧,在这里我就直接把代码贴下来了,希望能给初学者做最佳的学习参考,也希望有更多的开发人员来加入 ANDROID开发团队,参与更多的创新方式的开发,好了,今天我就简单的讲解一个关于手势识别的最基础也是最需要去掌握的一个技术节点,因为他能给我们 在开发中可能获得最新的用户体验效果,如利用手势识别,你只需要简单的一个手势操作就可能去完成你想要完成的某件可能比较复杂的事情,如通过一个手势来实 现打电话,而并不需要去找你所需要的电话号码这个比较麻烦的过程了,如你

android动画详解三 动画API概述

· 属性动画与view动画的不同之处 view动画系统提供了仅动画View 对象的能力,所以如果你想动画非View 对象,你就要自己实现代码. view动画系统实际上还被强制仅能对 View 的少数属性进行动画,比如缩放和旋转,而不能对背景色进行. view动画的另一个坏处是它仅修改View的绘制位置,而不是View的实际位置.例如,如果你动画一个移动穿越屏幕,button的绘制位置是正确的,但实际你可以点击它的位置却没有变,所以你必须去实现你自己的逻辑来处理它. 使用属性动画系统时,这个限制被

android矩阵详解

Matrix,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matrix由9个float值构成,是一个3*3的矩阵.最好记住.如下图: 解释一下,上面的sinX和cosX,表示旋转角度的cos值和sin值,注意,旋转角度是按顺时针方向计算的. translateX和translateY表示x和y的平移量.scale是缩放的比例,1是不变,2是表示缩放1/2,这样子. 在android.graphics.Matrix中有对应旋转的函

Android ProgressBar详解以及自定义

版本:1.0 日期:2014.5.16 版权:© 2014 kince 转载注明出处 这一次主要说一下Android下的进度条,为什么是它呢,因为近期被其各种美轮美奂的设计所倾倒,计划逐渐去实现.另外一个因素也是它也是为数不多的直接继承于View类的控件,从中可以学习到一些自定义控件的知识.下面列举了一些个人觉得还算漂亮的进度条,仅供参考. 是不是很漂亮,其实就像上面图形展示的那样,进度条大体上无非就是这几种形式.这样一来肯定是需要自定义了,所以方向有两个:要么继承于系统的ProgressBar

Android 菜单详解

Android中菜单分为三种,选项菜单(OptionMenu),上下文菜单(ContextMenu),子菜单(SubMenu) 选项菜单 可以通过两种办法增加选项菜单,一是在menu.xml中添加,该种方式参见Android 资源详解(二) 菜单资源,二是在.java中添加 1.覆盖Activity 的 onCreateOptionsMenu(Menu  menu)方法,当我们第一次打开菜单 时该方法被自动调用. 2.调用Menu的 add()方法添加菜单项(Menultem) ,可以调用Men

Android菜单详解(一)——理解android中的Menu

前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至今为止看到的最好的一本android书,中文版出到<精通Android 2>. 理解Android的菜单 菜单是许多应用程序不可或缺的一部分,Android中更是如此,所有搭载Android系统的手机甚至都要有一个"Menu"键,由此可见菜单在Android程序中的特殊性.An