当前位置: 首页 > wzjs >正文

企业在网站建设中需要做什么杭州设计公司老总

企业在网站建设中需要做什么,杭州设计公司老总,接app推广,成都plc培训机构哪家最好目录 一,SystemServer整体框架 二,SystemServer启动源码分析 2.1,重要的概念 2.2,启动入口 2.3,创建对应进程的binder 三,binder驱动和binder线程池 四,SystemServer真正启动方法 4.1 SystemServer main方法里面主要做了几件事情 1)创建SystemServiceManager管理所有的…

目录

一,SystemServer整体框架

二,SystemServer启动源码分析

2.1,重要的概念

2.2,启动入口

2.3,创建对应进程的binder

三,binder驱动和binder线程池

四,SystemServer真正启动方法

4.1 SystemServer main方法里面主要做了几件事情

1)创建SystemServiceManager管理所有的服务

2)创建上下文createSystemContext,

3)启动核心服务和其他服务

4)Looper.prepareMainLooper()

5)Looper.loop()

4.2 分析startBootstrapServices

4.3 分析startBootstrapServices

4.4 分析startBootstrapServices

五,结束语


一,SystemServer整体框架

1.1,SystemServer类图

1.1,SystemServer时序图

二,SystemServer启动源码分析

2.1,重要的概念

在开始讲解源码之前,需要搞清楚几个重要的概念

对象含义备注
SystemServerSystemServer是一个进程,这个进程是Android系统中的核心进程,该进程由zygote进程在开机时fork而出,管理了系统的核心服务,整个安卓系统只有一个SystemServer进程

属于进程级别

是一个单独的进程

SystemServiceManagerSystemServiceManager是为了管理SystemServer进程里面运行的90+多个服务(Services)设置的一个管理者角色,这个仅仅用于同一个进程之间使用普通的java对象
LocalServicesLocalServices是Android系统中用于在同一进程中注册和获取LocalService的工具类。它维护了一个ArrayMap来存储不同类型的LocalService实例,确保每个类型只对应一个实例。通过addService()方法注册服务,getService()方法获取服务。这些服务不是Binder对象仅限于同一进程内通信,类似于ServiceManager但更私有化,和ServiceManager最本质的区别是ServiceManager管理的服务都是binder服务,这些服务都是可以在不同进程之间跑的对象

管理的是普通的服务,只能在同一个进程之间使用的服务,不具备进程之间通信能力的服务,各个系统service在启动的过程中都会调用LocalServices.addService()把自己的local service注册到LocalServices中,比如AMS,WMS,PMS
注册到LocalServices中的service不是Binder对象,只能在同一个进程中使用,除此之外它的的使用方式和ServiceManager相似。

普通的java对象

SystemServiceRegistry

Android应用层将系统服务注册相关的API放在了SystemServiceRegistry类中,因为android系统的代码特别庞大,为了给上层应用开发者提供可以很方便的获取到被SystemServer进程管理的所有服务,那么通过

SystemServiceRegistry可以方便获取

比如ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

最终是调用到ServiceManager获取对应服务的Ibinder对象

,普通的java对象

SystemService为了统一管理SystemServer进程运行的所有服务提供的一个统一接口对象普通的java对象
ServiceManagerServiceManager  android系统的服务守护进程,管理了整个android系统的所有Ibinder对象是一个单独的进程,和Zygote平级,都是由Init进程fork出来的

上面说了这么多,一图胜千言,下面看具体的

2.2,启动入口

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

的main方法里面

if (startSystemServer) {Runnable r = forkSystemServer(abiList, socketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run();return;}}

fork出来,之所以后面可以通过java反射的方式调用到SystemServer,是因为在fork之前传递的参数重明确的说明了对象com.android.server.SystemServer,通知指定了运行所在的进程是在--nice-name=system_server

private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {....................................................................................String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","com.android.server.SystemServer",};....................................................................................

最后通过反射的方法调用MethodAndArgsCaller对象以后调用到SystemServer的main方法

static class MethodAndArgsCaller implements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try {mMethod.invoke(null, new Object[] { mArgs });

2.3,创建对应进程的binder

上面只是完成了SystemServer的启动,但是此时SystemServer并不具备进程之间通信的能力,所以在SystemServer启之后,立刻打开binder,做进程映射,

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}

此时通过nativeZygoteInit调用到jni,frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}

最后调用到/Volumes/aosp/android-8.1.0_r52/frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();
}

/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver): mDriverName(String8(driver)), mDriverFD(open_driver(driver)), mVMStart(MAP_FAILED), mThreadCountLock(PTHREAD_MUTEX_INITIALIZER), mThreadCountDecrement(PTHREAD_COND_INITIALIZER), mExecutingThreadsCount(0), mMaxThreads(DEFAULT_MAX_BINDER_THREADS)............................
{if (mDriverFD >= 0) {
............................mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
...................................}}
............................v
}

可以看到这里其实就是做了三件事情

1)打开binder驱动,和binder通信,通过

status_t result = ioctl(fd, BINDER_VERSION, &vers);

2)mmap内存映射

mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

3)设置binder驱动最多可以创建的线程数,

result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);

#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
#define DEFAULT_MAX_BINDER_THREADS 15

所以通过这里可以看到binder之前通信的时候最大的传递数据大小是1M-8K(同步),异步场景下是减半,binder驱动最多可以创建的线程数是15个,不包含主线程,包含的话是16个,上面这部分牵扯到binder驱动源码的分析,后续会用单独的文章讲解,敬请期待

2.4 创建binder线程池

/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/ProcessState.cpp

 virtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();}

启动binder线程池 

void ProcessState::startThreadPool()
{AutoMutex _l(mLock);if (!mThreadPoolStarted) {mThreadPoolStarted = true;spawnPooledThread(true);}
}

设置binder线程名字:Binder:%d_%X", pid, s,通过这段代码可以看到binder线程的名字是从0递增

void ProcessState::spawnPooledThread(bool isMain)
{if (mThreadPoolStarted) {String8 name = makeBinderThreadName();ALOGV("Spawning new pooled thread, name=%s\n", name.string());sp<Thread> t = new PoolThread(isMain);t->run(name.string());}
}

可以看到 PoolThread本身就是一个线程,在创建进程的时候此时启动的线程就是主线程,也是唯一的一个主线程,ProcessState是Application在Framework Native层面的对象,代表一个进程


class PoolThread : public Thread
{
public:explicit PoolThread(bool isMain): mIsMain(isMain){}protected:virtual bool threadLoop(){IPCThreadState::self()->joinThreadPool(mIsMain);return false;}const bool mIsMain;
};

在ProcessState里面调用了run方法以后,最后调用到了/Volumes/aosp/android-8.1.0_r52/system/core/libutils/Threads.cpp的run----->_threadLoop

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{................................................bool res;if (mCanCallJava) {res = createThreadEtc(_threadLoop,this, name, priority, stack, &mThread);} else {res = androidCreateRawThreadEtc(_threadLoop,this, name, priority, stack, &mThread);}................................................return NO_ERROR;
}
int Thread::_threadLoop(void* user)
{----------------------------------------------------------------------do {bool result;if (first) {first = false;self->mStatus = self->readyToRun();result = (self->mStatus == NO_ERROR);if (result && !self->exitPending()) {----------------------------------------------------------------------result = self->threadLoop();}} else {result = self->threadLoop();}} while(strong != 0);return 0;
}

到这里以后会开始binder线程池,通过/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/IPCThreadState.cpp ,IPCThreadState.cpp代表一个IPC线程池管理

IPCThreadState* IPCThreadState::self()
{---------------------------------------------pthread_mutex_lock(&gTLSMutex);if (!gHaveTLS) {int key_create_value = pthread_key_create(&gTLS, threadDestructor);if (key_create_value != 0) {pthread_mutex_unlock(&gTLSMutex);---------------------------------------------return NULL;}gHaveTLS = true;}pthread_mutex_unlock(&gTLSMutex);goto restart;
}

到这里为止才开始创建了一个真正的线程pthread_key_create,目前这种场景下只是创建了一个线程,所以读者有时候觉得joinThreadPool线程池不太明白,其实joinThreadPool后续还会被binder驱动调用,创建更多的线程,所以这个方法的名字叫做线程池

对于isMain=true的情况下, command为BC_ENTER_LOOPER,代表的是Binder主线程,不会退出的线程;
对于isMain=false的情况下,command为BC_REGISTER_LOOPER,表示是由binder驱动创建的线程。

Binder系统中可分为3类binder线程:

Binder主线程:进程创建过程会调用startThreadPool()过程中再进入spawnPooledThread(true),来创建Binder主线程。编号从1开始,也就是意味着binder主线程名为binder_1,并且主线程是不会退出的。
Binder普通线程:是由Binder Driver来根据是否有空闲的binder线程来决定是否创建binder线程,回调spawnPooledThread(false) ,isMain=false,该线程名格式为binder_x。
Binder其他线程:其他线程是指并没有调用spawnPooledThread方法,而是直接调用IPC.joinThreadPool(),将当前线程直接加入binder线程队列。例如: mediaserver和servicemanager的主线程都是binder线程,但system_server的主线程并非binder线程

对于joinThreadPoo其实最主要做了三件事情

1)processPendingDerefs 清除队列的引用

2)getAndExecuteCommand,如果有下一条命令的话,执行下一条命令,没有的话在这里等待,只有主进程创建的主线程会一直在这里等待,非主线程出现timeout则线程退出

3)mOut.writeInt32(BC_EXIT_LOOPER);推出循环以后通知binde驱动

4)talkWithDriver 和binder驱动通信交互数据

void IPCThreadState::joinThreadPool(bool isMain)
{LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);status_t result;do {processPendingDerefs();// now get the next command to be processed, waiting if necessaryresult = getAndExecuteCommand();if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",mProcess->mDriverFD, result);abort();}// Let this thread exit the thread pool if it is no longer// needed and it is not the main process thread.if(result == TIMED_OUT && !isMain) {break;}} while (result != -ECONNREFUSED && result != -EBADF);LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",(void*)pthread_self(), getpid(), result);mOut.writeInt32(BC_EXIT_LOOPER);talkWithDriver(false);
}

这块需要结合binder驱动源码来讲解,参考下面

三,binder驱动和binder线程池

binder驱动源码android-msm-angler-3.10-oreo-r6/msm/drivers/staging/android/binder.c

四,SystemServer真正启动方法

4.1 SystemServer main方法里面主要做了几件事情

1)创建SystemServiceManager管理所有的服务

2)创建上下文createSystemContext,

这里可以看到会创建ActivityThread,因为systemserver是一个进程和app一样,都有自己的looper

,同时把自己也注入到ActivityThread,让ActivityThread持有自己的IBinder对象

mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// Prepare the thread pool for init tasks that can be parallelizedSystemServerInitThreadPool.get();

3)启动核心服务和其他服务

try {traceBeginAndSlog("StartServices");startBootstrapServices();startCoreServices();startOtherServices();SystemServerInitThreadPool.shutdown();

4)Looper.prepareMainLooper()

5)Looper.loop()

永远循环,这样子SystemServer进程才不会推出

4.2 分析startBootstrapServices

.....................................
Installer installer = mSystemServiceManager.startService(Installer.class);mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);mActivityManagerService.initPowerManagement();mSystemServiceManager.startService(LightsService.class);mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);.....................................

4.3 分析startBootstrapServices

mSystemServiceManager.startService(DropBoxManagerService.class);mSystemServiceManager.startService(BatteryService.class);mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);mFirstBoot = mPackageManagerService.isFirstBoot();mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();

AMS启动之后会通过mActivityManagerService.setSystemProcess();

添加到ServiceManager

public void setSystemProcess() {try {ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);ServiceManager.addService("meminfo", new MemBinder(this));ServiceManager.addService("gfxinfo", new GraphicsBinder(this));ServiceManager.addService("dbinfo", new DbBinder(this));if (MONITOR_CPU_USAGE) {ServiceManager.addService("cpuinfo", new CpuBinder(this));}ServiceManager.addService("permission", new PermissionController(this));ServiceManager.addService("processinfo", new ProcessInfoService(this));ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());updateLruProcessLocked(app, false, null);}} catch (PackageManager.NameNotFoundException e) {throw new RuntimeException("Unable to find android system package", e);}}

4.4 分析startBootstrapServices

  wm = WindowManagerService.main(context, inputManager,mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBoot, mOnlyCore, new PhoneWindowManager());ServiceManager.addService(Context.WINDOW_SERVICE, wm);ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

可以看到所有的Service在启动以后,都会添加到ServiceManager进程来管理,通过这里就可以看到ServiceManager是整个android系统的大管家

五,结束语

鉴于作者水平有限,文章之中难免有错误或者遗漏地方,欢迎大家批评指正,也欢迎大家讨论,积极评论哈,谢谢

http://www.dtcms.com/wzjs/597228.html

相关文章:

  • 宁波网站建设论坛织梦dedecms资讯文章类网站模板
  • 聊城网站建设设计开发公司网站建设项目实践报告
  • 网站管理后台登录地址运动服装商城网站建设
  • 信游天下网站建设网站建设合同的结构
  • 58同城合肥网站建设wordpress增加百度收录
  • 黑色企业网站惠州的企业网站建设
  • 网站建设概算淘宝做网站的公司
  • 怎么把网站封包做app信息门户网站建设
  • 江门网站建设企业wordpress 做ins
  • 电子商务网站建设课程总结ui设计灵感网站
  • 如何进行一个网站建设网站ui设计兼职
  • 大连商城网站制作网站维护和推广
  • 网站设计方案书ppt涿州市住房和城乡建设局网站
  • 建个企业网站一年需要多少钱品牌提升方案
  • vs和sql怎么做网站商标注册45类明细
  • 济南网站建设的费用百度域名值多少钱
  • 网站设计方案要怎么写下载官方大庆加油app软件
  • 做美术鉴赏网站的心得邢台兼职网站有哪些?
  • 国外个人网站模板上海优化网站方法
  • 自己建一个网站能过期吗wap是什么意思?
  • 昆明商城网站开发oa系统网站建设方案
  • 站长工具 seo综合查询能搜索附近人的软件
  • 广州市官网网站建设多少钱减肥网站开发目的
  • 网站公司用什么软件做网站wordpress 禁止头像
  • 云南网络公司网站织梦模板源码下载
  • 洛阳做网站公司在哪上海网网站建设
  • 如何建设红色旅游网站百度移动版
  • 服务器关闭 网站被k做网站建设怎么找客户
  • 成都微信网站建设多做网站让人来注册
  • 安徽网站关键字优化网站搜索排名