展会信息港展会大全

adb install android开发教程
来源:互联网   发布日期:2016-01-14 12:58:32   浏览:2628次  

导读:adb install 也是用的pm命令去安装的,所以开始是在pm java中。frameworks base services java com android server pm1、调用pm程序开始安装得用Pm安装时,一般是shell运行一个pm命令,并传送相应的参数,我们 ...

adb install 也是用的pm命令去安装的,所以开始是在pm.java中。

frameworks\base\services\java\com\android\server\pm

1、调用pm程序开始安装

得用Pm安装时,一般是shell运行一个pm命令,并传送相应的参数,我们通过adb连接到机器,输入pm,会打出pm的一些参数

# pm

pm

frameworks\base\cmds\pm\src\com\android\commands\pm

public static void main(String[] args) {

new Pm().run(args);

}

public void run(String[] args) {

......进行一系列的判断......

if ("install".equals(op)) {

runInstall();

return;

}

}

private void runInstall() {

................此处省略一万字......................

mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,

verificationURI, null);

}

frameworks\base\services\java\com\android\server\pm

public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,

int flags, String installerPackageName, Uri verificationURI,

ManifestDigest manifestDigest) {

.................此处省略一万字.............................

final Message msg = mHandler.obtainMessage(INIT_COPY);

msg.obj = new InstallParams(packageURI, observer,filteredFlags,installerPackageName,

verificationURI, manifestDigest);

mHandler.sendMessage(msg);

}

void doHandleMessage(Message msg) {

switch (msg.what) {

case INIT_COPY: {

if (DEBUG_INSTALL) Slog.i(TAG, "init_copy");

HandlerParams params = (HandlerParams) msg.obj;

int idx = mPendingInstalls.size();

if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx);

// If a bind was already initiated we dont really

// need to do anything. The pending install

// will be processed later on.

if (!mBound) {

// If this is the only one pending we might

// have to bind to the service again.

//连接服务 链接上返回真走else

if (!connectToService()) {

Slog.e(TAG, "Failed to bind to media container service");

params.serviceError();

return;

} else {

// Once we bind to the service, the first

// pending request will be processed.

mPendingInstalls.add(idx, params);

}

} else {

mPendingInstalls.add(idx, params);

// Already bound to the service. Just make

// sure we trigger off processing the first request.

if (idx == 0) {

mHandler.sendEmptyMessage(MCS_BOUND);

}

}

break;

}

调用connectToService方法

private boolean connectToService() {

if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +

" DefaultContainerService");

//连接服务DefaultContainerService

Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);

//设置线程默认应用的优先级

Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);

//在连接成功的时候触发DefaultContainerConnection的onServiceConnected

if (mContext.bindService(service, mDefContainerConn,

Context.BIND_AUTO_CREATE)) {

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

mBound = true;

return true;

}

//设置线程优先级为后台,这样当多个线程并发后很多无关紧要的线程分配的CPU时间将会减少,有利于主线程的处理

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

return false;

}

连接服务DefaultContainerConnection 绑定成功发送一条消息MCS_BOUND

final private DefaultContainerConnection mDefContainerConn =

new DefaultContainerConnection();

class DefaultContainerConnection implements ServiceConnection {

public void onServiceConnected(ComponentName name, IBinder service) {

if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");

IMediaContainerService imcs =

IMediaContainerService.Stub.asInterface(service);

//PackageHandler发了一条MCS_BOUND

mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));

}

public void onServiceDisconnected(ComponentName name) {

if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");

}

};

发送了一条消息MCS_BOUND和 IMediaContainerService imcs 对象

IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(service);

调用方法params.startCopy()

final boolean startCopy() {

boolean res;

try {

if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");

if (++mRetries > MAX_RETRIES) {

Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");

mHandler.sendEmptyMessage(MCS_GIVE_UP);

handleServiceError();

return false;

} else {

//安装前的准备工作

handleStartCopy();

res = true;

}

} catch (RemoteException e) {

if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");

mHandler.sendEmptyMessage(MCS_RECONNECT);

res = false;

}

handleReturnCode();

return res;

}

handleStartCopy进行一些安装前准备工作,最后调用handleReturnCode

void handleReturnCode() {

// If mArgs is null, then MCS couldn't be reached. When it

// reconnects, it will try again to install. At that point, this

// will succeed.

if (mArgs != null) {

processPendingInstall(mArgs, mRet);

}

}

mArgs 在handleStartCopy进行了初始化

/*

* 调用远程方法来获取和安装包信息

* Invoke remote method to get package information and install

* location values. Override install location based on default

* policy if needed and then create install arguments based

* on the install location.

*/

public void handleStartCopy() throws RemoteException {

..............................

int ret = PackageManager.INSTALL_SUCCEEDED;

final InstallArgs args = createInstallArgs(this);

mArgs = args;

}

private void processPendingInstall(final InstallArgs args, final int currentStatus) {

// Queue up an async operation since the package installation may take a little while.

mHandler.post(new Runnable() {

public void run() {

mHandler.removeCallbacks(this);

// Result object to be returned

PackageInstalledInfo res = new PackageInstalledInfo();

res.returnCode = currentStatus;

res.uid = -1;

res.pkg = null;

res.removedInfo = new PackageRemovedInfo();

if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {

args.doPreInstall(res.returnCode);

synchronized (mInstallLock) {

installPackageLI(args, true, res);

}

args.doPostInstall(res.returnCode);

}

installPackageLI调用这个方法

在installPackageLI中,会new 一个PackageParser对package进行解析,调用parsePackage函数 parsePackage(File sourceFile, String destCodePath,

DisplayMetrics metrics, int flags)函数根据参数进行一些处理后最终调用parsePackage(

Resources res, XmlResourceParser parser, int flags, String[] outError)对包进行解析,我们看到这个函数里面主要对配置文件AndroidManifest.xml文件进行了解析。

//这个函数里面主要对配置文件AndroidManifest.xml文件进行了解析

//返回解析到的所有数据pkg

final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,

null, mMetrics, parseFlags);

private void installPackageLI(InstallArgs args,

boolean newInstall, PackageInstalledInfo res) {

..............................

//replace判断设备上面是否有安装的app

if (replace) {

replacePackageLI(pkg, parseFlags, scanMode,

installerPackageName, res);

} else {

installNewPackageLI(pkg, parseFlags, scanMode,

installerPackageName,res);

}

}

private void installNewPackageLI(PackageParser.Package pkg,

int parseFlags,int scanMode,

String installerPackageName, PackageInstalledInfo res) {

***********************省略若干*************************************************

PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,

System.currentTimeMillis());

***********************省略若干**************************************************

}

跟踪scanPackageLI()方法后发现,程序经过很多次的if else 的筛选,最后判定可以安装后调用了 mInstaller.install

if (mInstaller != null) {

int ret = mInstaller.install(pkgName, useEncryptedFSDir,pkg.applicationInfo.uid,pkg.applicationInfo.uid);

if(ret < 0) {

// Error from installer

mLastScanError =PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;

return null;

}

}

赞助本站

人工智能实验室

相关热词: adb install android

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港