android APK应用安装过程以及默认安装路径_第1页
android APK应用安装过程以及默认安装路径_第2页
android APK应用安装过程以及默认安装路径_第3页
android APK应用安装过程以及默认安装路径_第4页
android APK应用安装过程以及默认安装路径_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

androidAPK应用安装过程以及默认安装路径

分类:

Android一:安装过程APK是类似SymbianSis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。Android应用安装有如下四种方式

1.

系统应用安装――开机时完成,没有安装界面

2.

网络下载应用安装――通过market应用完成,没有安装界面

3.

ADB工具安装――没有安装界面。

4.

第三方应用安装――通过SD卡里的APK文件安装,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。

应用安装的流程及路径

应用安装涉及到如下几个目录:

system/app

系统自带的应用程序,无法删除

data/app

用户程序安装的目录,有删除权限。

安装时把apk文件复制到此目录

data/data

存放应用程序的数据

Data/dalvik-cache

将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)

安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。

卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。

一、系统应用安装:

PackageManagerService处理各种应用的安装,卸载,管理等工作,开机时由systemServer启动此服务

(源文件路径:android\frameworks\base\services\java\com\android\server\PackageManagerService.java)

PackageManagerService服务启动的流程:

1.首先扫描安装“system\framework”目录下的jar包

1.scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM,

scanMode|SCAN_NO_DEX);

2.第二步扫描安装“system\app”目录下的各个系统应用

scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM,scanMode);

3.第三步扫描“data\app”目录,即用户安装的第三方应用

scanDirLI(mAppInstallDir,0,scanMode);

4.第四步扫描"data\app-private"目录,即安装DRM保护的APK文件(目前没有遇到过此类的应用)。

scanDirLI(mDrmAppPrivateInstallDir,0,scanMode|SCAN_FORWARD_LOCKED);

安装应用的过程

1.scanDirLI(Filedir,intflags,intscanMode)遍历安装指定目录下的文件

2.scanPackageLI(FilescanFile,

FiledestCodeFile,FiledestResourceFile,intparseFlags,

intscanMode)

安装package文件

3.scanPackageLI(

FilescanFile,FiledestCodeFile,FiledestResourceFile,

PackageParser.Packagepkg,intparseFlags,intscanMode)

通过解析安装包parsePackage获取到安装包的信息结构

4.mInstaller.install(pkgName,pkg.applicationInfo.uid,

pkg.applicationInfo.uid);

实现文件复制的安装过程

(源文件路径:frameworks\base\cmds\installd\installd.install)

二、从market上下载应用:

GoogleMarket应用需要使用gmail账户登录才可以使用,选择某一应用后,开始下载安装包,此过程中,在手机的信号区有进度条提示,下载完成后,会自动调用Packagemanager的接口安装,调用接口如下:

publicvoidinstallPackage(finalUripackageURI,finalIPackageInstallObserverobserver,finalintflags)

finalUripackageURI:文件下载完成后保存的路径

finalIPackageInstallObserverobserver:处理返回的安装结果

finalintflags:安装的参数,从market上下载的应用,安装参数为-r(replace)

installPackage接口函数的安装过程:

1.publicvoidinstallPackage(

finalUripackageURI,finalIPackageInstallObserverobserver,finalintflags,

finalStringinstallerPackageName)

finalStringinstallerPackageName:安装完成后此名称保存在settings里,一般为null,不是关键参数

2.FiletmpPackageFile=copyTempInstallFile(packageURI,res);

把apk文件复制到临时目录下的临时文件

3.privatevoidinstallPackageLI(UripPackageURI,

intpFlags,booleannewInstall,StringinstallerPackageName,

FiletmpPackageFile,PackageInstalledInfores)

解析临时文件,获取应用包名pkgName=PackageParser.parsePackageName(

tmpPackageFile.getAbsolutePath(),0);

4.判断如果带有参数INSTALL_REPLACE_EXISTING,则调用replacePackageLI(pkgName,

tmpPackageFile,

destFilePath,destPackageFile,destResourceFile,

pkg,forwardLocked,newInstall,installerPackageName,

res)

5.如果没有,则调用installNewPackageLI(pkgName,

tmpPackageFile,

destFilePath,destPackageFile,destResourceFile,

pkg,forwardLocked,newInstall,installerPackageName,

res);

6.privatePackageParser.PackagescanPackageLI(

FilescanFile,FiledestCodeFile,FiledestResourceFile,

PackageParser.Packagepkg,intparseFlags,intscanMode)

scanPackageLI以后的流程,与开机时的应用安装流程相同。

三、从ADB工具安装

AndroidDebugBridge(adb)是SDK自带的管理设备的工具,通过ADB命令行的方式也可以为手机或模拟器安装应用,其入口函数源文件为pm.java

(源文件路径:android\frameworks\base\cmds\pm\src\com\android\commands\pm\pm.java)

ADB命令行的形式为adbinstall<path_to_apk>,还可以带安装参数如:"-l""-r""-i""-t"

函数runInstall()中判断参数

"-l"――INSTALL_FORWARD_LOCK

"-r"——INSTALL_REPLACE_EXISTING

"-i"——installerPackageName

"-t"——INSTALL_ALLOW_TEST

我们常用的参数为-r,表示覆盖安装手机上已安装的同名应用。从market上下载的应用,也是直接传入这个参数安装的。

runInstall与market调用同样的接口完成应用安装。

publicvoidinstallPackage(.UripackageURI,android.content.pm.IPackageInstallObserverobserver,intflags,java.lang.StringinstallerPackageName)

四、第三方应用安装――通过SD卡里的APK文件安装

把APK安装包保存在SD卡中,从手机里访问SD卡中的APK安装包,点击就可以启动安装界面,系统应用Packageinstaller.apk处理这种方式下的安装及卸载界面流程,如下图:

PackageInstallerActivity负责解析包,判断是否是可用的Apk文件

创建临时安装文件/data/data/com.android.packageinstaller/files/ApiDemos.apk

并启动安装确认界面startInstallConfirm,列出解析得到的该应用基本信息。如果手机上已安装有同名应用,则需要用户确认是否要替换安装。

确认安装后,启动InstallAppProgress,调用安装接口完成安装。

pm.installPackage(mPackageURI,observer,installFlags);

其它:

1.PackageManagerService.java的内部类AppDirObserver实现了监听app目录的功能:当把某个APK拖到app目录下时,可以直接调用scanPackageLI完成安装。

2.手机数据区目录“data/system/packages.xml”文件中,包含了手机上所有已安装应用的基本信息,如安装路径,申请的permission等信息。二:更改默认安装路径

如果你是一个apk应用开发者,没用android系统全套代码,你只想更改你的APK的默认安装路径的话,可以按下面方法来更改:在AndroidManifest.xml文件Manifest标签中添加android:installLocation属性android:installLocation这个属性设置的是默认安装位置,共有三个有效值,auto、internalOnly、preferExternal对应表auto表示自动,由系统决定安装位置,如果系统手机内存足够,默认安装在手机内存里,如果手机内在不够,则会安装在T卡内internalOnly安装在手机内存preferExternal安装在外部存储中ConstantValueDescriptionauto0LetthesystemdecideinstalllocationinternalOnly1ExplicitlyrequesttobeinstalledoninternalphonestorageonlypreferExternal2PerfertobeinstalledonSDcard,Thereisnoguaranteethatthesystemwillhonorthisrequest.Theapplicationmightendupbeinginstalledoninternalstorageifexternalmediaisunavailableortoofull

<manifestxmlns:android="/apk/res/android"package="com.ray"android:installLocation="auto"android:versionCode="1"android:versionName="1.0">如果你是一个手机方案开发者,能改framework层的代码,你希望下载到手机里的APK都默认优先安装到T卡的话,可以按下面方法更改:在PackageParser.java文件里,将privatestaticfinalintPARSE_DEFAULT_INSTALL_LOCATION

这个PARSE_DEFAULT_INSTALL_LOCATION值,改为PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL,就可以了.默认下载就会下到T卡里,T卡不存在或者满了时,才会下到手机内部.或者如果在应用的AndroidManifest.xml里,指定了installLocation属性为手机内部存储的话,是会存在手机内部的.没指这定的话,PARSE_DEFAULT_INSTALL_LOCATION这个值指定什么,就下到哪里安装在T卡里的应用,有几个缺点:

1:因为android装载T卡是在系统启动完成后,才开始装载的.所以如果应用装在T卡里的话,那么它是收不到开机启动完成的BOOT_COMPLETED这个广播的

2:如果T卡损坏或者T卡拨出来了,那么装在T卡里的应用是启动不了的.系统应用安装的详细过程,老罗有篇文章写得很透彻,这里引用下:Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息,完成应用程序的安装过程,本文将详细分析这个过程。

应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、BroadcastReceiver和ContentProvider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。

应用程序管理服务PackageManagerService是系统启动的时候由SystemServer组件启动的,启后它就会执行应用程序安装的过程,因此,本文将从SystemServer启动PackageManagerService服务的过程开始分析系统中的应用程序安装的过程。

应用程序管理服务PackageManagerService从启动到安装应用程序的过程如下图所示:

下面我们具体分析每一个步骤。

Step1.SystemServer.main

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:[java]

\o"viewplain"viewplain\o"copy"copypublic

class

SystemServer

{

......

native

public

static

void

init1(String[]

args);

......

public

static

void

main(String[]

args)

{

......

init1(args);

......

}

......

}

SystemServer组件是由Zygote进程负责启动的,启动的时候就会调用它的main函数,这个函数主要调用了JNI方法init1来做一些系统初始化的工作。

Step2.SystemServer.init1

这个函数是一个JNI方法,实现在

frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中:[cpp]

\o"viewplain"viewplain\o"copy"copynamespace

android

{

extern

"C"

int

system_init();

static

void

android_server_SystemServer_init1(JNIEnv*

env,

jobject

clazz)

{

system_init();

}

/*

*

JNI

registration.

*/

static

JNINativeMethod

gMethods[]

=

{

/*

name,

signature,

funcPtr

*/

{

"init1",

"([Ljava/lang/String;)V",

(void*)

android_server_SystemServer_init1

},

};

int

register_android_server_SystemServer(JNIEnv*

env)

{

return

jniRegisterNativeMethods(env,

"com/android/server/SystemServer",

gMethods,

NELEM(gMethods));

}

};

//

namespace

android

这个函数很简单,只是调用了system_init函数来进一步执行操作。

Step3.

libsystem_server.system_init

函数system_init实现在libsystem_server库中,源代码位于frameworks/base/cmds/system_server/library/system_init.cpp文件中:[cpp]

\o"viewplain"viewplain\o"copy"copyextern

"C"

status_t

system_init()

{

LOGI("Entered

system_init()");

sp<ProcessState>

proc(ProcessState::self());

sp<IServiceManager>

sm

=

defaultServiceManager();

LOGI("ServiceManager:

%p\n",

sm.get());

sp<GrimReaper>

grim

=

new

GrimReaper();

sm->asBinder()->linkToDeath(grim,

grim.get(),

0);

char

propBuf[PROPERTY_VALUE_MAX];

property_get("system_init.startsurfaceflinger",

propBuf,

"1");

if

(strcmp(propBuf,

"1")

==

0)

{

//

Start

the

SurfaceFlinger

SurfaceFlinger::instantiate();

}

//

Start

the

sensor

service

SensorService::instantiate();

//

On

the

simulator,

audioflinger

et

al

don't

get

started

the

//

same

way

as

on

the

device,

and

we

need

to

start

them

here

if

(!proc->supportsProcesses())

{

//

Start

the

AudioFlinger

AudioFlinger::instantiate();

//

Start

the

media

playback

service

MediaPlayerService::instantiate();

//

Start

the

camera

service

CameraService::instantiate();

//

Start

the

audio

policy

service

AudioPolicyService::instantiate();

}

//

And

now

start

the

Android

runtime.

We

have

to

do

this

bit

//

of

nastiness

because

the

Android

runtime

initialization

requires

//

some

of

the

core

system

services

to

already

be

started.

//

All

other

servers

should

just

start

the

Android

runtime

at

//

the

beginning

of

their

processes's

main(),

before

calling

//

the

init

function.

LOGI("System

server:

starting

Android

runtime.\n");

AndroidRuntime*

runtime

=

AndroidRuntime::getRuntime();

LOGI("System

server:

starting

Android

services.\n");

runtime->callStatic("com/android/server/SystemServer",

"init2");

//

If

running

in

our

own

process,

just

go

into

the

thread

//

pool.

Otherwise,

call

the

initialization

finished

//

func

to

let

this

process

continue

its

initilization.

if

(proc->supportsProcesses())

{

LOGI("System

server:

entering

thread

pool.\n");

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

LOGI("System

server:

exiting

thread

pool.\n");

}

return

NO_ERROR;

}

这个函数首先会初始化SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService、CameraService和AudioPolicyService这几个服务,然后就通过系统全局唯一的AndroidRuntime实例变量runtime的callStatic来调用SystemServer的init2函数了。关于这个AndroidRuntime实例变量runtime的相关资料,可能参考前面一篇文章Android应用程序进程启动过程的源代码分析一文。

Step4.AndroidRuntime.callStatic

这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:[cpp]

\o"viewplain"viewplain\o"copy"copy/*

*

Call

a

static

Java

Programming

Language

function

that

takes

no

arguments

and

returns

void.

*/

status_t

AndroidRuntime::callStatic(const

char*

className,

const

char*

methodName)

{

JNIEnv*

env;

jclass

clazz;

jmethodID

methodId;

env

=

getJNIEnv();

if

(env

==

NULL)

return

UNKNOWN_ERROR;

clazz

=

findClass(env,

className);

if

(clazz

==

NULL)

{

LOGE("ERROR:

could

not

find

class

'%s'\n",

className);

return

UNKNOWN_ERROR;

}

methodId

=

env->GetStaticMethodID(clazz,

methodName,

"()V");

if

(methodId

==

NULL)

{

LOGE("ERROR:

could

not

find

method

%s.%s\n",

className,

methodName);

return

UNKNOWN_ERROR;

}

env->CallStaticVoidMethod(clazz,

methodId);

return

NO_ERROR;

}

这个函数调用由参数className指定的java类的静态成员函数,这个静态成员函数是由参数methodName指定的。上面传进来的参数className的值为"com/android/server/SystemServer",而参数methodName的值为"init2",因此,接下来就会调用SystemServer类的init2函数了。

Step5.

SystemServer.init2

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:[java]

\o"viewplain"viewplain\o"copy"copypublic

class

SystemServer

{

......

public

static

final

void

init2()

{

Slog.i(TAG,

"Entered

the

Android

system

server!");

Thread

thr

=

new

ServerThread();

thr.setName("android.server.ServerThread");

thr.start();

}

}

这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例的run函数了。

Step6.

ServerThread.run

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:[java]

\o"viewplain"viewplain\o"copy"copyclass

ServerThread

extends

Thread

{

......

@Override

public

void

run()

{

......

IPackageManager

pm

=

null;

......

//

Critical

services...

try

{

......

Slog.i(TAG,

"Package

Manager");

pm

=

PackageManagerService.main(context,

factoryTest

!=

SystemServer.FACTORY_TEST_OFF);

......

}

catch

(RuntimeException

e)

{

Slog.e("System",

"Failure

starting

core

service",

e);

}

......

}

......

}

这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务,例如在前面学习Activity和Service的几篇文章中经常看到的ActivityManagerService服务,有兴趣的读者可以自己研究一下。

Step7.

PackageManagerService.main

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:[cpp]

\o"viewplain"viewplain\o"copy"copyclass

PackageManagerService

extends

IPackageManager.Stub

{

......

public

static

final

IPackageManager

main(Context

context,

boolean

factoryTest)

{

PackageManagerService

m

=

new

PackageManagerService(context,

factoryTest);

ServiceManager.addService("package",

m);

return

m;

}

......

}

这个函数创建了一个PackageManagerService服务实例,然后把这个服务添加到ServiceManager中去,ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象,具体可以参考浅谈ServiceManager成为Android进程间通信(IPC)机制Binder守护进程之路一文。

在创建这个PackageManagerService服务实例时,会在PackageManagerService类的构造函数中开始执行安装应用程序的过程:[java]

\o"viewplain"viewplain\o"copy"copyclass

PackageManagerService

extends

IPackageManager.Stub

{

......

public

PackageManagerService(Context

context,

boolean

factoryTest)

{

......

synchronized

(mInstallLock)

{

synchronized

(mPackages)

{

......

File

dataDir

=

Environment.getDataDirectory();

mAppDataDir

=

new

File(dataDir,

"data");

mSecureAppDataDir

=

new

File(dataDir,

"secure/data");

mDrmAppPrivateInstallDir

=

new

File(dataDir,

"app-private");

......

mFrameworkDir

=

new

File(Environment.getRootDirectory(),

"framework");

mDalvikCacheDir

=

new

File(dataDir,

"dalvik-cache");

......

//

Find

base

frameworks

(resource

packages

without

code).

mFrameworkInstallObserver

=

new

AppDirObserver(

mFrameworkDir.getPath(),

OBSERVER_EVENTS,

true);

mFrameworkInstallObserver.startWatching();

scanDirLI(mFrameworkDir,

PackageParser.PARSE_IS_SYSTEM

|

PackageParser.PARSE_IS_SYSTEM_DIR,

scanMode

|

SCAN_NO_DEX,

0);

//

Collect

all

system

packages.

mSystemAppDir

=

new

File(Environment.getRootDirectory(),

"app");

mSystemInstallObserver

=

new

AppDirObserver(

mSystemAppDir.getPath(),

OBSERVER_EVENTS,

true);

mSystemInstallObserver.startWatching();

scanDirLI(mSystemAppDir,

PackageParser.PARSE_IS_SYSTEM

|

PackageParser.PARSE_IS_SYSTEM_DIR,

scanMode,

0);

//

Collect

all

vendor

packages.

mVendorAppDir

=

new

File("/vendor/app");

mVendorInstallObserver

=

new

AppDirObserver(

mVendorAppDir.getPath(),

OBSERVER_EVENTS,

true);

mVendorInstallObserver.startWatching();

scanDirLI(mVendorAppDir,

PackageParser.PARSE_IS_SYSTEM

|

PackageParser.PARSE_IS_SYSTEM_DIR,

scanMode,

0);

mAppInstallObserver

=

new

AppDirObserver(

mAppInstallDir.getPath(),

OBSERVER_EVENTS,

false);

mAppInstallObserver.startWatching();

scanDirLI(mAppInstallDir,

0,

scanMode,

0);

mDrmAppInstallObserver

=

new

AppDirObserver(

mDrmAppPrivateInstallDir.getPath(),

OBSERVER_EVENTS,

false);

mDrmAppInstallObserver.startWatching();

scanDirLI(mDrmAppPrivateInstallDir,

PackageParser.PARSE_FORWARD_LOCK,

scanMode,

0);

......

}

}

}

......

}

这里会调用scanDirLI函数来扫描移动设备上的下面这五个目录中的Apk文件:

/system/framework

/system/app

/vendor/app

/data/app

/data/app-private

Step8.

PackageManagerService.scanDirLI

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:[java]

\o"viewplain"viewplain\o"copy"copyclass

PackageManagerService

extends

IPackageManager.Stub

{

......

private

void

scanDirLI(File

dir,

int

flags,

int

scanMode,

long

currentTime)

{

String[]

files

=

dir.list();

......

int

i;

for

(i=0;

i<files.length;

i++)

{

File

file

=

new

File(dir,

files[i]);

if

(!isPackageFilename(files[i]))

{

//

Ignore

entries

which

are

not

apk's

continue;

}

PackageParser.Package

pkg

=

scanPackageLI(file,

flags|PackageParser.PARSE_MUST_BE_APK,

scanMode,

currentTime);

//

Don't

mess

around

with

apps

in

system

partition.

if

(pkg

==

null

&&

(flags

&

PackageParser.PARSE_IS_SYSTEM)

==

0

&&

mLastScanError

==

PackageManager.INSTALL_FAILED_INVALID_APK)

{

//

Delete

the

apk

Slog.w(TAG,

"Cleaning

up

failed

install

of

"

+

file);

file.delete();

}

}

}

......

}

对于目录中的每一个文件,如果是以后Apk作为后缀名,那么就调用scanPackageLI函数来对它进行解析和安装。

Step9.

PackageManagerService.scanPackageLI

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:[java]

\o"viewplain"viewplain\o"copy"copyclass

PackageManagerService

extends

IPackageManager.Stub

{

......

private

PackageParser.Package

scanPackageLI(File

scanFile,

int

parseFlags,

int

scanMode,

long

currentTime)

{

......

String

scanPath

=

scanFile.getPath();

parseFlags

|=

mDefParseFlags;

PackageParser

pp

=

new

PackageParser(scanPath);

......

final

PackageParser.Package

pkg

=

pp.parsePackage(scanFile,

scanPath,

mMetrics,

parseFlags);

......

return

scanPackageLI(pkg,

parseFlags,

scanMode

|

SCAN_UPDATE_SIGNATURE,

currentTime);

}

......

}

这个函数首先会为这个Apk文件创建一个PackageParser实例,接着调用这个实例的parsePackage函数来对这个Apk文件进行解析。这个函数最后还会调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中。

Step10.

PackageParser.parsePackage

这个函数定义在frameworks/base/core/java/android/content/pm/PackageParser.java文件中:[java]

\o"viewplain"viewplain\o"copy"copypublic

class

PackageParser

{

......

public

Package

parsePackage(File

sourceFile,

String

destCodePath,

DisplayMetrics

metrics,

int

flags)

{

......

mArchiveSourcePath

=

sourceFile.getPath();

......

XmlResourceParser

parser

=

null;

AssetManager

assmgr

=

null;

boolean

assetError

=

true;

try

{

assmgr

=

new

AssetManager();

int

cookie

=

assmgr.addAssetPath(mArchiveSourcePath);

if(cookie

!=

0)

{

parser

=

assmgr.openXmlResourceParser(cookie,

"AndroidManifest.xml");

assetError

=

false;

}

else

{

......

}

}

catch

(Exception

e)

{

......

}

......

String[]

errorText

=

new

String[1];

Package

pkg

=

null;

Exception

errorException

=

null;

try

{

//

XXXX

todo:

need

to

figure

out

correct

configuration.

Resources

res

=

new

Resources(assmgr,

metrics,

null);

pkg

=

parsePackage(res,

parser,

flags,

errorText);

}

catch

(Exception

e)

{

......

}

......

parser.close();

assmgr.close();

//

Set

code

and

resource

paths

pkg.mPath

=

destCodePath;

pkg.mScanPath

=

mArchiveSourcePath;

//pkg.applicationInfo.sourceDir

=

destCodePath;

//pkg.applicationInfo.publicSourceDir

=

destRes;

pkg.mSignatures

=

null;

return

pkg;

}

......

}

每一个Apk文件都是一个归档文件,它里面包含了Android应用程序的配置文件AndroidManifest.xml,这里主要就是要对这个配置文件就行解析了,从Apk归档文件中得到这个配置文件后,就调用另一外版本的parsePackage函数对这个应用程序进行解析了:[java]

\o"viewplain"viewplain\o"copy"copypublic

class

PackageParser

{

......

private

Package

parsePackage(

Resources

res,

XmlResourceParser

parser,

int

flags,

String[]

outError)

throws

XmlPullParserException,

IOException

{

......

String

pkgName

=

parsePackageName(parser,

attrs,

flags,

outError);

......

final

Package

pkg

=

new

Package(pkgName);

......

int

type;

......

TypedArray

sa

=

res.obtainAttributes(attrs,

ernal.R.styleable.AndroidManifest);

......

while

((type=parser.next())

!=

parser.END_DOCUMENT

&&

(type

!=

parser.END_TAG

||

parser.getDepth()

>

outerDepth))

{

if

(type

==

parser.END_TAG

||

type

==

parser.TEXT)

{

continue;

}

String

tagName

=

parser.getName();

if

(tagName.equals("application"))

{

......

if

(!parseApplication(pkg,

res,

parser,

attrs,

flags,

outError))

{

return

null;

}

}

else

if

(tagName.equals("permission-group"))

{

......

}

else

if

(tagName.equals("permission"))

{

......

}

else

if

(tagName.equals("permission-tree"))

{

......

}

else

if

(tagName.equals("uses-permission"))

{

......

}

else

if

(tagName.equals("uses-configuration"))

{

......

}

else

if

(tagName.equals("uses-feature"))

{

......

}

else

if

(tagName.equals("uses-sdk"))

{

......

}

else

if

(tagName.equals("supports-screens"))

{

......

}

else

if

(tagName.equals("protected-broadcast"))

{

......

}

else

if

(tagName.equals("instrumentation"))

{

......

}

else

if

(tagName.equals("original-package"))

{

......

}

else

if

(tagName.equals("adopt-permissions"))

{

......

}

else

if

(tagName.equals("uses-gl-texture"))

{

......

}

else

if

(tagName.equals("compatible-screens"))

{

......

}

else

if

(tagName.equals("eat-comment"))

{

......

}

else

if

(RIGID_PARSER)

{

......

}

else

{

......

}

}

......

return

pkg;

}

......

}

这里就是对AndroidManifest.xml文件中的各个标签进行解析了,各个标签的含义可以参考官方文档/guide/topics/manifest/manifest-intro.html,这里我们只简单看一下application标签的解析,这是通过调用parseApplication函数来进行的。

Step11.

PackageParser.parseApplication

这个函数定义在frameworks/base/core/java/android/content/pm/PackageParser.java文件中:[java]

\o"viewplain"viewplain\o"copy"copypublic

class

PackageParser

{

......

private

boolean

parseApplication(Package

owner,

Resources

res,

XmlPullParser

parser,

AttributeSet

attrs,

int

flags,

String[]

outError)

throws

XmlPullParserException,

IOException

{

final

ApplicationInfo

ai

=

owner.applicationInfo;

final

String

pkgName

=

owner.applicationInfo.packageName;

TypedArray

sa

=

res.obtainAttributes(attrs,

ernal.R.styleable.AndroidManifestApplication);

......

int

type;

while

((type=parser.next()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论