Android的ActivityManagerService(簡(jiǎn)稱AMS)的源碼分析

Android的ActivityManagerService(簡(jiǎn)稱AMS)的源碼分析

Android的PackageManagerService10.0源碼解讀(AndroidManifest.xml解析)

Android判斷Activity是否在AndroidManifest.xml里面注冊(cè)(源碼分析)

Android的ActivityManagerService(簡(jiǎn)稱AMS)的源碼分析

內(nèi)容太多,建議收藏

AMS簡(jiǎn)介

ActivityManagerService是Android系統(tǒng)中一個(gè)特別重要的系統(tǒng)服務(wù),也是我們上層APP打交道最多的系統(tǒng)服務(wù)之一。ActivityManagerService(以下簡(jiǎn)稱AMS) 主要負(fù)責(zé)四大組件的啟動(dòng)、切換、調(diào)度以及應(yīng)用進(jìn)程的管理和調(diào)度工作,所有的APP應(yīng)用都需要 與AMS打交道。
Activity Manager的組成主要分為以下幾個(gè)部分:

  1. 服務(wù)代理:由ActivityManagerProxy實(shí)現(xiàn),用于與Server端提供的系統(tǒng)服務(wù)進(jìn)行進(jìn)程間通信
  2. 服務(wù)中樞:ActivityManagerNative繼承自Binder并實(shí)現(xiàn)IActivityManager,它提供了服務(wù)接口和
    Binder接口的相互轉(zhuǎn)化功能,并在內(nèi)部存儲(chǔ)服務(wù)代理對(duì)像,并提供了getDefault方法返回服務(wù)代理
  3. .Client:由ActivityManager封裝一部分服務(wù)接口供Client調(diào)用。ActivityManager內(nèi)部通過調(diào)用ActivityManagerNative的getDefault方法,可以得到一個(gè)ActivityManagerProxy對(duì)像的引用,進(jìn)而通過該代理對(duì)像調(diào)用遠(yuǎn)程服務(wù)的方法
  4. Server:由ActivityManagerService實(shí)現(xiàn),提供Server端的系統(tǒng)服務(wù)

ActivityManagerService的啟動(dòng)過程

AMS是在SystemServer中被添加的, 所以先到SystemServer中查看初始化.

public static void main(String[] args) {
        new SystemServer().run();
    }
private void run(){
        ...
        // Initialize the system context.
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
        try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    
        ...
    }

在SystemServer中,在startBootstrapServices()中去啟動(dòng)了AMS

 private void startBootstrapServices() { ...
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        //啟動(dòng)了AMS
        mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer); traceEnd(); ...
        // Now that the power manager has been started, let the activity manager
        // initialize power management features.
        traceBeginAndSlog("InitPowerManagement");
        mActivityManagerService.initPowerManagement();
        traceEnd();
        // Set up the Application instance for the system process and get started.
        traceBeginAndSlog("SetSystemProcess");
        mActivityManagerService.setSystemProcess();
        traceEnd();
    }

AMS是通過SystemServiceManager.startService去啟動(dòng)的,參數(shù)是
ActivityManagerService.Lifecycle.class, 首先看看startService方法.

@SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            throw new RuntimeException("Failed to create service " + className
                    + ": service class not found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it", ex);
        }
        return startService(serviceClass);
    }
    @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
 public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

startService方法很簡(jiǎn)單,是通過傳進(jìn)來的class然后反射創(chuàng)建對(duì)應(yīng)的service服務(wù)。所以此處創(chuàng)建的是Lifecycle的實(shí)例, 然后通過startService啟動(dòng)了AMS服務(wù).
再去看看ActivityManagerService.Lifecycle這個(gè)類的構(gòu)造方法.

public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        @Override
        public void onBootPhase(int phase) {
            mService.mBootPhase = phase;
            if (phase == PHASE_SYSTEM_SERVICES_READY) {
                mService.mBatteryStatsService.systemServicesReady();
                mService.mServices.systemServicesReady();
            }
        }

        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }
AMS初始化做了很多操作,具體的可以去看看ActivityManagerService,

具體的有

  • mSystemThread = ActivityThread.currentActivityThread();//獲取當(dāng)前的 ActivityThread
  • mUiContext = mSystemThread.getSystemUiContext();//賦值mUiContext
  • 創(chuàng)建Handler線程,用來處理handler消息
  • mUiHandler = mInjector.getUiHandler(this);//處理ui相關(guān)msg的Handler
  • 管理AMS的一些常量,廠商定制系統(tǒng)就可能修改此處 mConstants = new ActivityManagerConstants(this, mHandler)
  • 初始化管理前臺(tái)、后臺(tái)廣播的隊(duì)列, 系統(tǒng)會(huì)優(yōu)先遍歷發(fā)送前臺(tái)廣播 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false);
  • 初始化管理Service的 ActiveServices對(duì)象 mServices = new ActiveServices(this);
  • mProviderMap = new ProviderMap(this);//初始化Provider的管理者
  • mAppErrors = new AppErrors(mUiContext, this);//初始化APP錯(cuò)誤日志的打印器
  • 創(chuàng)建電池統(tǒng)計(jì)服務(wù), 并輸出到指定目錄 File dataDir = Environment.getDataDirectory();
  • 創(chuàng)建進(jìn)程統(tǒng)計(jì)分析服務(wù),追蹤統(tǒng)計(jì)哪些進(jìn)程有濫用或不良行為 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
  • 加載Uri的授權(quán)文件 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri- grants");
  • 負(fù)責(zé)管理多用戶 mUserController = new UserController(this);
  • vr功能的控制器 mVrController = new VrController(this);
  • 初始化OpenGL版本號(hào)
  • 管理ActivityStack的重要類,這里面記錄著activity狀態(tài)信息,是AMS中的核心類 mStackSupervisor = createStackSupervisor();
  • //根據(jù)當(dāng)前可見的Activity類型,控制Keyguard遮擋,關(guān)閉和轉(zhuǎn)換。 Keyguard就是我們的鎖 屏相關(guān)頁面mKeyguardController = mStackSupervisor.getKeyguardController();
  • 管理APK的兼容性配置 解析/data/system/packages-compat.xml文件,該文件用于存儲(chǔ)那些需要考慮屏幕尺寸的APK信 息,mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
  • Intent防火墻,Google定義了一組規(guī)則,來過濾intent,如果觸發(fā)了,則intent會(huì)被系統(tǒng)丟 棄,且不會(huì)告知發(fā)送者 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
  • 這是activity啟動(dòng)的處理類,這里管理者activity啟動(dòng)中用到的intent信息和flag標(biāo)識(shí),也 和stack和task有重要的聯(lián)系 mActivityStartController = new ActivityStartController(this);
  • 啟動(dòng)一個(gè)線程專門跟進(jìn)cpu當(dāng)前狀態(tài)信息,AMS對(duì)當(dāng)前cpu狀態(tài)了如指掌,可以更加高效的安排其他工 作
  • 看門狗,監(jiān)聽進(jìn)程。這個(gè)類每分鐘調(diào)用一次監(jiān)視器。 如果進(jìn)程沒有任何返回就殺掉 Watchdog.getInstance().addMonitor(this)
  • 等待mProcessCpuThread完成初始化后, 釋放鎖,初始化期間禁止訪問 mProcessCpuInitLatch.await()
setSystemProcess()做的事情
  1. 注冊(cè)服務(wù):首先將ActivityManagerService注冊(cè)到ServiceManager中,其次將幾個(gè)與系統(tǒng)性能調(diào)試相關(guān)的服務(wù)注冊(cè)到ServiceManager
  2. 查詢并處理ApplicationInfo。首先調(diào)用PackageManagerService的接口,查詢包名為android的應(yīng)用程序的ApplicationInfo信息,對(duì)應(yīng)于framework-res.apk。然后以該信息為參數(shù)調(diào)用ActivityThread上的installSystemApplicationInfo方法。
  3. 創(chuàng)建并處理ProcessRecord。調(diào)用ActivityManagerService上的newProcessRecordLocked,創(chuàng)建一個(gè)ProcessRecord類型的對(duì)象,并保存該對(duì)象的信息

AMS是什么?

  1. 從java角度來看,ams就是一個(gè)java對(duì)象,實(shí)現(xiàn)了Ibinder接口,所以它是一個(gè)用于進(jìn)程之間通信的
    接口,這個(gè)對(duì)象初始化是在systemServer.java 的run()方法里面.
  2. AMS是一個(gè)服務(wù):
    ActivityManagerService從名字就可以看出,它是一個(gè)服務(wù),用來管理Activity,而且是一個(gè)系統(tǒng)服務(wù),就是包管理服務(wù),電池管理服務(wù),震動(dòng)管理服務(wù)等。
  3. AMS是一個(gè)Binder
    ams實(shí)現(xiàn)了Ibinder接口,所以它是一個(gè)Binder,這意味著他不但可以用于進(jìn)程間通信,還是一個(gè)
    線程,因?yàn)橐粋€(gè)Binder就是一個(gè)線程。

如果我們啟動(dòng)一個(gè)hello World安卓用于程序,里面不另外啟動(dòng)其他線程,這個(gè)里面最少要啟動(dòng)4個(gè)
線程.

  1. main線程,只是程序的主線程,也是日常用到的最多的線程,也叫UI線程,因?yàn)閍ndroid的組件
    是非線程安全的,所以只允許UI/MAIN線程來操作。
  2. GC線程,java有垃圾回收機(jī)制,每個(gè)java程序都有一個(gè)專門負(fù)責(zé)垃圾回收的線程,
  3. Binder1 就是我們的ApplicationThread,這個(gè)類實(shí)現(xiàn)了Ibinder接口,用于進(jìn)程之間通信,具體
    來說,就是我們程序和AMS通信的工具
  4. Binder2 就是我們的ViewRoot.W對(duì)象,他也是實(shí)現(xiàn)了IBinder接口,就是用于我們的應(yīng)用程序和
    wms通信的工具。

wms就是WindowManagerServicer ,和ams差不多的概念,不過他是管理窗口的系統(tǒng)服務(wù)。

public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {}

AMS相關(guān)重要類介紹

ProcessRecord 數(shù)據(jù)結(jié)構(gòu)
第一類數(shù)據(jù):描述身份的數(shù)據(jù)
  • ApplicationInfo info:AndroidManifest.xml中定義的Application信息
  • boolean isolated:是不是isolated進(jìn)程
  • int uid:進(jìn)程uid
  • int userId:這個(gè)是android做的多用戶系統(tǒng)id,就像windows可以登錄很多用戶一樣,android
    也希望可以實(shí)現(xiàn)類似的多用戶
  • String processName:進(jìn)程名字,默認(rèn)情況下是包名
  • IApplicationThread thread:這個(gè)很重要,它是ApplicationThread的客戶端,AMS就是通過這
    個(gè)對(duì)象給apk進(jìn)程發(fā)送異步消息的(管理四大組件的消息),所以只有這個(gè)對(duì)象不為空的情況下,
    才代表apk進(jìn)程可是使用了
  • int pid:進(jìn)程的pid
第二類數(shù)據(jù):描述進(jìn)程中組件的數(shù)據(jù)
  • pkgList:進(jìn)程中運(yùn)行的包
  • ArraySet pkgDeps:進(jìn)程運(yùn)行依賴的包
  • ArrayList activities:進(jìn)程啟動(dòng)的所有的activity組件記錄表
  • ArraySet services:進(jìn)程啟動(dòng)的所有的service組件記錄表
  • ArraySet receivers:廣播接收器的記錄表
  • ArrayList conProviders:使用ContentProvider的客戶端記錄表
  • 10.BroadcastRecord curReceiver:當(dāng)前進(jìn)程正在執(zhí)行的廣播
第三類數(shù)據(jù):描述進(jìn)程狀態(tài)的數(shù)據(jù)
  • int maxAdj:進(jìn)程的adj上限(adjustment)
  • int curRawAdj:當(dāng)前正在計(jì)算的adj,這個(gè)值有可能大于maxAdj
  • int setRawAdj:上次計(jì)算的curRawAdj設(shè)置到lowmemorykiller系統(tǒng)后的adj
  • int curAdj:當(dāng)前正在計(jì)算的adj,這是curRawAdj被maxAdj削平的值
  • int pssProcState:pss進(jìn)程狀態(tài)
第四類數(shù)據(jù):和pss相關(guān)的數(shù)據(jù)

VSS- Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫占用的內(nèi)存) RSS- Resident Set Size 實(shí)際使用物理內(nèi)存(包含共享庫占用的內(nèi)存) PSS- Proportional Set Size 實(shí)際使用的物理內(nèi)存(比例分配共享庫占用的內(nèi)存) USS- Unique Set Size 進(jìn)程獨(dú)自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存) 一般來說內(nèi)存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS

  • .long initialIdlePss:初始化pss
  • .long lastPss:上次pss
  • .long lastSwapPss:上次SwapPss數(shù)據(jù)
  • long lastCachedPss:上次CachedPss數(shù)據(jù)
  • long lastCachedSwapPss:上次CachedSwapPss數(shù)據(jù)
第五類數(shù)據(jù):和時(shí)間相關(guān)的數(shù)據(jù)
  • long lastActivityTime:上次使用時(shí)間
  • long lastStateTime:上次設(shè)置進(jìn)程狀態(tài)的時(shí)間
  • long fgInteractionTime:變成前臺(tái)的時(shí)間
第六類數(shù)據(jù):crash和anr相關(guān)的數(shù)據(jù)
  • IBinder.DeathRecipient deathRecipient:apk進(jìn)程退出運(yùn)行的話,會(huì)觸發(fā)這個(gè)對(duì)象的
    binderDied()方法,來回收系統(tǒng)資源
  • boolean crashing:進(jìn)程已經(jīng)crash
  • Dialog crashDialog:crash對(duì)話框
  • Dialog anrDialog:anr顯示對(duì)話框
  • String waitingToKill:后臺(tái)進(jìn)程被kill原因
第七類數(shù)據(jù):和instrumentation相關(guān)的數(shù)據(jù)

instrumentation 也可以說是apk的一個(gè)組件,如果我們提供的話,系統(tǒng)會(huì)默認(rèn)使用Instrumentation.java類,按照我們一般的理解,UI 線程控制activity的生命周期,是是直接調(diào)用Activity類的方法,時(shí)間是這樣子的,UI線程調(diào)用的是instrumentation的方法,由它在調(diào)用Activity涉及生命周期的方法,所有如果我們覆寫了instrumentation的這些方法,就可以了解所有的Activity的生命周期了.

  • ComponentName instrumentationClass:AndroidManifest.xml中定義的instrumentation信 息
  • ApplicationInfo instrumentationInfo:instrumentation應(yīng)用信息
  • String instrumentationProfileFile:instrumentation配置文件
  • IInstrumentationWatcher instrumentationWatcher:instrumentation監(jiān)測(cè)器
第八類數(shù)據(jù):電源信息和調(diào)試信息
  • BatteryStatsImpl mBatteryStats:電量信息
  • BatteryStatsImpl.Uid.Proc curProcBatteryStats:當(dāng)前進(jìn)程電量信息
  • boolean debugging:處于調(diào)試中
  • boolean waitedForDebugger:等待調(diào)試
  • Dialog waitDialog:等待對(duì)話框
ProcessRecord容器
內(nèi)部四大組件記錄表的容器

組件運(yùn)行才是進(jìn)程存在的意義,由于android系統(tǒng)進(jìn)程間的無縫結(jié)合,所以系統(tǒng)需要控制到組件級(jí)別,所有的組件信息都需要映射到系統(tǒng),一個(gè)ActivityRecord記錄對(duì)應(yīng)一個(gè)Activity的信息,一個(gè)ServiceRecord記錄對(duì)應(yīng)一個(gè)Service的信息,一個(gè)ConnectionRecord記錄對(duì)應(yīng)一個(gè)bind service的客戶端信息,一個(gè)ReceiverList對(duì)應(yīng)處理同一事件的一組廣播,一個(gè)ContentProviderRecord記錄對(duì)應(yīng)一個(gè)ContentProvider信息,一個(gè)ContentProviderConnection對(duì)應(yīng)一個(gè)進(jìn)程中的所有ContentProvider客戶端.
activity記錄:activities:ActivityRecord的容器,進(jìn)程啟動(dòng)的所有的activity組件記錄表
service記錄

  • services:ServiceRecord的容器,進(jìn)程啟動(dòng)的所有的service組件記錄表
  • executingServices:正在運(yùn)行(executing)的ServiceRecord是怎么定義的?首先需要明確的是系統(tǒng)是怎么控制組件的?發(fā)送消息給apk進(jìn)程,apk進(jìn)程處理消息,上報(bào)消息完成,這被定義為一個(gè)完整的執(zhí)行過程,因此正在執(zhí)行(executing)被定義為發(fā)送消息到上報(bào)完成這段時(shí)間
  • connections:ConnectionRecord容器,綁定service的客戶端記錄表

廣播接收器記錄:receivers:ReceiverList容器,廣播接收器的記錄表
ContentProvider記錄:

  • pubProviders:名字到ContentProviderRecord的映射容器,pub是publish(發(fā)布)的意思,
    ContentProvider需要安裝然后把自己發(fā)布到系統(tǒng)(AMS)中后,才能使用,安裝指的是apk進(jìn)程
    加載ContentProvider子類、初始化、創(chuàng)建數(shù)據(jù)庫等過程,發(fā)布是將ContentProvider的binder客
    戶端注冊(cè)到AMS中
  • contProviders:ContentProviderConnection容器,使用ContentProvider的客戶端記錄表
與Activity管理有關(guān)的數(shù)據(jù)結(jié)構(gòu)
ActivityRecord

ActivityRecord,源碼中的注釋介紹:An entry in the history stack, representing an activity. 翻譯:歷史棧中的一個(gè)條目,代表一個(gè)activity。
ActivityRecord中存在著大量的成員變量,包含了一個(gè)Activity的所有信息。 ActivityRecord中的成員變量task表示其所在的TaskRecord,由此可以看出:ActivityRecord與TaskRecord建立了聯(lián)系,
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

TaskRecord

TaskRecord,內(nèi)部維護(hù)一個(gè) ArrayList<ActivityRecord> 用來保存ActivityRecord
\frameworks\base\services\core\java\com\android\server\am\TaskRecord.java
可以看到TaskRecord中使用了一個(gè)ArrayList來保存所有的ActivityRecord。 同樣,TaskRecord中的mStack表示其所在的ActivityStack。 startActivity()時(shí)也會(huì)創(chuàng)建一個(gè)TaskRecord.

ActivityStarter

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

ActivityStack

ActivityStack,內(nèi)部維護(hù)了一個(gè) ArrayList<TaskRecord> ,用來管理`TaskRecord
可以看到ActivityStack使用了一個(gè)ArrayList來保存TaskRecord。 另外,ActivityStack中還持有ActivityStackSupervisor對(duì)象,這個(gè)是用來管理ActivityStacks的。 ActivityStack是由ActivityStackSupervisor來創(chuàng)建的,實(shí)際ActivityStackSupervisor就是用來管理ActivityStack的.

ActivityStackSupervisor

ActivityStackSupervisor,顧名思義,就是用來管理ActivityStack的
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
ActivityStackSupervisor內(nèi)部有兩個(gè)不同的ActivityStack對(duì)象:mHomeStack、mFocusedStack,用來管理不同的任務(wù)。 ActivityStackSupervisor內(nèi)部包含了創(chuàng)建ActivityStack對(duì)象的方法。 AMS初始化時(shí)會(huì)創(chuàng)建一個(gè)ActivityStackSupervisor對(duì)象.

最后上幾幅圖

[圖片上傳失敗...(image-86a5a8-1626183388942)]


在這里插入圖片描述
在這里插入圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容