http://frameworks/base/core/java/android/os/BinderProxy.java
/**
* Perform a binder transaction on a proxy.
*
* @param code The action to perform. This should
* be a number between {@link #FIRST_CALL_TRANSACTION} and
* {@link #LAST_CALL_TRANSACTION}.
* @param data Marshalled data to send to the target. Must not be null.
* If you are not sending any data, you must create an empty Parcel
* that is given here.
* @param reply Marshalled data to be received from the target. May be
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
*
* @return
* @throws RemoteException
*/
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
boolean warnOnBlocking = mWarnOnBlocking; // Cache it to reduce volatile access.
if (warnOnBlocking && ((flags & FLAG_ONEWAY) == 0)
&& Binder.sWarnOnBlockingOnCurrentThread.get()) {
// For now, avoid spamming the log by disabling after we've logged
// about this interface at least once
mWarnOnBlocking = false;
warnOnBlocking = false;
if (Build.IS_USERDEBUG || Build.IS_ENG) {
// Log this as a WTF on userdebug and eng builds.
Log.wtf(Binder.TAG,
"Outgoing transactions from this process must be FLAG_ONEWAY",
new Throwable());
} else {
Log.w(Binder.TAG,
"Outgoing transactions from this process must be FLAG_ONEWAY",
new Throwable());
}
}
http://frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
try {
t.traceBegin("InitBeforeStartServices");
...
// The system server should never make non-oneway calls
Binder.setWarnOnBlocking(true);
...
}
}
系统不允许调用外部非 oneway 的方法,可能会阻塞系统进程。setWarnOnBlocking方法实际上是影响当前线程,而不是整个进程。当你在特定线程调用Binder.setWarnOnBlocking(true);,之后在该线程中进行的所有Binder调用如果导致阻塞,则会在系统日志中产生警告。