代码分析
1.代码路径
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/core/java/android/os/IBinder.java
代码参考:Android Q
2.ActivityThread
public static void main(String[] args) {
······
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
······
}
private void attach(boolean system, long startSeq) {
······
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
······
}
1.final ApplicationThread mAppThread = new ApplicationThread();
2.private class ApplicationThread extends IApplicationThread.Stub
3.ActivityManagerService.java
public final void attachApplication(IApplicationThread thread, long startSeq) {
······
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
······
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
······
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
new HostingRecord("link fail", processName));
return false;
}
······
}
1.重点在于thread.asBinder().linkToDeath(adr, 0)的使用
2.如果thread被kill了,就会马上调用adr对象中的binderDied方法
4.ActivityManagerService.AppDeathRecipient
private final class AppDeathRecipient implements IBinder.DeathRecipient {
ProcessRecord mApp = null;
final int mPid;
final IApplicationThread mAppThread;
AppDeathRecipient(ProcessRecord app, int pid,
IApplicationThread thread) {
//if (DEBUG_ALL)
Slog.v(
TAG, "New death recipient " + this
+ " for thread " + thread.asBinder()
+ ", pid:" + pid + ",mApp:" + mApp);
mApp = app;
mPid = pid;
mAppThread = thread;
}
@Override
public void binderDied() {
//if (DEBUG_ALL)
Slog.v(
TAG, "Death received in " + this
+ " for thread " + mAppThread.asBinder()
+ ", mPid:" + mPid + ",mApp:" + mApp);
synchronized(ActivityManagerService.this) {
appDiedLocked(mApp, mPid, mAppThread, true);
}
}
}
5.理论支持IBinder
public interface IBinder {
·······
/**
* Interface for receiving a callback when the process hosting an IBinder
* has gone away.
*
* @see #linkToDeath
*/
public interface DeathRecipient {
public void binderDied();
}
/**
* Register the recipient for a notification if this binder
* goes away. If this binder object unexpectedly goes away
* (typically because its hosting process has been killed),
* then the given {@link DeathRecipient}'s
* {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
* will be called.
*
* <p>You will only receive death notifications for remote binders,
* as local binders by definition can't die without you dying as well.
*
* @throws RemoteException if the target IBinder's
* process has already died.
*
* @see #unlinkToDeath
*/
public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
throws RemoteException;
/**
* Remove a previously registered death notification.
* The recipient will no longer be called if this object
* dies.
*
* @return {@code true} if the <var>recipient</var> is successfully
* unlinked, assuring you that its
* {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
* will not be called; {@code false} if the target IBinder has already
* died, meaning the method has been (or soon will be) called.
*
* @throws java.util.NoSuchElementException if the given
* <var>recipient</var> has not been registered with the IBinder, and
* the IBinder is still alive. Note that if the <var>recipient</var>
* was never registered, but the IBinder has already died, then this
* exception will <em>not</em> be thrown, and you will receive a false
* return value instead.
*/
public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
}
总结
对于通过跨进程通信的apk,不管是客户端还是服务端,都可以进行此方法来监听耦合的进程是否异常
参考学习
https://blog.csdn.net/qq_31429205/article/details/104175356
https://www.jianshu.com/p/1180886b3ff3
补充
AMS有封装监听Process运行情况并对外开放了一个接口,供系统进程调用查看各种进程的运行情况,具体如下:
一、监听
try {
IActivityManager am = ActivityManagerNative.getDefault();//ActivityManager.getService()
am.registerProcessObserver(mProcessObserver);
} catch (Exception e) {
e.printStackTrace();
}
二、回调
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
@Override
public void onForegroundActivitiesChanged(int pid, final int uid,
boolean foregroundActivities) {
}
@Override
public void onForegroundServicesChanged(int pid, int uid, int foregroundServiceTypes){
}
public void onProcessStateChanged(int pid, int uid, int procState) {
}
@Override
public void onProcessDied(final int pid, final int uid) {
}
};
三、注意
IProcessObserver是oneway的binder
oneway interface IProcessObserver {
void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
void onForegroundServicesChanged(int pid, int uid, int serviceTypes);
void onProcessDied(int pid, int uid);
}
四、原理分析
1.ActivityManagerService
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
synchronized (this) {
mProcessObservers.register(observer);
}
}
@Override
public void unregisterProcessObserver(IProcessObserver observer) {
synchronized (this) {
mProcessObservers.unregister(observer);
}
}
2.RemoteCallbackList
public boolean register(E callback) {
return register(callback, null);
}
public boolean register(E callback, Object cookie) {
synchronized (mCallbacks) {
if (mKilled) {
return false;
}
// Flag unusual case that could be caused by a leak. b/36778087
logExcessiveCallbacks();
IBinder binder = callback.asBinder();
try {
Callback cb = new Callback(callback, cookie);
binder.linkToDeath(cb, 0);
mCallbacks.put(binder, cb);
return true;
} catch (RemoteException e) {
return false;
}
}
}
关键点:binder.linkToDeath(cb, 0)。这里进行了linkToDeath,在进程挂了后,会调用cb.binderDied
public boolean unregister(E callback) {
synchronized (mCallbacks) {
Callback cb = mCallbacks.remove(callback.asBinder());
if (cb != null) {
cb.mCallback.asBinder().unlinkToDeath(cb, 0);
return true;
}
return false;
}
}
网友评论