com.android.phone进程启动流程

本文详细介绍了Android系统启动过程中,如何通过ActivityManagerService启动持久化应用的具体步骤,包括获取系统属性及启动进程等关键技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  system ready  【ActivityManagerService】

2. 获取系统属性为persist的app

3. startProcessLocked()启动进程

Code:

public void systemReady(final Runnable goingCallback) {  

            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
                try {  
                    List apps = AppGlobals.getPackageManager().  
                        getPersistentApplications(STOCK_PM_FLAGS);  
                    if (apps != null) {  
                        int N = apps.size();  
                        int i;  
                       for (i=0; i<N; i++) {  
                            ApplicationInfo info  
                                = (ApplicationInfo)apps.get(i);  
                            if (info != null &&  
                                    !info.packageName.equals("android")) {  
                                addAppLocked(info);  
                            }  
                        }  
                    }  
                } catch (RemoteException ex) {  
                    // pm is in same process, this will never happen.  
                }  
            }     
}  



Log

sys_log.boot

14:49:01.388081  1222  1222 I ActivityManager: u0 : Start proc 1559:com.android.phone/1001 for added application com.android.phone

main_log.boot

14:49:02.062996  1559  1559 V PhoneApp: u0 : onCreate()...


refer:

http://blog.youkuaiyun.com/windskier/article/details/6560925

http://blog.youkuaiyun.com/shrimpcolo/article/details/43766579

<think>我们正在处理一个关于AndroidANR(Application NotResponding)的问题,具体是输入分发超时导致的ANR,并出现“Applicationdoes nothave afocused window”的提示。根据引用资料,我们知道这种情况通常发生在InputDispatcher在分发输入事件时超时(默认5秒),并且系统发现当前应用没有获得焦点的窗口(focusedwindow)时。原因分析:1. **主线程阻塞**:最常见的原因是应用的主线程(UI线程)被阻塞,无法及时处理输入事件。这可能是由于在主线程执行了耗时操作(如网络请求、数据库操作、复杂计算等)导致的。2.**没有获得焦点的窗口**:应用程序当前没有获得焦点的窗口(即没有处于前台的Activity或Dialog),这可能是由于窗口创建延迟、窗口焦点丢失等原因造成的。引用[1]和引用[2]都提到了这种情况。3.**系统资源紧张**:系统整体资源(如CPU、内存)紧张,导致应用无法及时获得执行时间。4.**死锁或同步问题**:主线程在等待某个锁,而其他线程持有该锁且长时间不释放,导致主线程无法继续执行。解决方案:1. **优化主线程任务**:确保主线程只处理UI更新和轻量级操作,将耗时操作移到后台线程(如使用AsyncTask、ThreadPoolExecutor、IntentService等)。2.**检查窗口焦点**:确保在需要接收输入事件时,应用有获得焦点的窗口。例如,检查Activity的生命周期,确保在onResume之后才能接收输入事件;检查Dialog的显示是否正确获得焦点。3. **使用性能分析工具**:使用AndroidStudio的Profiler工具(特别是CPU和内存分析)来定位主线程的阻塞点。同时,使用Systrace工具分析系统级的行为,查看主线程在ANR发生时的状态。4.**检查死锁和同步问题**:检查代码中是否有潜在的同步问题或死锁,特别是在多线程访问共享资源时。5. **避免过度布局和绘制**:复杂的布局和频繁的重绘会导致主线程卡顿,优化布局层次和使用ViewStub等延迟加载技术。6.**监控ANR日志**:当发生ANR时,系统会生成traces.txt文件(位于/data/anr/),分析该文件可以找到主线程的堆栈信息,从而定位问题代码。根据引用[3],我们还可以通过以下方式进一步定位问题:-查看logcat日志,搜索“ANRin”关键字,找到发生ANR的进程和原因。-分析traces.txt文件,查看主线程的调用堆栈,找出阻塞的位置。示例:在traces.txt中,我们可能会看到类似如下的堆栈信息,表明主线程在等待某个锁: ```"main" prio=5 tid=1Blocked|group="main"sCount=1dsCount=0flags=1 obj=0x72deb848self=0x7f0e1c0e00| sysTid=12345nice=0 cgrp=defaultsched=0/0handle=0x7f9a5bd9a0|state=Sschedstat=(1234567899876543211234) utm=12stm=5core=1 HZ=100|stack=0x7fc2c1d000-0x7fc2c1f000stackSize=8MBatcom.example.app.MainActivity.doSomething(MainActivity.java:123)- waitingto lock<0x12345678> (a java.lang.Object) heldby thread23... ```这表明主线程在等待一个被线程23持有的锁,从而导致了阻塞。总结:对于“Applicationdoes nothave afocused window”的ANR问题,我们需要从主线程阻塞和窗口焦点两个方面入手,结合日志和性能分析工具定位问题代码,并进行优化。§§相关问题§§1.如何获取和分析Android ANR发生时的traces.txt文件? 2.Android开发中,有哪些常见的导致主线程阻塞的场景? 3.如何避免在Android应用中出现“没有获得焦点的窗口”的情况?4.使用Systrace工具分析ANR问题的具体步骤是什么?</think>### Android ANR "Input dispatching timed out" 问题分析与解决方案 #### 问题原因分析 当系统显示 **"Application does not have a focused window"** 的ANR对话框时,根本原因是输入事件分发超时(默认5秒),且应用没有获得焦点的窗口来处理输入事件[^1][^2]。具体机制如下: 1. **输入分发超时机制** InputDispatcher(输入分发器)在分发事件时启动超时计时器: - 若5秒内未收到应用处理完成的信号,触发`inputDispatchingTimedOut()`[^3] - 系统检查应用窗口焦点状态时,发现无有效聚焦窗口 2. **无聚焦窗口的常见场景** ```mermaid graph TD A[ANR触发条件] --> B{窗口焦点状态} B -->|无焦点| C[Activity未完成启动] B -->|无焦点| D[Dialog未正确显示] B -->|无焦点| E[窗口被遮挡/销毁] B -->|无焦点| F[Surface未完成创建] ``` 3. **根本原因分类** | 类型 | 具体场景 | 发生位置 | |---|---|----| | **窗口创建阻塞** | Activity.onCreate()耗时过长 | 主线程 | | **焦点丢失** | 后台Activity意外获得焦点 | Activity栈异常 | | **系统资源争用** | 内存不足导致Surface创建失败 | Native层 | | **同步操作超时** | Binder调用阻塞 | IPC通信 | #### 解决方案 **1. 优化窗口创建流程** ```java // 错误示例:主线程执行耗时初始化 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initHeavyResource(); // 可能导致阻塞 setContentView(R.layout.main); } // 正确做法:异步初始化 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 先创建基础UI new Thread(() -> initHeavyResource()).start(); // 后台初始化 } ``` **2. 焦点管理最佳实践** - 使用`onWindowFocusChanged()`确保窗口就绪: ```java public void onWindowFocusChanged(boolean hasFocus) { if(hasFocus) { // 窗口获得焦点后才启用输入监听 registerInputListeners(); } } ``` - 避免在`onPause()`中销毁未完成操作的窗口组件 **3. ANR日志分析步骤** 1. 获取`/data/anr/traces.txt`文件 2. 搜索关键字: ```log "Input dispatching timed out" "Reason: Application does not have a focused window" ``` 3. 检查主线程堆栈: ```log "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 flags=1 obj=0x74c1a8a0 | sysTid=25681 nice=-10 cgrp=default sched=0/0 handle=0x7adde25a08 | state=S schedstat=( 123456789 987654321 123 ) | stack=0x7fc95da000-0x7fc95dc000 at android.view.Surface.nativeLockCanvas(Native Method) at com.example.blocked.BadActivity.drawHeavyView(BadActivity.java:123) ← 阻塞点 ``` **4. 系统级优化建议** - 修改`InputDispatcher`超时阈值(需root): ```bash adb shell settings put global window_timeout 10000 # 改为10秒 ``` - 监控窗口焦点状态: ```bash adb shell dumpsys window windows | grep -E "mCurrentFocus|mFocusedApp" ``` #### 预防措施 1. **严格主线程规范** - 使用`StrictMode`检测主线程IO操作: ```java StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads().penaltyLog().build()); ``` 2. **异步加载机制** ```kotlin viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) { val data = heavyOperation() withContext(Dispatchers.Main) { updateUI(data) // 主线程更新 } } ``` 3. **窗口生命周期监控** 在`Activity`/`DialogFragment`中覆写: ```java public void onAttachedToWindow() { super.onAttachedToWindow(); // 窗口附加到WindowManager时记录状态 } ``` > **关键提示**:当ANR对话框显示时,实际阻塞点通常发生在对话框弹出**之前**的5-8秒[^3]。分析traces.txt需关注ANR时间点前的主线程状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值