Android 深入理解 Watchdog的原理

带着问题去阅读源码是最有效的!

 

一、概述:

       1.1 

          本文围绕以下几个问题点来学习Watchdog:1.Watchdog的工作原理是什么?

                                                                                 2.发生了Watchdog后系统会做什么?有哪些关键的打印信息?

 

       1.2  Watchdog是作用

           Android系统中,有硬件WatchDog用于定时检测关键硬件是否正常工作,类似地,在framework层有一个软件WatchDog用于定期检测关键系统服务是否发生死锁事件。WatchDog功能主要是分析系统核心服务和重要线程是否处于Blocked状态。

 

二、源代码,Watchdog的工作原理

    2.1 Watchdog的启动

          SystemServer.java

   private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
705          t.traceBegin("startBootstrapServices");
706  
707          // Start the watchdog as early as possible so we can crash the system server
708          // if we deadlock during early boot
709          t.traceBegin("StartWatchdog");
710          final Watchdog watchdog = Watchdog.getInstance();
711          watchdog.start();
712          t.traceEnd();

2.2  getInstance

 public static Watchdog getInstance() {
        if (sWatchdog == null) {
            sWatchdog = new Watchdog();
        }

        return sWatchdog;
    }

2.3 Watchdog

 private Watchdog() {
        super("watchdog");
        // Initialize handler checkers for each common thread we want to check.  Note
        // that we are not currently checking the background thread, since it can
        // potentially hold longer running operations with no guarantees about the timeliness
        // of operations there.

        // The shared foreground thread is the main checker.  It is where we
        // will also dispatch monitor checks and do other work.
        mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
                "foreground thread", DEFAULT_TIMEOUT);
        mHandlerCheckers.add(mMonitorChecker);
        // Add checker for main thread.  We only do a quick check since there
        // can be UI running on the thread.
        mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
                "main thread", DEFAULT_TIMEOUT));
        // Add checker for shared UI thread.
        mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),
                "ui thread", DEFAULT_TIMEOUT));
        // And also check IO thread.
        mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
                "i/o thread", DEFAULT_TIMEOUT));
        // And the display thread.
        mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
                "display thread", DEFAULT_TIMEOUT));
        // And the animation thread.
        mHandlerCheckers.add(new HandlerChecker(AnimationThread.getHandler(),
                "animation thread", DEFAULT_TIMEOUT));
        // And the surface animation thread.
        mHandlerCheckers.add(new HandlerChecker(SurfaceAnimationThread.getHandler(),
                "surface animation thread", DEFAULT_TIMEOUT));

        // Initialize monitor for Binder threads.
        addMonitor(new BinderThreadMonitor());//放在后台线程做监听

        mOpenFdMonitor = OpenFdMonitor.create();

        mInterestingJavaPids.add(Process.myPid());

        // See the notes on DEFAULT_TIMEOUT.
        assert DB ||
                DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
    }

  上面创建了FgThread,getMainLooper,UiThread,IoThread,DisplayThread,AnimationThread,SurfaceAnimationThread 这些HandlerChecker,HandlerChecker是Runnable类型。这些HandlerChecker类型被添加到mHandlerCheckers。

2.3.1 HandlerChecker

   public final class HandlerChecker implements Runnable {
        private final Handler mHandler;
        private final String mName;//线程名称
        private final long mWaitMax;//等待的最长时间,正常是60s
        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
        private final ArrayList<Monitor> mMonitorQueue = new ArrayList<Monitor>();
        private boolean mCompleted;//初始化的是是true
        private Monitor mCurrentMonitor;
        private long mStartTime; //开始准备检查的时间点
        private int mPauseCount;

        HandlerChecker(Handler handler, String name, long waitMaxMillis) {
            mHandler = handler;
            mName = name;
            mWaitMax = waitMaxMillis;
            mCompleted = true;
        }

        void addMonitorLocked(Monitor monitor) {
            // We don't want to update mMonitors when the Handler is in the middle of checking
            // all monitors. We will update mMonitors on the next schedule if it is safe
            mMonitorQueue.add(monitor);//添加到列队中
        }
private static final class BinderThreadMonitor implements Watchdog.Monitor {
    public void monitor() {
        Binder.blockUntilThreadAvailable();
    }
}

2.3.2  IPCThreadState.cpp

void IPCThreadState::blockUntilThreadAvailable()
{
    pthread_mutex_lock(&mProcess->mThreadCountLock);
    while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) {
        //等待正在执行的binder线程小于进程最大binder线程上限(16个)
        pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock);
    }
    pthread_mutex_unlock(&mProcess->mThreadCountLock);
}

后面会讲到watchdog的工作原理,这边就提前解释一下。在run 方法中执行mCurrentMonitor.monitor(),monitor就是每个服务(比如 AMS,PMS 等)实现的监听方法,对于binder来说就是blockUntilThreadAvailable方法的调用。当执行这个方法时候发生了卡顿,比如binder线程卡顿或者binder线程的数量大于16,需要等待系统释放其他的binder线程,那么就有可能发生响应超时的情况。Watchdog就会判断系统卡顿。

2.4 run

 @Override
    public void run() {
        boolean waitedHalf = false;
        while (true) {
            final List<HandlerChecker> blockedCheckers;
            final String subject;
            final boolean allowRestart;
            int debuggerWasConnected = 0;
            synchronized (this) {
                long timeout = CHECK_INTERVAL;
                // Make sure we (re)spin the checkers that have become idle within
                // this wait-and-check interval
//遍历所有的添加的hanlercheck,并且会执行scheduleChecklocked 方法,这个方法是Watchdog 核心方法,见2.4.1
                for (int i=0; i<mHandlerCheckers.size(); i++) {
                    HandlerChecker hc = mHandlerCheckers.get(i);
                    hc.scheduleCheckLocked();
                }

                if (debuggerWasConnected > 0) {
                    debuggerWasConnected--;
                }

                // NOTE: We use uptimeMillis() here because we do not want to increment the time we
                // wait while asleep. If the device is asleep then the thing that we are waiting
                // to timeout on is asleep as well and won't have a chance to run, causing a false
                // positive on when to kill things.
                long start = SystemClock.uptimeMillis();
                while (timeout > 0) {//这个while的循环的意义是保证等待的时间是超过30s
                    if (Debug.isDebuggerConnected()) {
                        debuggerWasConnected = 2;
                    }
                    try {
                        wait(timeout);
                        // Note: mHandlerCheckers and mMonitorChecker may have changed after waiting
                    } catch (InterruptedException e) {
                        Log.wtf(TAG, e);
                    }
                    if (Debug.isDebuggerConnected()) {
                        debuggerWasConnected = 2;
                    }
                    timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
                }

                boolean fdLimitTriggered = false;
                if (mOpenFdMonitor != null) {//监听fd leek 的错误。
                    fdLimitTriggered = mOpenFdMonitor.monitor(); 这个判断依据是/proc/self/fd/1012 这个文件。
                }

                if (!fdLimitTriggered) {//一般情况是false ,只有发生了fd leak的时候才是true
				
					这个检查状态是依据此刻的时间与mStartTime的差值,并且与 mWaitMax/2比较,也就是判断是否大于30s还是小于30s
					COMPLETED = 0:等待完成;
					WAITING = 1:等待时间小于DEFAULT_TIMEOUT的一半,即30s;
					WAITED_HALF = 2:等待时间处于30s~60s之间;
					OVERDUE = 3:等待时间大于或等于60s。
					
                    final int waitState = evaluateCheckerCompletionLocked();//见2.4.4
                    if (waitState == COMPLETED) {
                        // The monitors have returned; reset
                        waitedHalf = false;
                        continue;
                    } else if (waitState == WAITING) {
                        // still waiting but within their configured intervals; back off and recheck
                        continue;
                    } else if (waitState == WAITED_HALF) {
                        if (!waitedHalf) {
                            Slog.i(TAG, "WAITED_HALF");
                            // We've waited half the deadlock-detection interval.  Pull a stack
                            // trace and wait another half.
							//第一次超过30s就是打印信息。
                            ArrayList<Integer> pids = new ArrayList<>(mInterestingJavaPids);
                            ActivityManagerService.dumpStackTraces(pids, null, null,
                                    getInterestingNativePids(), null);
                            waitedHalf = true;
                        }
                        continue;
                    }

                    // something is overdue!
					//获取被阻塞的模块 ,判断依据是以是否超过一分钟来判断
                    blockedCheckers = getBlockedCheckersLocked();
                    subject = describeCheckersLocked(blockedCheckers);收集所有的卡顿的describeBlockedStateLocked的打印信息
                } else {
                    blockedCheckers = Collections.emptyList();
                    subject = "Open FD high water mark reached";
                }
                allowRestart = mAllowRestart;//如果是false的话,就不会重启。
            }

            // If we got here, that means that the system is most likely hung.
            // First collect stack traces from all threads of the system process.
            // Then kill this process so that the system will restart.
            EventLog.writeEvent(EventLogTags.WATCHDOG, subject);//所以一旦发生了watchdog的问题 在event log 中能找到相关的打印

            ArrayList<Integer> pids = new ArrayList<>(mInterestingJavaPids);

            long anrTime = SystemClock.uptimeMillis();
            StringBuilder report = new StringBuilder();
            report.append(MemoryPressureUtil.currentPsiState());//添加/proc/pressure/memory节点的信息
            ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(false);
            StringWriter tracesFileException = new StringWriter();
			//第二次以追加的方式,输出system_server和3个native进程的栈信息
            final File stack = ActivityManagerService.dumpStackTraces(
                    pids, processCpuTracker, new SparseArray<>(), getInterestingNativePids(),
                    tracesFileException);

            // Give some extra time to make sure the stack traces get written.
            // The system's been hanging for a minute, another second or two won't hurt much.
            SystemClock.sleep(5000);//系统已被阻塞1分钟,也不在乎多等待5s,来确保stack trace信息输出

            processCpuTracker.update();
            report.append(processCpuTracker.printCurrentState(anrTime));
            report.append(tracesFileException.getBuffer());

            // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log
			///proc/sysrq-trigger 触发kernel输出打印信息
            doSysRq('w');
            doSysRq('l');

            // Try to add the error to the dropbox, but assuming that the ActivityManager
            // itself may be deadlocked.  (which has happened, causing this statement to
            // deadlock and the watchdog as a whole to be ineffective)
            Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
                    public void run() {
                        // If a watched thread hangs before init() is called, we don't have a
                        // valid mActivity. So we can't log the error to dropbox.
                        if (mActivity != null) {
                            mActivity.addErrorToDropBox(
                                    "watchdog", null, "system_server", null, null, null,
                                    subject, report.toString(), stack, null);
                        }
                        FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED,
                                subject);
                    }
                };
            dropboxThread.start();
            try {
                dropboxThread.join(2000);  // wait up to 2 seconds for it to return.
            } catch (InterruptedException ignored) {}

            IActivityController controller;
            synchronized (this) {
                controller = mController;
            }
            if (controller != null) {
                Slog.i(TAG, "Reporting stuck state to activity controller");
                try {
				//将阻塞状态报告给activity controller
                    Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
                    // 1 = keep waiting, -1 = kill system
                    int res = controller.systemNotResponding(subject);
					 //返回值为1表示继续等待,-1表示杀死系统
                    if (res >= 0) {
                        Slog.i(TAG, "Activity controller requested to coninue to wait");
                        waitedHalf = false;
                        continue;
                    }
                } catch (RemoteException e) {
                }
            }

            // Only kill the process if the debugger is not attached.
            if (Debug.isDebuggerConnected()) {
                debuggerWasConnected = 2;
            }
            if (debuggerWasConnected >= 2) {
                Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
            } else if (debuggerWasConnected > 0) {
                Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
            } else if (!allowRestart) {
                Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
            } else {
                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
                WatchdogDiagnostics.diagnoseCheckers(blockedCheckers);
                Slog.w(TAG, "*** GOODBYE!");
                Process.killProcess(Process.myPid());
                System.exit(10);
            }

            waitedHalf = false;
        }
    }

 

2.4.1 scheduleCheckLocked

	public void scheduleCheckLocked() {
		//第一次调用的时候,清空mMonitorQueue,并且把mMonitorQueue里面的实例添加到mMonitors。其实mMonitorQueue每次添加的时候就只有一个。
            if (mCompleted) {
                // Safe to update monitors in queue, Handler is not in the middle of work
                mMonitors.addAll(mMonitorQueue);
                mMonitorQueue.clear();
            }
			
			//如果monitoers 是空的话或者//当目标looper正在轮询状态则返回
            if ((mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling())
                    || (mPauseCount > 0)) {
                // Don't schedule until after resume OR
                // If the target looper has recently been polling, then
                // there is no reason to enqueue our checker on it since that
                // is as good as it not being deadlocked.  This avoid having
                // to do a context switch to check the thread. Note that we
                // only do this if we have no monitors since those would need to
                // be executed at this point.
                mCompleted = true;
                return;
            }
            if (!mCompleted) {//如果之前已经检查过了,就不必要重新再设置时间,发生消息
                // we already have a check in flight, so no need
                return;
            }

            mCompleted = false;
            mCurrentMonitor = null;
            mStartTime = SystemClock.uptimeMillis();//创建监听开始的时间。
			//发生消息,是把自身加入消息列队中。mHandler的值有:FgThread.getHandler() ,UiThread.getHandler(),IoThread.getHandler(),
			//所以一旦这些handler 执行的任务超时或者本身线程卡顿都是有可能产生SWT。所以在执行describeBlockedStateLocked打印信息的时候引入一个mCurrentMonitor
			//来作为区分。mCurrentMonitor的逻辑看run方法就比较清晰。大体的意思就是,如果handler执行到run方法,那么mCurrentMonitor不为空,而此时发生了watchdog 的Error。
			//那就是执行monitor卡顿,而这个monitor我们需要监听服务(比如AMS PMS等)内部方法。mCurrentMonitor==null 那么就是说明handler线程还没有执行run方法时就发生了SWT。
            mHandler.postAtFrontOfQueue(this); 
        }

  2.4.2 describeBlockedStateLocked

 String describeBlockedStateLocked() {
            if (mCurrentMonitor == null) {
                return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";
            } else {
                return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
                        + " on " + mName + " (" + getThread().getName() + ")";
            }
        }

2.4.3 run

  public void run() {
            // Once we get here, we ensure that mMonitors does not change even if we call
            // #addMonitorLocked because we first add the new monitors to mMonitorQueue and
            // move them to mMonitors on the next schedule when mCompleted is true, at which
            // point we have completed execution of this method.
            final int size = mMonitors.size();
            for (int i = 0 ; i < size ; i++) {
                synchronized (Watchdog.this) {//保证线程的同步问题,并且只要执行的服务卡顿了,后续代码就无法执行。
                    mCurrentMonitor = mMonitors.get(i);
                }
                mCurrentMonitor.monitor();//调用添加的服务自身的方法,比如我们之前介绍的binder 的 blockUntilThreadAvailable
            }

            synchronized (Watchdog.this) {
                mCompleted = true;
                mCurrentMonitor = null;//这个置空的目的是在执行describeBlockedStateLocked打印的时候能比较清晰的知道,到底是哪个地方卡住了,是执行的handler线程还是服务。
            }
        }

  2.4.4 evaluateCheckerCompletionLocked

  private int evaluateCheckerCompletionLocked() {
        int state = COMPLETED;
        for (int i=0; i<mHandlerCheckers.size(); i++) {
            HandlerChecker hc = mHandlerCheckers.get(i);
            state = Math.max(state, hc.getCompletionStateLocked());
        }
        return state;
    }

    private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
        ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
        for (int i=0; i<mHandlerCheckers.size(); i++) {
            HandlerChecker hc = mHandlerCheckers.get(i);
            if (hc.isOverdueLocked()) {
                checkers.add(hc);
            }
        }
        return checkers;
    }

到这里整个Watchdog的工作原理就讲解完了。

  总结一下:1. 启动所有的 HandlerChecker.scheduleCheckLocked(), 获取Watchdog 监听开始的时间:mStartTime = SystemClock.uptimeMillis,这个开始时间很重要,是否发生了Watchdog的错误就是以这个时间作为标准。 mHandler.postAtFrontOfQueue(this) 会把自身添加的handler 列队中等待执行。在这个等待执行的过程中有可能会超时,所以在describeBlockedStateLocked的打印信息中有做区分。最后就会执行mCurrentMonitor.monitor()。这个方法就为了检查添加的服务是否卡顿的。这就是Watchdog运行的核心逻辑。

                    2.evaluateCheckerCompletionLocked获取所有的HandlerChecker.getCompletionStateLocked的状态,而状态的依据是SystemClock.uptimeMillis() > mStartTime + mWaitMax 。也就是差值跟30s比较,

                    COMPLETED = 0:等待完成;
                    WAITING = 1:等待时间小于DEFAULT_TIMEOUT的一半,即30s;
                    WAITED_HALF = 2:等待时间处于30s~60s之间;
                    OVERDUE = 3:等待时间大于或等于60s。

                如果waitState=WAITED_HALF,就会打印一次track信息 ActivityManagerService.dumpStackTraces(pids, null, null, getInterestingNativePids(), null);

               如果waitState=OVERDUE     EventLog.writeEvent(EventLogTags.WATCHDOG, subject)和ActivityManagerService.dumpStackTraces。并且还会把相关的log输出到kernel log中doSysRq('w'),doSysRq('l');以及 mActivity.addErrorToDropBox

            3.如果有设置重启标识符allowRestart 就会重启  Process.killProcess(Process.myPid());System.exit(10);,并且推出进程。

    所以Watchdog的工作原理我们就介绍完成了

 

 

三、发生了Watchdog后系统会做什么?有哪些关键的打印信息

    1.如果是超时30s,会有一个track打印。 ActivityManagerService.dumpStackTraces,主要是一些堆 栈的信息,会被输出到data/anr/traces.txt

 private static synchronized File createAnrDumpFile(File tracesDir) throws IOException {
4019          if (sAnrFileDateFormat == null) {
4020              sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
4021          }
4022  
4023          final String formattedDate = sAnrFileDateFormat.format(new Date());
4024          final File anrFile = new File(tracesDir, ANR_FILE_PREFIX + formattedDate);
4025  
4026          if (anrFile.createNewFile()) {
4027              FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
4028              return anrFile;
4029          } else {
4030              throw new IOException("Unable to create ANR dump file: createNewFile failed");
4031          }
4032      }

        2.如果是超过 60s , 会再一次 ActivityManagerService.dumpStackTraces,以及 EventLog.writeEvent。还会触发kernel的信息打印 doSysRq('w'); doSysRq('l');         
            

 private void doSysRq(char c) {
723          try {
724              FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
725              sysrq_trigger.write(c);
726              sysrq_trigger.close();
727          } catch (IOException e) {
728              Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
729          }
730      }

  mActivity.addErrorToDropBox和  FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED,subject); 

   if (debuggerWasConnected >= 2) {
                Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
            } else if (debuggerWasConnected > 0) {
                Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
            } else if (!allowRestart) {
                Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
            } else {
                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
                WatchdogDiagnostics.diagnoseCheckers(blockedCheckers);
                Slog.w(TAG, "*** GOODBYE!");
                Process.killProcess(Process.myPid());
                System.exit(10);
            }

发生了Watchdog是否重启依据allowRestart,这个值是由

 public void setAllowRestart(boolean allowRestart) {
        synchronized (this) {
            mAllowRestart = allowRestart;
        }
    }

而这个方法的调用是由AMS调用的。

 

 public void hang(final IBinder who, boolean allowRestart) {
9292          if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9293                  != PackageManager.PERMISSION_GRANTED) {
9294              throw new SecurityException("Requires permission "
9295                      + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9296          }
9297  
9298          final IBinder.DeathRecipient death = new DeathRecipient() {
9299              @Override
9300              public void binderDied() {
9301                  synchronized (this) {
9302                      notifyAll();
9303                  }
9304              }
9305          };
9306  
9307          try {
9308              who.linkToDeath(death, 0);
9309          } catch (RemoteException e) {
9310              Slog.w(TAG, "hang: given caller IBinder is already dead.");
9311              return;
9312          }
9313  
9314          synchronized (this) {
9315              Watchdog.getInstance().setAllowRestart(allowRestart);
9316              Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9317              synchronized (death) {
9318                  while (who.isBinderAlive()) {
9319                      try {
9320                          death.wait();
9321                      } catch (InterruptedException e) {
9322                      }
9323                  }
9324              }
9325              Watchdog.getInstance().setAllowRestart(true);
9326          }
9327      }

binder进程死掉就会触发

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 阅读前的准备工作 1.1 系统架构 1.1.1 Android系统架构 1.1.2 本书的架构 1.2 搭建开发环境 1.2.1 下载源码 1.2.2 编译源码 1.3 工具介绍 1.3.1 Source Insight介绍 1.3.3 Busybox的使用 1.4 本章小结 第2章 深入理解JNI 2.1 JNI概述 2.2 学习JNI的实例:MediaScanner 2.3 Java层的MediaScanner分析 2.3.1 加载JNI库 2.3.2 Java的native函数和总结 2.4 JNI层MediaScanner的分析 2.4.1 注册JNI函数 2.4.2 数据类型转换 2.4.3 JNIEnv介绍 2.4.4 通过JNIEnv操作jobject 2.4.5 jstring介绍 2.4.6 JNI类型签名介绍 2.4.7 垃圾回收 2.4.8 JNI中的异常处理 2.5 本章小结 第3章 深入理解init 3.1 概述 3.2 init分析 3.2.1 解析配置文件 3.2.2 解析service 3.2.3 init控制service 3.2.4 属性服务 3.3 本章小结 第4章 深入理解zygote 4.1 概述 4.2 zygote分析 4.2.1 AppRuntime分析 4.2.2 Welcome to Java World 4.2.3 关于zygote的总结 4.3 SystemServer分析 4.3.1 SystemServer的诞生 4.3.2 SystemServer的重要使命 4.3.3 关于 SystemServer的总结 4.4 zygote的分裂 4.4.1 ActivityManagerService发送请求 4.4.2 有求必应之响应请求 4.4.3 关于zygote分裂的总结 4.5 拓展思考 4.5.1 虚拟机heapsize的限制 4.5.2 开机速度优化 4.5.3 Watchdog分析 4.6 本章小结 第5章 深入理解常见类 5.1 概述 5.2 以“三板斧”揭秘RefBase、sp和wp 5.2.1 第一板斧--初识影子对象 5.2.2 第二板斧--由弱生强 5.2.3 第三板斧--破解生死魔咒 5.2.4 轻量级的引用计数控制类LightRefBase 5.2.5 题外话-三板斧的来历 5.3 Thread类及常用同步类分析 5.3.1 一个变量引发的思考 5.3.2 常用同步类 5.4 Looper和Handler类分析 5.4.1 Looper类分析 5.4.2 Handler分析 5.4.3 Looper和Handler的同步关系 5.4.4 HandlerThread介绍 5.5 本章小结 第6章 深入理解Binder 6.1 概述 6.2 庖丁解MediaServer 6.2.1 MediaServer的入口函数 6.2.2 独一无二的ProcessState 6.2.3 时空穿越魔术-defaultServiceManager 6.2.4 注册MediaPlayerService 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析 6.2.6 你彻底明白了吗 6.3 服务总管ServiceManager 6.3.1 ServiceManager的原理 6.3.2 服务的注册 6.3.3 ServiceManager存在的意义 6.4 MediaPlayerService和它的Client 6.4.1 查询ServiceManager 6.4.2 子承父业 6.5 拓展思考 6.5.1 Binder和线程的关系 6.5.2 有人情味的讣告 6.5.3 匿名Service 6.6 学以致用 6.6.1 纯Native的Service 6.6.2 扶得起的“阿斗”(aidl) 6.7 本章小结 第7章 深入理解Audio系统 7.1 概述 7.2 AudioTrack的破解 7.2.1 用例介绍 7.2.2 AudioTrack(Java空间)分析 7.2.3 AudioTrack(Native空间)分析 7.2.4 关于AudioTrack的总结 7.3 AudioFlinger的破解 7.3.1 AudioFlinger的诞生 7.3.2 通过流程分析AudioFlinger 7.3.3 audio_track_cblk_t分析 7.3.4 关于AudioFlinger的总结 7.4 AudioPolicyService的破解 7.4.1 AudioPolicyService的创建 7.4.2 重回AudioTrack 7.4.3 声音路由切换实例分析 7.4.4 关于AudioPol
深入理解Android 卷1 不是扫描版的,是全版电子书的,非PDF,可编辑,各种阅览器以打开!包括书签和同步目录! 第1章 阅读前的准备工作 / 1 1.1 系统架构 / 2 1.1.1 Android系统架构 / 2 1.1.2 本书的架构 / 3 1.2 搭建开发环境 / 4 1.2.1 下载源码 / 4 1.2.2 编译源码 / 6 1.3 工具介绍 / 8 1.3.1 Source Insight介绍 / 8 1.3.3 Busybox的使用 / 11 1.4 本章小结 / 12 第2章 深入理解JNI / 13 2.1 JNI概述 / 14 2.2 学习JNI的实例:MediaScanner / 15 2.3 Java层的MediaScanner分析 / 16 2.3.1 加载JNI库 / 16 2.3.2 Java的native函数和总结 / 17 2.4 JNI层MediaScanner的分析 / 17 2.4.1 注册JNI函数 / 18 2.4.2 数据类型转换 / 22 2.4.3 JNIEnv介绍 / 24 2.4.4 通过JNIEnv操作jobject / 25 2.4.5 jstring介绍 / 27 2.4.6 JNI类型签名介绍 / 28 2.4.7 垃圾回收 / 29 2.4.8 JNI中的异常处理 / 32 2.5 本章小结 / 32 第3章 深入理解init / 33 3.1 概述 / 34 3.2 init分析 / 34 3.2.1 解析配置文件 / 38 3.2.2 解析service / 42 3.2.3 init控制service / 48 3.2.4 属性服务 / 52 3.3 本章小结 / 60 第4章 深入理解zygote / 61 4.1 概述 / 62 4.2 zygote分析 / 62 4.2.1 AppRuntime分析 / 63 4.2.2 Welcome to Java World / 68 4.2.3 关于zygote的总结 / 74 4.3 SystemServer分析 / 74 4.3.1 SystemServer的诞生 / 74 4.3.2 SystemServer的重要使命 / 77 4.3.3 关于 SystemServer的总结 / 83 4.4 zygote的分裂 / 84 4.4.1 ActivityManagerService发送请求 / 84 4.4.2 有求必应之响应请求 / 86 4.4.3 关于zygote分裂的总结 / 88 4.5 拓展思考 / 88 4.5.1 虚拟机heapsize的限制 / 88 4.5.2 开机速度优化 / 89 4.5.3 Watchdog分析 / 90 4.6 本章小结 / 93 第5章 深入理解常见类 / 95 5.1 概述 / 96 5.2 以“三板斧”揭秘RefBase、sp和wp / 96 5.2.1 第一板斧——初识影子对象 / 96 5.2.2 第二板斧——由弱生强 / 103 5.2.3 第三板斧——破解生死魔咒 / 106 5.2.4 轻量级的引用计数控制类LightRefBase / 108 5.2.5 题外话-三板斧的来历 / 109 5.3 Thread类及常用同步类分析 / 109 5.3.1 一个变量引发的思考 / 109 5.3.2 常用同步类 / 114 5.4 Looper和Handler类分析 / 121 5.4.1 Looper类分析 / 122 5.4.2 Handler分析 / 124 5.4.3 Looper和Handler的同步关系 / 127 5.4.4 HandlerThread介绍 / 129 5.5 本章小结 / 129 第6章 深入理解Binder / 130 6.1 概述 / 131 6.2 庖丁解MediaServer / 132 6.2.1 MediaServer的入口函数 / 132 6.2.2 独一无二的ProcessState / 133 6.2.3 时空穿越魔术-defaultServiceManager / 134 6.2.4 注册MediaPlayerService / 142 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析 / 149 6.2.6 你彻底明白了吗 / 152 6.3 服务总管ServiceManager / 152 6.3.1 ServiceManager的原理 / 152 6.3.2 服务的注册 / 155 6.3.3 ServiceManager存在的意义 / 158 6.4 MediaPlayerService和它的Client / 158 6.4.1 查询ServiceManager / 158 6.4.2 子承父业 / 159 6.5 拓展思考 / 162 6.5.1 Binder和线程的关系 / 162 6.5.2 有人情味的讣告 / 163 6.5.3 匿名Service / 165 6.6 学以致用 / 166 6.6.1 纯Native的Service / 166 6.6.2 扶得起的“阿斗”(aidl) / 169 6.7 本章小结 / 172 第7章 深入理解Audio系统 / 173 7.1 概述 / 174 7.2 AudioTrack的破解 / 174 7.2.1 用例介绍 / 174 7.2.2 AudioTrack(Java空间)分析 / 179 7.2.3 AudioTrack(Native空间)分析 / 188 7.2.4 关于AudioTrack的总结 / 200 7.3 AudioFlinger的破解 / 200 7.3.1 AudioFlinger的诞生 / 200 7.3.2 通过流程分析AudioFlinger / 204 7.3.3 audio_track_cblk_t分析 / 230 7.3.4 关于AudioFlinger的总结 / 234 7.4 AudioPolicyService的破解 / 234 7.4.1 AudioPolicyService的创建 / 235 7.4.2 重回AudioTrack / 245 7.4.3 声音路由切换实例分析 / 251 7.4.4 关于AudioPolicy的总结 / 262 7.5 拓展思考 / 262 7.5.1 DuplicatingThread破解 / 262 7.5.2 题外话 / 270 7.6 本章小结 / 272 第8章 深入理解Surface系统 / 273 8.1 概述 / 275 8.2 一个Activity的显示 / 275 8.2.1 Activity的创建 / 275 8.2.2 Activity的UI绘制 / 294 8.2.3 关于Activity的总结 / 296 8.3 初识Surface / 297 8.3.1 和Surface有关的流程总结 / 297 8.3.2 Surface之乾坤大挪移 / 298 8.3.3 乾坤大挪移的JNI层分析 / 303 8.3.4 Surface和画图 / 307 8.3.5 初识Surface小结 / 309 8.4 深入分析Surface / 310 8.4.1 与Surface相关的基础知识介绍 / 310 8.4.2 SurfaceComposerClient分析 / 315 8.4.3 SurfaceControl分析 / 320 8.4.4 writeToParcel和Surface对象的创建 / 331 8.4.5 lockCanvas和unlockCanvasAndPost分析 / 335 8.4.6 GraphicBuffer介绍 / 344 8.4.7 深入分析Surface的总结 / 353 8.5 SurfaceFlinger分析 / 353 8.5.1 SurfaceFlinger的诞生 / 354 8.5.2 SF工作线程分析 / 359 8.5.3 Transaction分析 / 368 8.5.4 关于SurfaceFlinger的总结 / 376 8.6 拓展思考 / 377 8.6.1 Surface系统的CB对象分析 / 377 8.6.2 ViewRoot的你问我答 / 384 8.6.3 LayerBuffer分析 / 385 8.7 本章小结 / 394 第9章 深入理解Vold和Rild / 395 9.1 概述 / 396 9.2 Vold的原理与机制分析 / 396 9.2.1 Netlink和Uevent介绍 / 397 9.2.2 初识Vold / 399 9.2.3 NetlinkManager模块分析 / 400 9.2.4 VolumeManager模块分析 / 408 9.2.5 CommandListener模块分析 / 414 9.2.6 Vold实例分析 / 417 9.2.7 关于Vold的总结 / 428 9.3 Rild的原理与机制分析 / 428 9.3.1 初识Rild / 430 9.3.2 RIL_startEventLoop分析 / 432 9.3.3 RIL_Init分析 / 437 9.3.4 RIL_register分析 / 444 9.3.5 关于Rild main函数的总结 / 447 9.3.6 Rild实例分析 / 447 9.3.7 关于Rild的总结 / 459 9.4 拓展思考 / 459 9.4.1 嵌入式系统的存储知识介绍 / 459 9.4.2 Rild和Phone的改进探讨 / 462 9.5 本章小结 / 463 第10章 深入理解MediaScanner / 464 10.1 概述 / 465 10.2 android.process.media分析 / 465 10.2.1 MSR模块分析 / 466 10.2.2 MSS模块分析 / 467 10.2.3 android.process.media媒体扫描工作的流程总结 / 471 10.3 MediaScanner分析 / 472 10.3.1 Java层分析 / 472 10.3.2 JNI层分析 / 476 10.3.3 PVMediaScanner分析 / 479 10.3.4 关于MediaScanner的总结 / 485 10.4 拓展思考 / 486 10.4.1 MediaScannerConnection介绍 / 486 10.4.2 我问你答 / 487 10.5 本章小结 / 488
深入理解Android:卷2》是一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际应用开发需求,书中所涵盖的知识点都是Android应用开发者和系统开发者需要重点掌握的。 全书共10章,第1章介绍了阅读本书所需要做的准备工作,主要包括对Android系统架构和源码阅读方法的介绍;第2章通过对Android系统中的MediaScanner进行分析,详细讲解了Android中十分重要的JNI技术;第3章分析了init进程,揭示了通过解析init.rc来启动Zygote以及属性服务的工作原理;第4章分析了Z ygote、SystemServer等进程的工作机制,同时还讨论了Android的启动速度、虚拟机HeapSize的大小调整、Watchdog工作原理等问题;第5章讲解了Android系统中常用的类,包括sp、wp、RefBase、Thread等类,同步类,以及Java中的Handler类和Looper类,掌握这些类的知识后方能在后续的代码分析中做到游刃有余;第6章以MediaServer为切入点,对Android中极为重要的Binder进行了较为全面的分析,深刻揭示了其本质。第7章对Audio系统进行了深入的分析,尤其是AudioTrack、AudioFlinger和AudioPolicyService等的工作原理。第8章深入讲解了Surface系统的实现原理,分析了Surface与Activity之间以及Surface与SurfaceFlinger之间的关系、SurfaceFlinger的工作原理、Surface系统中的帧数据传输以及LayerBuffer的工作流程。第9章对Vold和Rild的原理和机制进行了深入的分析,同时还探讨了Phone设计优化的问题;

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值