发生ANR的时候这个进程(com.google.android.videos)的主线程stack如下:
"main" prio=5 tid=1 Native
......
at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:503)
at com.android.vending.contentfilters.IContentFiltersService$Stub$Proxy.getContentFiltersAndIntent(SourceFile:138)
at com.google.android.videos.contentfiltering.ContentFiltersManager.saveContentFiltersToPreference(SourceFile:438)
at com.google.android.videos.contentfiltering.ContentFiltersManager.access$100(SourceFile:81)
at com.google.android.videos.contentfiltering.ContentFiltersManager$1.onServiceConnected(SourceFile:423)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1223)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1240)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5446)
......
阻塞在binder调用中,因此需要继续看binder服务端为什么没有及时返回。这个对应的binder服务端是进程com.android.vending。
此时com.android.vending对应的binder线程的堆栈如下:
Cmd line: com.android.vending
"Binder_2" prio=5 tid=8 Waiting
held mutexes=
at java.lang.Object.wait!(Native method)
waiting on <0x0ee7a0e1> (a com.android.volley.toolbox.RequestFuture)
at java.lang.Object.wait(Object.java:423)
at com.android.volley.toolbox.RequestFuture.doGet(RequestFuture.java:111)
locked <0x0ee7a0e1> (a com.android.volley.toolbox.RequestFuture)
at com.android.volley.toolbox.RequestFuture.get(RequestFuture.java:88)
at com.google.android.finsky.api.model.DfeContentFilters.fetchOverNetwork$6f1d50b6(DfeContentFilters.java:54)
at com.google.android.finsky.services.ContentFiltersService$1.getContentFiltersAndIntent(ContentFiltersService.java:69)
at com.android.vending.contentfilters.IContentFiltersService$Stub.onTransact(IContentFiltersService.java:50)
at android.os.Binder.execTransact(Binder.java:453)
通过反编译com.android.vending代码,看到binder服务端代码如下:
public class ContentFiltersService extends Service {
......
private final IContentFiltersService.Stub mBinder = new IContentFiltersService.Stub() {
public final Bundle getContentFiltersAndIntent(
......
DfeContentFilters localDfeContentFilters = new DfeContentFilters(localFinskyApp.getDfeApi(null),ContentFiltersService.this);
boolean bool = localDfeContentFilters.isCacheStale();
......
if (bool)
localContentFilterSettingsResponse = localDfeContentFilters
.fetchOverNetwork$6f1d50b6();
......
}
......
}
这里在if(bool)成立时会执行DfeContentFilters对象localDfeContentFilters的fetchOverNetwork$6f2d50b6方法。从stack信息看这个方法继续调用到RequestFuture.doGet.
RequestFuture.doGet代码:
100 private synchronized T doGet(Long timeoutMs)
101 throws InterruptedException, ExecutionException, TimeoutException {
102 if (mException != null) {
103 throw new ExecutionException(mException);
104 }
105
106 if (mResultReceived) {
107 return mResult;
108 }
109
110 if (timeoutMs == null) {
111 wait(0);
112 } else if (timeoutMs > 0) {
113 wait(timeoutMs);
114 }
115
116 if (mException != null) {
117 throw new ExecutionException(mException);
118 }
119
120 if (!mResultReceived) {
121 throw new TimeoutException();
122 }
123
124 return mResult;
125 }
这里如果网络有问题就会导致等待超时最终导致binder调用时间过长,调用的app:com.google.android.videos主线程ANR.