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

网站前端怎么做方法濮阳新闻综合频道网站

网站前端怎么做方法,濮阳新闻综合频道网站,河北石家庄旅游网页设计,爱采购官网首页该系列文章总纲链接#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 说明#xff1a; 说明#xff1a;本章节主要涉及systemserver启动AMS及初始化AMS相关操作。同时由于该部分内容过多#xff0c;因此拆成2个章节#xff0c;本章节是第二章节…该系列文章总纲链接专题总纲目录 Android Framework 总纲 本章关键点总结 说明 说明本章节主要涉及systemserver启动AMS及初始化AMS相关操作。同时由于该部分内容过多因此拆成2个章节本章节是第二章节第一章节文章链接为 Android Framework AMS01AMS启动及相关初始化1-4 systemserver在启动AMSActivityManagerService时不仅仅是做简单的AMS服务启动还有很多的其他初始化相关操作这里我们以SystemServer启动流程为主线对AMS启动及相关逻辑进行初始化操作进行分析接下来我们通过代码来看看具体的操作逻辑。相关代码如下 // SystemServer//...// 定义系统服务的成员变量private ActivityManagerService mActivityManagerService;private SystemServiceManager mSystemServiceManager;private PowerManagerService mPowerManagerService;private PackageManagerService mPackageManagerService;//...private void startBootstrapServices() {// 启动引导服务这些服务在系统启动的早期阶段被启动// ...// 关键点1启动ActivityManagerService服务mActivityManagerService mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();// 关键点2为ActivityManagerService设置系统服务管理器mActivityManagerService.setSystemServiceManager(mSystemServiceManager);// 启动PowerManagerService服务mPowerManagerService mSystemServiceManager.startService(PowerManagerService.class);// 关键点3初始化电源管理mActivityManagerService.initPowerManagement();// 关键点4将当前进程设置为系统进程mActivityManagerService.setSystemProcess();// ...}//...private void startCoreServices() {// 启动核心服务// ...// 为ActivityManagerService设置UsageStatsManager服务mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));// ...}//...private void startOtherServices() {// 启动其他服务// ...WindowManagerService wm null;// ...// 关键点5安装系统提供的ContentProvidersmActivityManagerService.installSystemProviders();// 初始化看门狗监控watchdog.init(context, mActivityManagerService);// 创建WindowManagerService服务wm WindowManagerService.main(context, inputManager,mFactoryTestMode ! FactoryTest.FACTORY_TEST_LOW_LEVEL,mActivityManagerService);// 关键点6为ActivityManagerService设置WindowManagermActivityManagerService.setWindowManager(wm);final boolean safeMode wm.detectSafeMode();if (safeMode) {// 检测安全模式// 进入安全模式mActivityManagerService.enterSafeMode();// 禁用JIT编译VMRuntime.getRuntime().disableJitCompilation();} else {// 启用JIT编译VMRuntime.getRuntime().startJitCompilation();}if (safeMode) {// 如果处于安全模式显示安全模式覆盖层mActivityManagerService.showSafeModeOverlay();}// ...// 通知PowerManagerService系统已准备好mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());// 关键点7当ActivityManagerService准备好后执行的操作mActivityManagerService.systemReady(new Runnable() {Overridepublic void run() {// 启动系统服务管理器的下一个启动阶段mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);try {//关键点8开始监控本地崩溃mActivityManagerService.startObservingNativeCrashes();} catch (Throwable e) {// 报告错误reportWtf(observing native crashes, e);}// ...WebViewFactory.prepareWebViewInSystemServer();try {// 尝试启动系统用户界面startSystemUi(context);} catch (Throwable e) {reportWtf(starting System UI, e);}try {//尝试通知挂载服务系统已准备就绪if (mountServiceF ! null) mountServiceF.systemReady();} catch (Throwable e) {reportWtf(making Mount Service ready, e);}//...//其他各种服务准备就绪//...}});// ...} 以上代码通过关键点的标注共列出了8个重要的调用并对这些调用进行了简单的描述。整理如下 关键点1启动ActivityManagerService服务。关键点2为ActivityManagerService设置系统服务管理器。关键点3初始化电源管理。关键点4将当前进程设置为系统进程。关键点5安装系统提供的ContentProviders。关键点6为ActivityManagerService设置WindowManager。关键点7当ActivityManagerService准备好后执行的操作。关键点8开始监控本地崩溃。 接下来针对这8个关键点进行详细的解读。上一篇关注关键点1-4部分本章节主要关注关键点5-8部分。 5 安装系统提供的ContentProviders 这里从代码 mActivityManagerService.installSystemProviders(); 开始分析对应代码实现如下 //ActivityManagerServicepublic final void installSystemProviders() {ListProviderInfo providers;synchronized (this) {// 获取系统进程的记录// 这个进程是Android系统框架的核心部分包含了许多系统服务和系统应用ProcessRecord app mProcessNames.get(system, Process.SYSTEM_UID);// 生成系统应用的ContentProvider列表// 这些 ContentProvider 属于系统应用包是系统框架的一部分。providers generateApplicationProvidersLocked(app);if (providers ! null) {// 遍历列表检查每个Provider是否属于系统应用for (int i providers.size() - 1; i 0; i--) {ProviderInfo pi providers.get(i);// 检查Provider是否设置了FLAG_SYSTEM标志if ((pi.applicationInfo.flags ApplicationInfo.FLAG_SYSTEM) 0) {// 如果没有设置FLAG_SYSTEM标志记录警告日志并从列表中移除providers.remove(i);}}}}// 如果最终的Provider列表不为空则安装这些Providerif (providers ! null) {mSystemThread.installSystemProviders(providers);}// 创建一个核心设置观察者用于监听系统设置的变化mCoreSettingsObserver new CoreSettingsObserver(this);} installSystemProviders方法的主要作用是安装系统应用的ContentProvider。这些ContentProvider是系统正常运行所必需的它们提供了对系统数据的访问和管理。通过同步代码块和检查FLAG_SYSTEM标志确保只有属于系统应用的ContentProvider会被安装。此外该方法还负责创建系统设置观察者用于监控系统设置的变化。这个过程是系统启动和初始化阶段的关键部分确保了系统应用能够正常提供服务。 installSystemProviders方法在Android的ActivityManagerServiceAMS中执行其主要目的是初始化和注册系统级别的ContentProvider。那么为什么要这么做呢总结如下 系统数据管理系统级的ContentProvider提供了对核心系统数据的访问如联系人、日历事件、系统设置等。这些数据需要被多个应用程序共享和访问。服务注册通过installSystemProviders方法系统可以将这些关键的ContentProvider注册到服务管理器ServiceManager使得其他应用和系统组件能够发现并与之通信。安全性系统级的ContentProvider可以实施严格的安全策略包括权限检查确保只有授权的应用可以访问敏感数据。性能优化预先加载和初始化这些ContentProvider有助于提高系统性能因为它们在系统启动早期就已经准备就绪减少了应用运行时的等待时间。跨应用通信ContentProvider是Android中实现跨应用通信的重要机制。它们允许应用之间共享数据而无需应用直接相互引用。系统服务支持许多系统服务依赖于ContentProvider来存储和检索数据。这些服务可能包括设备策略管理器、备份服务等。一致性和可靠性确保所有必要的系统ContentProvider都在系统启动时正确初始化有助于提高整个系统的一致性和可靠性。用户体验快速响应用户操作和提供流畅的用户体验需要系统服务和应用能够及时访问所需的数据。系统监控和管理一些系统ContentProvider提供了系统运行状况和性能数据的访问有助于系统监控和管理。初始化和配置在系统启动过程中installSystemProviders方法确保了所有必要的系统级ContentProvider被正确配置和初始化。 总结来说installSystemProviders方法对于建立一个功能齐全、安全、高效的Android系统至关重要。它确保了系统应用和系统服务能够访问和管理核心数据同时为应用提供了必要的数据共享机制。 最后这里详细解读下涉及到的generateApplicationProvidersLocked方法代码实现如下 //ActivityManagerServiceprivate final ListProviderInfo generateApplicationProvidersLocked(ProcessRecord app) {ListProviderInfo providers null;try {// 查询该应用进程的ContentProviderproviders AppGlobals.getPackageManager().queryContentProviders(app.processName, app.uid,STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);} catch (RemoteException ex) {}int userId app.userId;if (providers ! null) {int N providers.size();app.pubProviders.ensureCapacity(N app.pubProviders.size());for (int i0; iN; i) {ProviderInfo cpi providers.get(i);boolean singleton isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags);// 单例ContentProvider且不是默认用户移除if (singleton UserHandle.getUserId(app.uid) ! 0) {providers.remove(i);N--;i--;continue;}// 创建ComponentNameComponentName comp new ComponentName(cpi.packageName, cpi.name);// 尝试获取已有的ContentProviderRecordContentProviderRecord cpr mProviderMap.getProviderByClass(comp, userId);if (cpr null) {// 如果没有找到创建新的ContentProviderRecordcpr new ContentProviderRecord(this, cpi, app.info, comp, singleton);mProviderMap.putProviderByClass(comp, cpr);}app.pubProviders.put(cpi.name, cpr);// 如果ContentProvider不是多进程的添加到应用包列表if (!cpi.multiprocess || !android.equals(cpi.packageName)) {app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, mProcessStats);}ensurePackageDexOpt(cpi.applicationInfo.packageName);}}return providers;} generateApplicationProvidersLocked方法的目的是初始化和注册系统应用的ContentProvider确保它们可以为整个系统提供必要的数据访问服务。具体来说该方法会查询系统应用包中的所有 ContentProvider包括 系统设置 ContentProvider如 SettingsProvider提供了对系统设置的访问。账户 ContentProvider如 AccountsProvider管理账户信息。联系人 ContentProvider如 ContactsProvider管理联系人数据。其他系统 ContentProvider任何其他包含在系统应用包中的 ContentProvider。 这些 ContentProvider 通常位于系统应用的包名如 android下并且对于系统的正常运行和应用的数据访问至关重要。 6 为ActivityManagerService设置WindowManager 这里从代码 mActivityManagerService.setWindowManager(wm);开始分析对应代码实现如下 //ActivityManagerServicepublic void setWindowManager(WindowManagerService wm) {mWindowManager wm;mStackSupervisor.setWindowManager(wm);} 这里的设计很简单但我们要了解这样设计背后的意义 协调窗口和活动管理通过设置窗口管理器的引用AMS和ActivityStackSupervisor可以与窗口管理器进行交互确保活动和窗口的正确创建和显示。提供窗口上下文WindowManagerService提供了必要的上下文和工具使AMS能够为应用程序创建和管理窗口。支持动态界面更新在Android系统中窗口和活动经常需要动态更新。例如当用户切换应用程序或启动新活动时窗口管理器负责更新用户界面。确保系统组件一致性setWindowManager方法确保AMS和ActivityStackSupervisor使用的是同一个WindowManagerService实例这有助于保持系统组件之间的一致性和同步。 总之setWindowManager方法在AMS中至关重要因为它确保了活动管理器AMS和活动堆栈监管者ActivityStackSupervisor能够与窗口管理器WindowManagerService进行通信和协调。这种设置对于正确管理应用程序的窗口和活动至关重要特别是在处理复杂的用户界面场景时。 这里详细解读下涉及到的mStackSupervisor.setWindowManager方法代码实现如下 //ActivityStackSupervisorvoid setWindowManager(WindowManagerService wm) {synchronized (mService) {// 设置ActivityStackSupervisor使用的窗口管理器mWindowManager wm;// 获取显示管理服务mDisplayManager (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);// 注册显示管理服务的监听器mDisplayManager.registerDisplayListener(this, null);// 获取所有显示的数组Display[] displays mDisplayManager.getDisplays();// 遍历所有显示for (int displayNdx displays.length - 1; displayNdx 0; --displayNdx) {// 获取显示IDfinal int displayId displays[displayNdx].getDisplayId();// 创建ActivityDisplay对象ActivityDisplay activityDisplay new ActivityDisplay(displayId);//...// 将ActivityDisplay对象添加到映射中mActivityDisplays.put(displayId, activityDisplay);}// 在默认显示上创建主堆栈createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);// 设置主堆栈、焦点堆栈和最后焦点的堆栈为刚创建的主堆栈mHomeStack mFocusedStack mLastFocusedStack getStack(HOME_STACK_ID);// 获取输入管理服务的内部服务mInputManagerInternal LocalServices.getService(InputManagerInternal.class);// 初始化LeanbackOnlyDevice标志现在可以获得有效的PackageManager引用mLeanbackOnlyDevice isLeanbackOnlyDevice();}} mStackSupervisor.setWindowManager方法的主要作用是设置窗口管理器并进行一系列初始化工作包括获取显示管理服务、注册显示监听器、创建显示相关的数据结构、初始化主堆栈和焦点堆栈以及获取输入管理服务。这些步骤确保了ActivityStackSupervisor能够正确管理活动的显示和堆栈无论设备有多少个显示以及是否为特定模式如Leanback模式的设备。 7 当ActivityManagerService准备好后执行的操作 这里从代码 //SystemServerprivate void startOtherServices() {// 启动其他服务//...mActivityManagerService.systemReady(new Runnable() {Overridepublic void run() {//...}});//...}开始分析因ActivityManagerService.systemReady的代码较长因此这里分成3个阶段进行解读。具体如下。 7.1 systemReady第一阶段主要以升级相关逻辑为主 systemReady第一阶段代码实现如下 //ActivityManagerService // 该方法在系统启动时调用用于执行系统服务的初始化public void systemReady(final Runnable goingCallback) {//第一阶段synchronized(this) {// 检查系统是否已经准备好如果已经准备好运行传入的回调并返回if (mSystemReady) {if (goingCallback ! null) {goingCallback.run();}return;}// 更新当前的用户配置文件信息这些信息用于安全检查updateCurrentProfileIdsLocked();// 如果最近任务列表为空则尝试从持久化存储中恢复最近任务if (mRecentTasks null) {mRecentTasks mTaskPersister.restoreTasksLocked();// 如果恢复了最近任务创建对应的任务堆栈if (!mRecentTasks.isEmpty()) {mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);}// 清理最近任务列表移除不再需要的任务cleanupRecentTasksLocked(UserHandle.USER_ALL);// 开始持久化保存任务列表mTaskPersister.startPersisting();}// 检查是否有系统更新的广播接收器需要运行if (!mDidUpdate) {// 如果已经在等待更新那么直接返回if (mWaitingUpdate) {return;}// 创建一个列表来记录完成的广播接收器final ArrayListComponentName doneReceivers new ArrayListComponentName();// 设置正在等待更新的标志mWaitingUpdate true;// 调用deliverPreBootCompleted来执行系统更新相关的广播接收器deliverPreBootCompleted(new Runnable() {public void run() {// 同步代码块确保线程安全synchronized (ActivityManagerService.this) {// 设置系统更新完成的标志mDidUpdate true;}// 记录完成的广播接收器writeLastDonePreBootReceivers(doneReceivers);// 显示系统更新完成的消息showBootMessage(mContext.getText(R.string.android_upgrading_complete),false);// 递归调用systemReady继续执行系统启动的下一阶段systemReady(goingCallback);}}, doneReceivers, UserHandle.USER_OWNER);// 如果还在等待更新那么返回if (mWaitingUpdate) {return;}// 设置系统更新完成的标志mDidUpdate true;}// 通知AppOpsService系统已经准备好mAppOpsService.systemReady();// 设置系统已经准备好的标志mSystemReady true;}//...} systemReady方法的第一阶段主要负责初始化系统的关键部分包括更新用户配置文件信息、恢复最近任务、执行系统更新广播接收器等。这些步骤确保了系统在启动过程中能够正确地恢复状态为用户使用做好准备。 7.2 systemReady第二阶段以kill掉AMS之前启动的应用进程为主 systemReady第二阶段代码实现如下 //ActivityManagerService // 该方法在系统启动时调用用于执行系统服务的初始化public void systemReady(final Runnable goingCallback) {//...// 第二阶段清理不应该在启动过程中运行的进程ArrayListProcessRecord procsToKill null;synchronized(mPidsSelfLocked) {for (int i mPidsSelfLocked.size()-1; i 0; i--) {ProcessRecord proc mPidsSelfLocked.valueAt(i);// 检查进程是否允许在启动过程中运行if (!isAllowedWhileBooting(proc.info)){if (procsToKill null) {procsToKill new ArrayListProcessRecord();}procsToKill.add(proc);}}}// 同步代码块确保线程安全synchronized(this) {// 清理更新进程if (procsToKill ! null) {for (int i procsToKill.size()-1; i 0; i--) {ProcessRecord proc procsToKill.get(i);Slog.i(TAG, Removing system update proc: proc);// 移除不应该在启动过程中运行的进程removeProcessLocked(proc, true, false, system update done);}}// 标记为不再清理更新进程准备启动真正的进程mProcessesReady true;}// 同步代码块确保线程安全synchronized(this) {// 处理工厂测试模式if (mFactoryTest FactoryTest.FACTORY_TEST_LOW_LEVEL) {ResolveInfo ri mContext.getPackageManager().resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),STOCK_PM_FLAGS);CharSequence errorMsg null;if (ri ! null) {ActivityInfo ai ri.activityInfo;ApplicationInfo app ai.applicationInfo;if ((app.flags ApplicationInfo.FLAG_SYSTEM) ! 0) {mTopAction Intent.ACTION_FACTORY_TEST;mTopData null;mTopComponent new ComponentName(app.packageName, ai.name);} else {errorMsg mContext.getResources().getText(com.android.internal.R.string.factorytest_not_system);}} else {errorMsg mContext.getResources().getText(com.android.internal.R.string.factorytest_no_action);}if (errorMsg ! null) {mTopAction null;mTopData null;mTopComponent null;Message msg Message.obtain();msg.what SHOW_FACTORY_ERROR_MSG;msg.getData().putCharSequence(msg, errorMsg);mHandler.sendMessage(msg);}}}// 检索系统设置retrieveSettings();// 加载系统资源loadResourcesOnSystemReady();// 同步代码块确保线程安全synchronized (this) {// 读取授权的URI权限readGrantedUriPermissionsLocked();}// 如果有传入的回调运行它if (goingCallback ! null) goingCallback.run();// 通知电池统计服务用户开始运行mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,Integer.toString(mCurrentUserId), mCurrentUserId);// 通知电池统计服务用户进入前台mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,Integer.toString(mCurrentUserId), mCurrentUserId);// 启动用户会话mSystemServiceManager.startUser(mCurrentUserId);//... systemReady方法的第二阶段主要负责清理更新进程、记录系统就绪事件、应用设置、加载资源以及启动用户会话。这些步骤确保了系统在启动完成后能够正常运行应用程序并为用户提供服务。 7.3 systemReady第三阶段以启动系统应用、发广播、恢复前台活动为主 systemReady第三阶段代码实现如下 //ActivityManagerService // 该方法在系统启动时调用用于执行系统服务的初始化public void systemReady(final Runnable goingCallback) {//...// 第三阶段启动应用程序和发送用户启动广播synchronized (this) {// 如果不是工厂测试模式if (mFactoryTest ! FactoryTest.FACTORY_TEST_LOW_LEVEL) {try {// 获取所有持久应用的列表List apps AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);if (apps ! null) {int N apps.size();for (int i 0; i N; i) {ApplicationInfo info (ApplicationInfo)apps.get(i);// 添加非android包的应用到系统中if (info ! null !info.packageName.equals(android)) {addAppLocked(info, false, null /* ABI override */);}}}} catch (RemoteException ex) {// 由于PackageManagerService在同一个进程中这个异常不会发生}}// 启动初始活动mBooting true;startHomeActivityLocked(mCurrentUserId);try {// 检查是否有系统UID错误if (AppGlobals.getPackageManager().hasSystemUidErrors()) {Message msg Message.obtain();msg.what SHOW_UID_ERROR_MSG;mHandler.sendMessage(msg);}} catch (RemoteException e) {// 忽略异常}// 清除调用者身份以便以系统身份发送广播long ident Binder.clearCallingIdentity();try {// 发送ACTION_USER_STARTED广播通知所有用户相关的应用Intent intent new Intent(Intent.ACTION_USER_STARTED);intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY| Intent.FLAG_RECEIVER_FOREGROUND);intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);broadcastIntentLocked(null, null, intent,null, null, 0, null, null, null, AppOpsManager.OP_NONE,false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);// 发送ACTION_USER_STARTING广播通知用户启动intent new Intent(Intent.ACTION_USER_STARTING);intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);broadcastIntentLocked(null, null, intent,null, new IIntentReceiver.Stub() {Overridepublic void performReceive(Intent intent, int resultCode, String data,Bundle extras, boolean ordered, boolean sticky, int sendingUser)throws RemoteException {}}, 0, null, null,INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);} catch (Throwable t) {Slog.wtf(TAG, Failed sending first user broadcasts, t);} finally {// 恢复调用者身份Binder.restoreCallingIdentity(ident);}// 恢复前台活动mStackSupervisor.resumeTopActivitiesLocked();// 发送用户切换广播sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);}} systemReady方法的第三阶段主要负责处理工厂测试模式、启动系统的应用、发送用户启动广播、恢复前台活动等。这些步骤确保了系统在启动完成后能够正常运行应用程序并为用户提供服务。 8 开始监控本地崩溃 这里从代码 mActivityManagerService.startObservingNativeCrashes(); 开始分析对应代码实现如下 //ActivityManagerServicepublic void startObservingNativeCrashes() {final NativeCrashListener ncl new NativeCrashListener(this);ncl.start();} NativeCrashListener 是继承Thread的实际上就是开启了一个线程。 8.1 解读 NativeCrashListener线程逻辑 NativeCrashListener 线程的实现是run方法该部分代码忽略了异常处理和日志的打印的逻辑关键代码如下 // NativeCrashListenerpublic void run() {// 用于接收信号的字节数组final byte[] ackSignal new byte[1];// 删除已存在的socket文件{File socketFile new File(DEBUGGERD_SOCKET_PATH);if (socketFile.exists()) {socketFile.delete();}}try {// 创建一个UNIX domain socketFileDescriptor serverFd Os.socket(AF_UNIX, SOCK_STREAM, 0);final InetUnixAddress sockAddr new InetUnixAddress(DEBUGGERD_SOCKET_PATH);// 绑定socket到指定路径Os.bind(serverFd, sockAddr, 0);// 监听socket连接Os.listen(serverFd, 1);// 无限循环等待debuggerd的连接while (true) {InetSocketAddress peer new InetSocketAddress();FileDescriptor peerFd null;try {// 接受连接peerFd Os.accept(serverFd, peer);// 检查连接的凭证只允许超级用户连接StructUcred credentials Os.getsockoptUcred(peerFd, SOL_SOCKET, SO_PEERCRED);if (credentials.uid 0) {// 消费崩溃数据consumeNativeCrashData(peerFd);}} finally {// 无论处理过程中是否发生异常都要发送确认信号给debuggerdif (peerFd ! null) {try {Os.write(peerFd, ackSignal, 0, 1);} finally {// 关闭socket连接Os.close(peerFd);}}}}}//...} NativeCrashListener的run方法主要负责监听和处理由debuggerd发送的native崩溃信号。它通过创建一个socket服务器等待debuggerd的连接并在连接建立后处理崩溃数据。这个过程确保了系统能够及时响应native崩溃从而提高系统的稳定性。 接下来我们来看看对于这些崩溃数据是如何处理的即consumeNativeCrashData的代码实现具体如下 // NativeCrashListener// 处理崩溃的native进程发送的数据void consumeNativeCrashData(FileDescriptor fd) {// 创建一个字节缓冲区用于读取数据final byte[] buf new byte[4096];// 创建一个字节输出流用于收集崩溃数据final ByteArrayOutputStream os new ByteArrayOutputStream(4096);try {// 设置读取和写入的超时时间StructTimeval timeout StructTimeval.fromMillis(SOCKET_TIMEOUT_MILLIS);Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);// 首先读取崩溃的进程ID和信号号int headerBytes readExactly(fd, buf, 0, 8);int pid unpackInt(buf, 0); // 进程IDint signal unpackInt(buf, 4); // 信号号if (pid 0) {// 根据进程ID获取崩溃进程的记录final ProcessRecord pr;synchronized (mAm.mPidsSelfLocked) {pr mAm.mPidsSelfLocked.get(pid);}if (pr ! null) {// 持久进程不进行崩溃报告if (pr.persistent) {return;}int bytes;// 循环读取崩溃数据直到读取完毕do {bytes Os.read(fd, buf, 0, buf.length);if (bytes 0) {if (buf[bytes-1] 0) {os.write(buf, 0, bytes-1);break;}os.write(buf, 0, bytes);}} while (bytes 0);// 标记进程为正在崩溃状态synchronized (mAm) {pr.crashing true;pr.forceCrashReport true;}// 将崩溃报告转换为字符串final String reportString new String(os.toByteArray(), UTF-8);// 创建一个崩溃报告线程(new NativeCrashReporter(pr, signal, reportString)).start();}}}// 异常处理略...} consumeNativeCrashData方法用于处理崩溃的native进程发送的数据。它读取崩溃数据生成崩溃报告并启动一个线程来处理这个报告。对应的处理报告的线程为NativeCrashReporter它的run方法代码实现如下 //NativeCrashListenerclass NativeCrashReporter extends Thread {//...Overridepublic void run() {try {// 创建CrashInfo对象封装崩溃信息CrashInfo ci new CrashInfo();ci.exceptionClassName Native crash;ci.exceptionMessage Os.strsignal(mSignal);ci.throwFileName unknown;ci.throwClassName unknown;ci.throwMethodName unknown;ci.stackTrace mCrashReport;// 调用AMS的handleApplicationCrashInner方法处理崩溃mAm.handleApplicationCrashInner(native_crash, mApp, mApp.processName, ci);}//...}}继续分析AMS的handleApplicationCrashInner方法代码实现如下 //ActivityManagerService// 处理应用程序崩溃的方法void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,ApplicationErrorReport.CrashInfo crashInfo) {// 将崩溃事件记录到系统事件日志中,包括崩溃的进程ID、用户ID、进程名称// 、进程标志、异常类名、异常信息、发生异常的文件名和行号等信息EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),UserHandle.getUserId(Binder.getCallingUid()), processName,r null ? -1 : r.info.flags,crashInfo.exceptionClassName,crashInfo.exceptionMessage,crashInfo.throwFileName,crashInfo.throwLineNumber);// 将崩溃的错误信息添加到DropBox中// DropBox是一个系统服务用于收集和存储系统和应用程序的错误报告供后续分析和调试使用addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);// 执行崩溃处理逻辑包括重启应用程序、通知用户、记录崩溃信息等crashApplication(r, crashInfo);} handleApplicationCrashInner方法是一个关键的系统方法用于处理应用程序崩溃事件。它通过记录崩溃信息、添加错误报告到DropBox以及执行崩溃处理确保了系统能够适当地响应崩溃事件同时为后续的错误分析和调试提供了必要的信息。这部分至此就不再继续分析了再往后就是一堆崩溃信息的详细处理了我们只需要了解到最终崩溃的处理是在AMS中处理即可。其他的可根据自己的需要继续深入分析。 8.2 关于崩溃处理的理解总结 当应用程序发生崩溃时系统会通过一系列机制来处理崩溃并生成崩溃报告。以下是整个过程的概述 应用崩溃当应用程序发生崩溃通常是由于native代码异常如段错误、总线错误等时系统会捕获到这个崩溃信号。生成崩溃报告系统服务debuggerd会生成崩溃报告。这个报告包含了崩溃时的堆栈跟踪、寄存器状态、运行的线程等信息。建立socket连接debuggerd会尝试建立一个socket连接将崩溃报告发送给ActivityManagerServiceAMS或其他监听崩溃的服务。监听崩溃在AMS中NativeCrashListener线程会监听崩溃。它会创建一个socket服务器并等待debuggerd的连接。接收崩溃报告当debuggerd与AMS的socket服务器建立连接后AMS的NativeCrashListener线程会接收到崩溃报告。处理崩溃AMS会处理崩溃报告这可能包括记录崩溃信息、通知开发者、重启应用程序或执行其他错误恢复操作。发送确认信号AMS会向debuggerd发送一个确认信号表明崩溃报告已经收到。关闭socket连接处理完崩溃报告后AMS会关闭socket连接。用户通知如果应用程序崩溃导致用户体验受到影响系统可能会向用户显示一个崩溃通知让用户知道应用程序发生了问题。崩溃转储可选在某些情况下系统可能会将崩溃信息转储到磁盘上的一个文件中以供后续分析。重启应用程序如果可能系统会尝试重启崩溃的应用程序为用户提供尽可能无缝的体验。 这个过程确保了应用程序崩溃时系统能够捕获必要的信息并采取适当的措施来恢复或通知用户。通过这种方式系统能够提高应用程序的稳定性和用户体验。
http://www.hkea.cn/news/14509812/

相关文章:

  • 有了域名公司网站怎么建设创建网站的步骤
  • 无锡做网站365caiyi住房和城乡建设部的叉车证能用吗
  • 做本地网站赚钱吗php可视化网站开发工具
  • 网站设计服务做招聘网站需要哪些手续
  • 设计 微网站个人作品展示网站
  • php网站开发用什么软件百度个人网站申请
  • 有没有专门搞网站上线的公司妇幼医院网站建设方案
  • 七彩建设集团官方网站管理培训公司
  • 自己做网站 如何推广个人风采网站制作
  • 苏州市住房和城乡建设局网站台州市住房和城乡建设厅网站
  • 张槎网站开发大数据网站开发工程师
  • 阳江网站建设推广安微省建设厅网站
  • 给人做传销网站哈尔滨seo优化客户
  • 拖拽式制作网站做网站都需要什么步骤
  • 提供网站建设报价做网站大概需要多少钱
  • 网站设置关键词学历提升专升本
  • 网站重构营销一型网站建设公司
  • 烟台市建设工程交易中心网站网页设计与制作心得体会800字
  • 做教育网站多少钱wordpress首页弹出公告
  • 深圳代做网站网站维护页面怎么做的
  • 重庆 做网站开网店需要自己做网站吗
  • 江苏10大网站建设公司小程序搭建系统
  • 屏山县建设招标网站关键词排名优化怎么样
  • 淘宝客 网站无备案公众号平台官网网页版
  • 有哪些是外国人做的网站中国建筑集团有限公司有几个局
  • 三河网站建设公司百度系app有哪些
  • 网站建设定制价格明细表用照片做的ppt模板下载网站
  • 苏州企业建站公司软件技术跟网站开发有关系吗
  • 重庆网站定制哪家好开车搜索关键词
  • 门户网站开发项目一个专做里番的网站