您的位置:首页 > 移动开发 > Android开发

修改Android系统源代码,优化开机速度。

2015-01-23 22:57 134 查看
下面部分写的比较零散,整合了一下,可以移步到最新一篇:

http://blog.csdn.net/xxm282828/article/details/49095839

通常情况下,Android系统开机保持在20s~25s应该算是合格比较好的状态。

最近几天在看关于Android系统开机启动过程的相关内容。做个笔记。

关于有话Android系统开机时间有话,采取三个措施有话,修改ZygoteInit.java。 Android系统开机启动过程这里就不说了,网上很多大牛对应的文章。

1. 修改ZygoteInit.java 中预加载资源函数preload() ,  preloadClasses(); 与 preloadResources(); 并行加载。
2. 修改读取配置信息过程中GC频率。
3. 提升进程优先级。


1.

static void preload() {
        //
        Thread  preloadRsThread = new Thread(new Runnable(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
            //将该资源加载放在子线程中  。加载资源文件要比加载classes文件要快,因此这里不提升子线程优先级。  
            preloadResources();
            }

        }) ;

        preloadRsThread.start() ;
        preloadClasses();
        //wait preloadRes complete.
        try {
            preloadRsThread.join() ;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
        //暴露什么问题。
        preloadOpenGL();
    }




2.
/**
     * Performs Zygote process initialization. Loads and initializes
     * commonly used classes.
     *
     * Most classes only cause a few hundred bytes to be allocated, but
     * a few will allocate a dozen Kbytes (in one case, 500+K).
     */
    private static void preloadClasses() {
        final VMRuntime runtime = VMRuntime.getRuntime();

        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(
                PRELOADED_CLASSES);
        if (is == null) {
            Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
        } else {
            Log.i(TAG, "Preloading classes...");
            long startTime = SystemClock.uptimeMillis();

            // Drop root perms while running static initializers.
            setEffectiveGroup(UNPRIVILEGED_GID);
            setEffectiveUser(UNPRIVILEGED_UID);

            // Alter the target heap utilization.  With explicit GCs this
            // is not likely to have any effect.
            float defaultUtilization = runtime.getTargetHeapUtilization();
            runtime.setTargetHeapUtilization(0.8f);

            // Start with a clean slate.
            System.gc();
            runtime.runFinalizationSync();
            Debug.startAllocCounting();

            try {
                BufferedReader br
                    = new BufferedReader(new InputStreamReader(is), 256);

                int count = 0;
                String line;
                while ((line = br.readLine()) != null) {
                    // Skip comments and blank lines.
                    line = line.trim();
                    if (line.startsWith("#") || line.equals("")) {
                        continue;
                    }

                    try {
                        if (false) {
                            Log.v(TAG, "Preloading " + line + "...");
                        }
                        Class.forName(line);
                        //减少GC频率,modify   begin
                        if (count%128==0&&Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {//end
                            if (false) {
                                Log.v(TAG,
                                    " GC at " + Debug.getGlobalAllocSize());
                            }
                            System.gc();
                            runtime.runFinalizationSync();
                            Debug.resetGlobalAllocSize();
                        }
                        count++;
                    } catch (ClassNotFoundException e) {
                        Log.w(TAG, "Class not found for preloading: " + line);
                    } catch (UnsatisfiedLinkError e) {
                        Log.w(TAG, "Problem preloading " + line + ": " + e);
                    } catch (Throwable t) {
                        Log.e(TAG, "Error preloading " + line + ".", t);
                        if (t instanceof Error) {
                            throw (Error) t;
                        }
                        if (t instanceof RuntimeException) {
                            throw (RuntimeException) t;
                        }
                        throw new RuntimeException(t);
                    }
                }

                Log.i(TAG, "...preloaded " + count + " classes in "
                        + (SystemClock.uptimeMillis()-startTime) + "ms.");
            } catch (IOException e) {
                Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
            } finally {
                IoUtils.closeQuietly(is);
                // Restore default.
                runtime.setTargetHeapUtilization(defaultUtilization);

                // Fill in dex caches with classes, fields, and methods brought in by preloading.
                runtime.preloadDexCaches();

                Debug.stopAllocCounting();

                // Bring back root. We'll need it later.
                setEffectiveUser(ROOT_UID);
                setEffectiveGroup(ROOT_GID);
            }
        }
    }


3.

//    ZygoteInit.java入口
    public static void main(String argv[]) {
        try {

            //优化开机速度 begin
            /* 20150127 begin */
            //获取当前进程优先级
            int currentPriority = Process.getThreadPriority(Process.myPid()) ;
            //提升当前进程优先级。
            Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO) ;
            /* 20150127 end */
            
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

//            1.注册socket服务端
            registerZygoteSocket();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
//            5.加载资源
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gc();
            
            /* 20150127 begin */
            Process.setThreadPriority(currentPriority) ;
            /* 20150127 end */
            //优化开机速度 end
            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);

            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }
//          2. 调用starySystemServer()方法
            if (argv[1].equals("start-system-server")) {
                startSystemServer();
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            Log.i(TAG, "Accepting command socket connections");

            //3.循环监听并接收客户端请求。
            runSelectLoop();
//关闭socket
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
//          4  《深入理解Android卷1》作者说这里比较重要
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }


4.修改gc调用阀值

/** when preloading, GC after allocating this many bytes 
     * 
     * 20150127 优化开机速度
     */
    
    //- private static final int PRELOAD_GC_THRESHOLD = 50000;
    private static final int PRELOAD_GC_THRESHOLD = 64*1024*1024;
    
    /*20150127 优化开机速度 end*/


另外,Android系统启动过程中,会预先加载资源文件,这些文件中,包含了很多系统应用会频繁使用到的资源文件,比如图片资源等。因此,我们自己的新添加其他的部分资源也可以预先加载到内存,

这样不仅提升响应速度,而且也可以加快应用的冷启动速度。

Android系统性能优化是个大工程,从一个小小的细节出发,或许能收获哪怕几百毫秒的时间,也是不错的。细节决定成败。

关于进程优先级:

参考:/article/1921337.html

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //设置线程优先级为后台,这样当多个线程并发后很多无关紧要的线程分配的CPU时间将会减少,有利于主线程的处理,有以下几种:
		int THREAD_PRIORITY_AUDIO ;//标准音乐播放使用的线程优先级
		int THREAD_PRIORITY_BACKGROUND ;//标准后台程序
		int THREAD_PRIORITY_DEFAULT ;// 默认应用的优先级
		int THREAD_PRIORITY_DISPLAY ;//标准显示系统优先级,主要是改善UI的刷新
		int THREAD_PRIORITY_FOREGROUND ; //标准前台线程优先级
		int THREAD_PRIORITY_LESS_F***ORABLE ;//低于favorable
		int THREAD_PRIORITY_LOWEST  ;//有效的线程最低的优先级
		int THREAD_PRIORITY_MORE_F***ORABLE ; //高于favorable
		int THREAD_PRIORITY_URGENT_AUDIO  ;//标准较重要音频播放优先级
		int THREAD_PRIORITY_URGENT_DISPLAY  ;//标准较重要显示优先级,对于输入事件同样适用。


Android系统开机优化,可以修改的地方还有很多。后续会补上。

此外,Android开机过程中,PackageManagerService会扫描系统内置apk,因此这个过程也是耗费时间比较长的。

在这个过程中下功夫还是很有必要。

比如odex优化等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: