android加快启动页速度,Android提高启动速度

三,系统服务初始化和package扫描

在启动系统服务的init2()时会启动应用层(Java层)的所有服务。

public static void main(String[] args) {

System.loadLibrary("Android_servers");

init1(args); //init1 初始化,完成之后会回调init2()

}

在init2()中会启动一个线程来启动所有服务

public static final void init2() {

Log.i(TAG, "Entered the Android system server!");

Thread thr = new ServerThread();

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

thr.start();

}

class ServerThread extends Thread {

。。。

public void run() {

。。。

关键服务:

ServiceManager.addService("entropy", new EntropyService());

ServiceManager.addService(Context.POWER_SERVICE, power);

context = ActivityManagerService.main(factoryTest);

ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));

PackageManagerService.main(context,

factoryTest != SystemServer.FACTORY_TEST_OFF);//apk扫描的服务

ServiceManager.addService(Context.ACCOUNT_SERVICE,

new AccountManagerService(context));

ContentService.main(context,

factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

battery = new BatteryService(context);

ServiceManager.addService("battery", battery);

hardware = new HardwareService(context);

ServiceManager.addService("hardware", hardware);

AlarmManagerService alarm = new AlarmManagerService(context);

ServiceManager.addService(Context.ALARM_SERVICE, alarm);

ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context));

WindowManagerService.main(context, power,

factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);

ServiceManager.addService(Context.WINDOW_SERVICE, wm);

上面这些都是关键服务,不建议进行裁剪。

下面的这些不是很关键,可以进行裁剪,当是必须相应的修改framework部分的代码,工作量比较大和复杂。我去掉了20个服务,大概需要相应修改大概20多个文件。

statusBar = new StatusBarService(context);

ServiceManager.addService("statusbar", statusBar);

ServiceManager.addService("clipboard", new ClipboardService(context));

imm = new InputMethodManagerService(context, statusBar);

ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);

ServiceManager.addService("netstat", new NetStatService(context));

connectivity = ConnectivityService.getInstance(context);

ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,

new AccessibilityManagerService(context));

notification = new NotificationManagerService(context, statusBar, hardware);

ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);

ServiceManager.addService("mount", new MountService(context));

ServiceManager.addService(DeviceStorageMonitorService.SERVICE,

new DeviceStorageMonitorService(context));

ServiceManager.addService(Context.LOCATION_SERVICE, new LocationManagerService(context));

ServiceManager.addService( Context.SEARCH_SERVICE, new SearchManagerService(context) );

if (INCLUDE_DEMO) {

Log.i(TAG, "Installing demo data...");

(new DemoThread(context)).start();

}

Intent intent = new Intent().setComponent(new ComponentName(

"com.google.android.server.checkin",

"com.google.android.server.checkin.CheckinService"));

ServiceManager.addService("checkin", new FallbackCheckinService(context));

wallpaper = new WallpaperManagerService(context);

ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);

ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));

headset = new HeadsetObserver(context);

dock = new DockObserver(context, power);

ServiceManager.addService(Context.BACKUP_SERVICE, new BackupManagerService(context));

ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);package 扫描部分,整个流程为

callstatic("com/android/server/SystemServer","init2")

init2()

main(context, factoryTest)

PackageManagerService(context, factoryTest)

scanDirLI(dir, flags, mode)

scanPackageLI(file, file resfile, flags, mode)

parsePackage(file, dest filename, metrics, flags)

parsePackage(file, dest, metrics, flags)

openXmlResourceParser(cookie, filename) (“AndroidManifest.xml“)

openXmlBlockAsset(cookie, filename)

openXmlAssetNative(cookie, filename)

android_content_AssetManager_openXmlAssetNative

openNonAsset(cookie, filename, flag)

openNonAssetInPathLocked(filename, mode, asset_path)

getZipFileLocked(asset_path)

getZip(ap.path)

get(path)

getZip()

SharedZip(path, modWhen)

ZipFileRO::open(path)

parseZipArchive(void)

get4LE(ptr)

(memory access)

最终的zip文件(apk)读取是在下面这两个函数:

/*

* Open the specified file read-only.  We memory-map the entire thing and

* close the file before returning.

*/

status_t ZipFileRO::open(const char* zipFileName)

{

int fd = -1;

off_t length;

assert(mFileMap == NULL);

LOGD("opening zip '%s'\n", zipFileName);

/*

* Open and map the specified file.

*/

fd = ::open(zipFileName, O_RDONLY);

if (fd < 0) {

LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));

return NAME_NOT_FOUND;

}

length = lseek(fd, 0, SEEK_END);

if (length < 0) {

close(fd);

return UNKNOWN_ERROR;

}

mFileMap = new FileMap();

if (mFileMap == NULL) {

close(fd);

return NO_MEMORY;

}

if (!mFileMap->create(zipFileName, fd, 0, length, true)) {

LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));

close(fd);

return UNKNOWN_ERROR;

}

mFd = fd;

/*

* Got it mapped, verify it and create data structures for fast access.

*/

if (!parseZipArchive()) {

mFileMap->release();

mFileMap = NULL;

return UNKNOWN_ERROR;

}

LOGD("done opening zip\n");

return OK;

}

/*

* Parse the Zip archive, verifying its contents and initializing internal

* data structures.

*/

bool ZipFileRO::parseZipArchive(void)

{

#define CHECK_OFFSET(_off) {                                                \

if ((unsigned int) (_off) >= maxOffset) {                           \

LOGE("ERROR: bad offset %u (max %d): %s\n",                     \

(unsigned int) (_off), maxOffset, #_off);                   \

goto bail;                                                      \

}                                                                   \

}

const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();

const unsigned char* ptr;

size_t length = mFileMap->getDataLength();

bool result = false;

unsigned int i, numEntries, cdOffset;

unsigned int val;

/*

* The first 4 bytes of the file will either be the local header

* signature for the first file (kLFHSignature) or, if the archive doesn't

* have any files in it, the end-of-central-directory signature

* (kEOCDSignature).

*/

val = get4LE(basePtr);

if (val == kEOCDSignature) {

LOGI("Found Zip archive, but it looks empty\n");

goto bail;

} else if (val != kLFHSignature) {

LOGV("Not a Zip archive (found 0x%08x)\n", val);

goto bail;

}

/*

* Find the EOCD.  We'll find it immediately unless they have a file

* comment.

*/

ptr = basePtr + length - kEOCDLen;

while (ptr >= basePtr) {

if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)

break;

ptr--;

}

if (ptr < basePtr) {

LOGI("Could not find end-of-central-directory in Zip\n");

goto bail;

}

/*

* There are two interesting items in the EOCD block: the number of

* entries in the file, and the file offset of the start of the

* central directory.

*

* (There's actually a count of the #of entries in this file, and for

* all files which comprise a spanned archive, but for our purposes

* we're only interested in the current file.  Besides, we expect the

* two to be equivalent for our stuff.)

*/

numEntries = get2LE(ptr + kEOCDNumEntries);

cdOffset = get4LE(ptr + kEOCDFileOffset);

/* valid offsets are [0,EOCD] */

unsigned int maxOffset;

maxOffset = (ptr - basePtr) +1;

LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);

if (numEntries == 0 || cdOffset >= length) {

LOGW("Invalid entries=%d offset=%d (len=%zd)\n",

numEntries, cdOffset, length);

goto bail;

}

/*

* Create hash table.  We have a minimum 75% load factor, possibly as

* low as 50% after we round off to a power of 2.

*/

mNumEntries = numEntries;

mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));

mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);

/*

* Walk through the central directory, adding entries to the hash

* table.

*/

ptr = basePtr + cdOffset;

for (i = 0; i < numEntries; i++) {

unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;

const unsigned char* localHdr;

unsigned int hash;

if (get4LE(ptr) != kCDESignature) {

LOGW("Missed a central dir sig (at %d)\n", i);

goto bail;

}

if (ptr + kCDELen > basePtr + length) {

LOGW("Ran off the end (at %d)\n", i);

goto bail;

}

localHdrOffset = get4LE(ptr + kCDELocalOffset);

CHECK_OFFSET(localHdrOffset);

fileNameLen = get2LE(ptr + kCDENameLen);

extraLen = get2LE(ptr + kCDEExtraLen);

commentLen = get2LE(ptr + kCDECommentLen);

//LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",

//    i, localHdrOffset, fileNameLen, extraLen, commentLen);

//LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);

/* add the CDE filename to the hash table */

hash = computeHash((const char*)ptr + kCDELen, fileNameLen);

addToHash((const char*)ptr + kCDELen, fileNameLen, hash);

//  localHdr = basePtr + localHdrOffset;

//  if (get4LE(localHdr) != kLFHSignature) {

// LOGW("Bad offset to local header: %d (at %d)\n",

//   localHdrOffset, i);

//  goto bail;

//   }

ptr += kCDELen + fileNameLen + extraLen + commentLen;

CHECK_OFFSET(ptr - basePtr);

}

result = true;

bail:

return result;

#undef CHECK_OFFSET

}0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值