/**Reports if the given class should be preloaded. */
    public static boolean isPreloadable(LoadedClass clazz) {
三,系统服务初始化和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
}
 
养成励志的习惯,一生励志   
30本经典Linux学习和开发教程和资料 
15本经典C、C++、MFC、VC++教程
10本经典Java教程
15本经典Android教程和海量Android源码