android系统从systemserver开始的launcher启动详细流程_第1页
android系统从systemserver开始的launcher启动详细流程_第2页
android系统从systemserver开始的launcher启动详细流程_第3页
android系统从systemserver开始的launcher启动详细流程_第4页
android系统从systemserver开始的launcher启动详细流程_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、android系统启动流程android系统启动流程 从systemserver开始的launcher 目录1 概述:22 systemserver工作内容分析32.1 SystemServer类简述42.2 ServerThread类简述43 ActivityManagerService工作内容分析63.1 ActivityManagerService之main73.1.1创建ActivityManagerService实例73.1.2 创建ActivityThread实例,获取全局Context83.1.3创建ActivityStackSupervisor实例103.1.4调用startR

2、unning103.2 ActivityManagerService之setSystemProcess113.3. ActivityManagerService之setWindowManager123.4 ActivityManagerService之systemready123.4.1 启动所有Persistent属性的APK133.4.2 启动launcher144 ActivityStackSupervisor启动launcher154.1首先回顾一下ActivityStackSupervisor实例的初始化154.2 进入ActivityStackSupervisor.resumeTo

3、pActivitiesLocked164.3 进入ActivityStack.resumeTopActivityLocked164.4 回到ActivityStackSupervisor.resumeHomeActivity。174.5 ActivityStackSupervisor.mProbeThread174.6 ActivityStackSupervisor.mProbeHandler184.7 回到ActivityManagerService.startHomeActivityLocked184.8 ActivityStackSupervisor.startHomeActivity1

4、94.9 ActivityStackSupervisor.startActivityUncheckedLocked204.10 ActivityStack.startActivityLocked214.11 ActivityStackSupervisor.resumeTopActivitiesLocked224.12 ActivityStack.resumeTopActivityLocked224.13 ActivityStackSupervisor.startSpecificActivityLocked244.14 ActivityStackSupervisor.realStartActiv

5、ityLocked244.15 ActivityManagerService.startProcessLocked255 Process类管理创建activity进程275.1 Process.start:275.2Process.startViaZygote285.3 zygoteSendArgsAndGetResult和 openZygoteSocketIfNeeded286 ActivityThread线程类分析306.1 ActivityThread.main分析306.1.1创建了looper对象和本线程绑定。306.1.2创建了ActivityThread对象实例306.1.3进行

6、attach回调316.1.4 ActivityStackSupervisor.attachApplicationLocked346.1.5 ActivityStackSupervisor. ensureActivitiesVisibleLocked346.2 ApplicationThread内部类346.2.1 ActivityThread.ApplicationThread. scheduleLaunchActivity356.2.2 ActivityThread.ApplicationThread.scheduleResumeActivity376.2.3 发出开机完成通知387 总结

7、407.1 luancher启动流程总结407.2 luancher黑屏问题分析411 概述: android系统启动到zygote后,系统就真正进入java世界了;而zygote启动的第一个进程是systemserver.而用户看到的第一个程序是launcher. 本文要分析的正是从systemserver道launcher的启动流程.分析过程涉及到PowerManagerService,ActivityManagerService, PackageManagerService, DisplayManagerService, WindowManagerService , InputManag

8、erService ,ServiceManager等一系列相关知识,必要的地方会做一些简单分析。这些service的详细分析,在另外的笔记中再做阐述。流程图:黑线:途径1;蓝线:途径2;红线:途径3; 部分流程重叠。systemserver:ServerThread.initAndLoopPersistent属性apk启动:getPersistentApplicationsActivityManagerService:1)attachApplication2)startProcessLocked3)startHomeActivityLocked4)systemreadyActivityStac

9、kSupervisor:1)realStartActivityLocked2)startSpecificActivityLocked3)attachApplicationLocked4)startHomeActivity5)resumeHomeActivity mProbeThread mProbeHandler6)resumeTopActivitiesLockedActivityStack:resumeTopActivityLockedtopRunningActivity=NULL?activity resumed?activity进程已启动Process:startstartViaZygo

10、teActivityThread:mainattachzygoteinit(zygotesocket):runSelectLoop显示launcher:1)WindowManagerServicesetAppVisibility2) ActivityThread . ApplicationThreadscheduleResumeActivityscheduleResumeActivity设置Activity resumedYNYdo nothingreturnNYN2 systemserver工作内容分析源代码路径: frameworksbaseservicesjavacomandroidse

11、rverSystemServer.javasystemserver最主要的作用: 1)就是初始化framework层各种service和其对应的特定servicemanager,并将他们注册到全局servicemanager类,以便其他地方只需要通过servicemanager.getService(String servicename)就可以取得该service的实例。 2)调用各service的systemready接口,启动service。这些service基本都是单例类,所以这种注册也是方便全局调用。下面分析其代码流程2.1 SystemServer类简述这里启动了ServerThre

12、ad类,并调用其initAndLoop函数。2.2 ServerThread类简述源代码路径: frameworksbaseservicesjavacomandroidserverSystemServer.java进入同样在SystemServer.java下的ServerThread类:可见systemsever的工作基本都是在ServerThread内完成的.其中我们所需要关注的是ActivityManagerService,正是这个类的启动,最终完成了launcher的启动;下面接着分析ActivityManagerService在ServerThread内的5个主要步骤。3 Activ

13、ityManagerService工作内容分析这个分析,对应其在ServerThread内的5个步骤,重点是其如何systemReady完成launcher的启动。从上面systemserver的分析可以看到,systemserver最后也调用了ActivityManagerService的systemReady,那么systemReady到底 是如何启动launcher的?源代码路径:frameworksbaseservicesjavacomandroidserveramActivityManagerService.java3.1 ActivityManagerService之main回顾下

14、ActivityManagerService在systemserver中的第一个动作:下面进入ActivityManagerService的main方法: ActivityManagerService的main方法完成以下几个事情:3.1.1创建ActivityManagerService实例 ActivityManagerService实例是通过AThread这个内部类创建的;这里我们看下AThread是如何创建这个实例的。 AThread是在其run方法中创建的ActivityManagerService实例,AThread. start被执行的时候,run方法就被调用,从而完成创建Act

15、ivityManagerService实例。ActivityManagerService在创建了实例后,self函数就直接返回该实例:3.1.2 创建ActivityThread实例,获取全局Context调用ActivityThread类的systemMain创建ActivityThread实例,再调用getSystemContext获得contextframeworksbasecorejavaandroidappActivityThread.java 这个context是ActivityThread下的全局context,所有的上下文都继承于此。扩展一:为什么这里要创建一个Activity

16、Thread线程? ActivityThread类故名思议是处理activity生命周期内的活动的线程,ActivityManagerService运行在systemserver进程内,为什么需要创建ActivityThread线程?实际上systemserver.java下有一个startSystemUi,这个函数本身启动一个service处理了很多系统级的临时弹出消息,这些有一部分也处理为activity,他们的运行同样需要ActivityThread;同时其他aitivity的一些善后的工作也需要ActivityManagerService来处理;所以这个systemserver进程就需

17、要 这么一个ActivityThread线程,换句话说,这个线程放在systemsever内创建也是可以的。ActivityManagerService实际需要的是ActivityThread下的全局conntext(即getSystemContext的结果).扩展二: ActivityThread类是如何工作的? 这个知识点较多,放到后面再分析.但是这里需要提前讲一下的是ActivityThread的基本原理和意义: ActivityThread是所有应用层activity启动时所创建的进程所启动的专门管理activity生命周期事务的线程;有一个activity运行 就有一个进程,就有一个

18、ActivityThread; ActivityThread有一个main方法,这是app层activity创建该线程的入口,最后通过attach方法进行回调,通知上层进程和线程都创建起来了(你可以显示了)。 而ActivityManagerService是通过systemMain来创建的线程,进程则不需要创建了,因位他本来就是zygote拉起的systemserver进程的一部分。 可见,本质上是一样的,只是ActivityManagerService和app层activity创建线程的入口不同,权限不同。 以上其实就是所谓的android运行时环境,把进程的处理放在后台,普通java程序员

19、根本不需要知道进程概念,只需要知道android环境就够了。3.1.3创建ActivityStackSupervisor实例记录到mStackSupervisor,ActivityStackSupervisor是启动launcher的直接起点,放到后面讲.3.1.4调用startRunning这里的systemReady(null)不会被执行. ,这里完成初始化的参数值得注意:mTopComponent:栈顶Component为空mTopAction:栈顶动作是: Intent.ACTION_MAINmTopData:栈顶activity数据为空3.2 ActivityManagerServi

20、ce之setSystemProcess回顾下ActivityManagerService在systemserver中的第二个动作:下面看下setSystemProcess的实现Context.ACTIVITY_SERVICE在frameworksbasecorejavaandroidcontentContext.java中的定义: 则其他地方可以通过ServiceManager.getService("activity"/*或Context.ACTIVITY_SERVICE*/)来使用ActivityManagerService的单例mSelf。另外framework-re

21、s.apk的包名是android,可以查看frameworksbasecoreres下的Android.mk和AndroidManifest.xml。3.3. ActivityManagerService之setWindowManager回顾下ActivityManagerService在systemserver中的第4个动作:(第三个动作是installSystemProviders,偏离主题太远,跳过)这样一来ActivityManagerService和ActivityStackSupervisor都得到了全局WindowManagerService的实例.3.4 ActivityMan

22、agerService之systemready回顾下ActivityManagerService在systemserver中的第5个动作: systemready方法在ActivityManagerService的main方法中调用startRunning的时候被调用了一次,但是并没有执行,所以真正执行systemready还是要按看这里。下面分析systemready的具体实现3.4.1 启动所有Persistent属性的APK进入frameworksbaseservicesjavacomandroidserverpmPackageManagerService.java:这个函数将遍历所有a

23、pk,具备Persistent属性,且当前不是安全模式启动,或者这个apk同时是system属性,就会被load加入list列表回到ActivityManagerService.java看下addAppLocked如何拉起这些apk的进程:3.4.2 启动launcher调用mStackSupervisor.resumeTopActivitiesLocked();真正开始启动luancher.注意如果luancher具备了persistent属性,则显然luancher的进程已经先于activity的调用被拉起来了。这里产生了一个问题: mStackSupervisor.resumeTopAc

24、tivitiesLocked()这个动作在拉起所有persistent属性的apk之后,如果luancher也具备这个属性,是不是意味着luancher的进程一定会先于后面这个动作先启动? 答案是不一定,这里先解答一下。启动进程的startProcessLocked是通过socket通讯去通知底层zygote进程创建子进程,而这个通知发出后,该函数就直接返回了,连执行结果都不需要等待,所以下面到底何时能创建这个子进程,要看子进程有多少,排在第几位,何时socket得到响应。所以不排除,真正启动luancher进程的动作比后面这个mStackSupervisor.resumeTopActivit

25、iesLocked要慢。4 ActivityStackSupervisor启动launcher相关源代码路径:frameworksbaseservicesjavacomandroidserveramActivityStackSupervisor.javaframeworksbaseservicesjavacomandroidserveram ActivityStack.java4.1首先回顾一下ActivityStackSupervisor实例的初始化1) ActivityStackSupervisor实例构造:systemserver调用ActivityManagerService的main

26、,后者在最后创建了ActivityStackSupervisor实例ActivityManagerService.mainActivityStackSupervisor的构造函数:这里ActivityStackSupervisor在构造时记录了ActivityManagerService创建的service实例,全局context,和looper.2) setWindowManager设置窗口管理systemserver自己创建了WindowManagerService实例:systemserver调用ActivityManagerService的setWindowManager,后者则内部调

27、用了ActivityStackSupervisor的setWindowManagerActivityManagerService. setWindowManager:ActivityStackSupervisor. setWindowManager:注意这里不仅仅是记录了这个全局的WindowManagerService,还创建了一个home属性的activity栈空间,mHomeStack,并加入到mStacks,但这里仅仅是mStacks这个ArrayList<ActivityStack>中加入了这个数据,仅此而已。4.2 进入ActivityStackSupervisor.r

28、esumeTopActivitiesLocked这里最终执行的是resumeTopActivitiesLocked(null, null, null);mStacks在setWindowManager的时候已经加入了mhomeStack,所以此时mStacks.size()为1,stack即为mHomeStack,进入分支stack.resumeTopActivityLocked(null);4.3 进入ActivityStack.resumeTopActivityLocked显然这时,topRunningActivityLocked一定返回null,程序回到mStackSupervisor.

29、resumeHomeActivity(prev);prev为NULL。注意: 这里的mStackSupervisor正是ActivityManagerService.main中初始化的 ActivityStackSupervisor,在ActivityStackSupervisor. setWindowManager 内部创建ActivityStack实例mHomeStack被创建的时候传进来4.4 回到ActivityStackSupervisor.resumeHomeActivity。mHomeStack这个空间被movetop,但是此时launcher的activity并没有运行,.to

30、pRunningActivityLocked(null);自然还是null,mIsHomeActivityStarted为false,程序进入mProbeThread.start();。注意: mProbeThread是final变量,性质是线程,定义时就初始化,但是并没有start,所以mProbeThread.isAlive()必为false,mProbeThread.getState() != Thread.State.TERMINATED为true。4.5 ActivityStackSupervisor.mProbeThread mProbeThread为ActivityStackSu

31、pervisor的内部类,run方法给handler发出START_HOME_MSG消息。4.6 ActivityStackSupervisor.mProbeHandlermProbeHandler为私有final成员变量。他的工作只有一个就是调用ActivityServiceManger的startHomeActivityLocked,执行这一步后mIsHomeActivityStarted变为true。特别注意:这一步是消息发送,可能存在调度问题而导致startHomeActivityLocked实际调用慢。前面已经分析过,ActivityStackSupervisor中的mService

32、就是ActivityManagerService。4.7 回到ActivityManagerService.startHomeActivityLocked 首先调用getHomeIntent构造一个intent为CATEGORY_HOME类型,然后通过resolveActivityInfo函数向PackageManagerService查询Category类型为HOME的Activity,此时aInfo即luancher的ActivityInfo。 通过getProcessRecordLocked,进一步查询该app的执行情况,如果查不到则表明进程都没启动,如果app进程查到了但是instru

33、mentationClass为空则表明activity未启动,此时调用mStackSupervisor.startHomeActivity(intent, aInfo);4.8 ActivityStackSupervisor.startHomeActivity传入startActivityLocked的参数只有intent和aInfo不为空,程序很容易判断进入 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);r正是根据intent和ainfo创建的ActivityRecord,直到这时

34、才有了实际的Activity准备启动,但是此时还没有加入到activityStack的栈顶。4.9 ActivityStackSupervisor.startActivityUncheckedLocked这个函数很长,仔细梳理并通过加打印,确认其会进入最后ActivityStack类的的startActivityLocked,而targetStack为之前创建的homestack。特别注意: doResume参数为true., newTask为true(因为启动方式为Intent.FLAG_ACTIVITY_NEW_TASK)4.10 ActivityStack.startActivityLo

35、cked1)直到这里,launcher的activity才真正加到到activitystack的栈顶。2)正常情况应该进入第二个分支的mWindowManager.addAppToken,并最后执行if (doResume) mStackSupervisor.resumeTopActivitiesLocked(); 注意:mWindowManager.addAppToken的调用将当前acitivity的apptoken加入到window管理里面去,后面才能把他显示出来。4.11 ActivityStackSupervisor.resumeTopActivitiesLocked 和前面一样,这

36、里传入的参数为空:程序再回到ActivityStack. resumeTopActivityLocked。4.12 ActivityStack.resumeTopActivityLocked程序走到这里,才终于走到了显示出launcher的边缘。下面的resumeTopActivityLocked需要仔细分析: 这个函数的层次:1)if (next = null) ,启动home: resumeHomeActivity2) 目标next已经是mResumedActivity,直接return3)目标next的app和app.thread都已经建立,直接进入显示,调用mWindowManager

37、.setAppVisibility(next.appToken, true)和next.app.thread.scheduleResumeActivity;否则调用mStackSupervisor.startSpecificActivityLocked(next, true, true)进入继续做其他处理.显然此时不会走1);如果能走2),一定是被别的地方已经调用了显示;那么正常启动应该走3)。对于层次3),做下分析: 如果不是persistent属性的launcher,显然从前面的分析看,一直走到这里也不会有人拉起他的进程;那么就是说正常情况下,普通不带persistent属性的launch

38、er应该 会走到调用startSpecificActivityLocked,跟踪也多是如此。 之所以说多是如此,是因为实际上系统上还有其他方法来保证launcher这个activity进程被尽快拉起,所以有时会走到“if (next.app != null && next.app.thread != null) ”这个分支下。问题:有没有可能走到层次2)上面去?假设有别的地方还调用了显示,何尝不会?4.13 ActivityStackSupervisor.startSpecificActivityLocked 此时,如果满足条件if (app != null &&

39、; app.thread != null),则会调用realStartActivityLocked。 而如果系统没有其他地方启动launcher的进程,显然就会进入mService.startProcessLocked(cessName, .applicationInfo, true, 0,"activity", ent.getComponent(), false, false, true);来自己拉起进程,那么这个时候,谁去显示?似乎都没人去显示launcher了?4.14 ActivityStackSupervisor.realStart

40、ActivityLocked函数里面: 调用mWindowManager.setAppVisibility(r.appToken, true);设置窗口可见; 调用app.thread.scheduleLaunchActivity启动LaunchActivity的绘制,即oncreate+onresume. 调用stack.minimalResumeActivityLocked(r);记录该app为resumed状态:走到这里,正常的launcher启动流程就讲完了,但却留下2个问题:问题1: 如果launcher不带persistemt属性,也没有别的地方会主动创建launcher的进程,那

41、么startSpecificActivityLocked会走入mService.startProcessLocked,而不是realStartActivityLocked,这种情况下谁来显示?问题2: 假设有别的地方调用了realStartActivityLocked,而这时apptoken没准备好,显然光scheduleLaunchActivity画好了ui还是显示不出来,但是这时却仍然执行了:r.state = ActivityState.RESUMED; 这个时候上面的ActivityStack.resumeTopActivityLocked就会走入层次2,什么都不做就直接return了

42、,导致launcher不显示。因此我们还有必要跟着mService.startProcessLocked这个分支再继续看看。4.15 ActivityManagerService.startProcessLocked回顾下startSpecificActivityLocked走mService.startProcessLocked的情况: 这段代码也可以看出,ProcessRecord app由startProcessLocked产生,并同时创建了一个app.thread,也就是说每创建一个进程就一定有一个thread线程,至少对于activity而言是这样。 (注意:ActivityMana

43、gerService.SystemReady里面在主动启动persistent属性的apk时,也是调用的该函数)。继续ActivityManagerService.startProcessLocked,继续进入重载的ActivityManagerService. startProcessLocked(只有3个参数)这里有3个信息值得关注:1) Process.start: 进程启动,Process是进程管理类,一直跟踪下去,会发现他最后和zygote进程启动的服务端socket进行了通讯,通知zygote分化出一个子进程来。2) android.app.ActivityThread Proce

44、ss.start的时候,传入的class名称是android.app.ActivityThread,这里就是之前说的activity的进程一定对应着一个后台activitythread进程的,activity的所有生命周期动作都是activitythread处理的,所以前面真正让activity显示的是app.thread的schedule名称的相关函数,后面再分析3)后面的打印信息 这里专门截取这个打印信息,是为了让大家看到这种打印数据组织方式,同时知道进程创建后,android系统一定有这么一个打印,我们在看log的时候就可以关注这个信息。 搜索log的时候也注意,直接搜索整句log,在代

45、码中是搜索不到的,因为很多地方都像上面被截断了,需要搜索单个字符串。5 Process类管理创建activity进程源代码路径:frameworksbasecorejavaandroidos Process.java5.1 Process.start:重点关注前4个参数,具体到我们追踪的luancher:第一个参数: processclass,android.app.ActivityThread第二个参数:nicename对应着进程名称launcher.第三个参数:uid,用户id第四个参数:gid:用户组id5.2 Process.startViaZygote5.3 zygoteSendAr

46、gsAndGetResult和 openZygoteSocketIfNeeded1)openZygoteSocketIfNeeded方法:完成了java层LocalSocket 的创建得到sZygoteSocket ,并继续完成和zygote进程的服务端zygote这个socket的连接,继续创建sZygoteSocket收发数据用的stream对象和buffer。2)zygoteSendArgsAndGetResult:利用sZygoteWriter发送创建进程需要的参数,包括进程名称nicename(即luancher),进程要启动的第一个class(android.app.Activit

47、yThread),uid和gid等3)底层响应参考android系统从init进程开始到systemserver启动详细流程.docx的6.3.4和6.3.5此时frameworksbasecorejavacomandroidinternalosZygoteInit.java下的ZygoteInit .runSelectLoop()接收到socket连接请求,继续接收参数列表,开始fork子进程,并最终执行该进程的入口函数;继续进入到frameworksbasecorejavacomandroidinternalosZygoteConnection.java的ZygoteConnection

48、.handleChildProc方法。在android系统从init进程开始到systemserver启动详细流程.docx的6.3.5节已经分析过,ZygoteConnection .handleChildProc执行的入口函数,是app层创建进程是传递的第一个参数所代表的class的main函数,所以这里就是android.app.ActivityThread的main函数。到此为止,luancher运行需要的子进程创建完毕,名称为launcher,第一个要执行的函数是android.app.ActivityThread的main。6 ActivityThread线程类分析源代码路径: f

49、rameworksbasecorejavaandroidappActivityThread.java6.1 ActivityThread.main分析ActivityThread这个线程是专门管理activity运行生命周期的各种动作的封装。当然他实际还包含了对systemserver这个进程创建管理线程的工作,之前分析过其入口是systemmain,而普通的activity的入口是main;这二者本质是一样的,只是处理的权限等属性不同。main做3个主要的任务,分析如下:6.1.1创建了looper对象和本线程绑定。 原来我们在activity或service或dialog中可以随便使用ha

50、ndler是这个线程在后台付出的努力。 关于handler,looper,messagequeue之间的关系可以百度或参考深入理解Android 卷1,比较简单,这里不讨论。6.1.2创建了ActivityThread对象实例注意,当new ActivityThread()的时候,其成员变量 final ApplicationThread mAppThread = new ApplicationThread();同时被创建。ApplicationThread是内部类,继承自ApplicationThreadNativeApplicationThreadNative继承自接口IApplicati

51、onThread这意味着mAppThread变量可以直接转换为IApplicationThread。6.1.3进行attach回调ActivityThread.attach注意,这里正是把mAppThread转换为IApplicationThread,再调用了mgr.attachApplication(mAppThread);。1) ActivityManagerNative. getDefault源代码路径frameworksbasecorejavaandroidappActivityManagerNative.java注意,这里有2个知识点:a) binder通讯最终调用到Activity

52、ManagerService.attachApplication gDefault中return的am是ActivityManagerProxy类,传入的参数b是一个binder客户端(从ServiceManager.getService("activity")可以知道他是ActivityManagerService的ibinder),该参数被赋值给mRemote变量。 这时ActivityThread.attach实际进入ActivityManagerProxy. attachApplicationtransact通讯会使得服务端ActivityManagerServic

53、e执行onTransact。而ActivityManagerService自己继承自ActivityManagerNative,也没有重载onTransact,所以这里会执行ActivityManagerNative.onTransact,进入到调用ActivityManagerService自己的attachApplication方法。b 模板类 gDefault方法返回是一个模板类Singleton:可以看到,这个模板类的作用就是将他的模板T统统搞成单例类,以保证ActivityManagerNative. getDefault即使被反复调用,都始终只有一个binder客户端。2)回到Ac

54、tivityManagerService. attachApplication继续看attachApplicationLocked这里有两件事要关注:第一:makeActive这个方法将当前thread记录到了ProcessRecord下,这就是我们之前说的ProcessRecord.thread的来源。第二:程序最终进入了mStackSupervisor.attachApplicationLocked,可见如果完全由调用lucnher的流程自己来拉起他的进程的话,最后转了一圈还是回到了mStackSupervisor。mStackSupervisor.attachApplicationLocked到底做了什么?6.1.4 ActivityStackSupervisor.attachApplicationLocked一目了然,这个时候会走到调用realStartActivityLocked,而这个函数在前面4.1.4分析过了,会调用ActivityThread.ApplicationThread.scheduleResumeActivity触发显示。6.1.5 ActivityStackSupervisor. ensureActivitiesVisib

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论