|Job| Application No Response Analysis

ANR 的發生情形,通常是時間到了還沒有回應!所以掌握這個想法,就比較好找 Code。

比較常見有三種情形:

  1. Service Timeout
  2. BroadcastQueue Timeout
  3. ContentProvider Timeout

 

Case 1. Service Timeout

 a. Service 啟動後,會發送 SERVICE_TIMEOUT_MSG 消息
 b. Service 刪除後,就會刪除 SERVICE_TIMEOUT_MSG 消息
 c. 如果 SERVICE_TIMEOUT_MSG 未删除,時間到後就會 ANR

 呼叫 ActiveServices 的 serviceTimeout 方法進行處理,
 serviceTimeout方法邏輯:

 if (anrMessage != null) {
  mAm.appNotResponding(proc, null, null, false, anrMessage);
 }

 

Case 2. BroadcastQueue Timeout

 BroadcastQueue 中的 mHandler 收到 BROADCAST_TIMEOUT_MSG 消息時會觸發

 // 正常要發送消息前
 broadcastTimeoutLocked(false);

 // 發送消息,鎖住
 case BROADCAST_TIMEOUT_MSG: {
  synchronized (mService) {
   broadcastTimeoutLocked(true);

 // ANR
 在 broadcastTimeoutLocked 方法中,首先取得 anrMessage 字串

 anrMessage = “Broadcast of ” + r.intent.toString();

 mHandler.post(new AppNotResponding(app, anrMessage));
 mService.appNotResponding(mApp, null, null, false, mAnnotation);

 

Case 3. ContentProvider Timeout

 MainHandler 的 handleMessage CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG

 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
cleanupAppInLaunchingProvidersLocked(app, true);
 removeProcessLocked(app, false, true, “timeout publishing content providers”);
 }

 app.kill(reason, true);

 

ref.

https://blog.csdn.net/u012439416/article/category/7261623

 

|RIL| Data Connection Flow

觀念:

  1. 啟動數據服務前,要先設定 APN。APN 在上層有一份,在 modem 也有一份
  2. 是可以只用 modem 裡的那份 APN (嵌入式平台)
  3. Android 是由上層帶 APN 給 modem 的
  4. 上層主要是看 bringUp & RIL 的 setupDataCall

 

以下只講部分關鍵點。

 

# load 上層的 db:TelephonyProvider.java

  loadApns()

# TelephonyManager:使用者點開數據上網的 Icon
  public void setDataEnabled(boolean enable) {
   setDataEnabled(getDefaultDataSubscriptionId(), enable);

# DcAsyncChannel:填入 APN, 準備往下帶
    public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology,
                        boolean unmeteredUseOnly, Message onCompletedMsg,
                        int connectionGeneration) {
        mLastConnectionParams = new ConnectionParams(apnContext, profileId, rilRadioTechnology,
                unmeteredUseOnly, onCompletedMsg, connectionGeneration);
        sendMessage(DataConnection.EVENT_CONNECT, mLastConnectionParams);

# DataConnection:StateMachine 收到要建立連線啦!
 public boolean processMessage(Message msg) {
  …
   case EVENT_CONNECT:
    if (DBG) log(“DcInactiveState: mag.what=EVENT_CONNECT”);
     ConnectionParams cp = (ConnectionParams) msg.obj;
     if (initConnection(cp)) {
      onConnect(mConnectionParams);

# RIL:終於送到 RIL了,要往 Modem 前進啦!

 mPhone.mCi.setupDataCall(cp.mRilRat, dp, isModemRoaming, allowRoaming, msg);

 

Ref. https://blog.csdn.net/u012439416/article/details/75263645

WordPress.com.

Up ↑