Token

首先各种Token都是Binder对象,Binder对象一般有两种用途,一是方便进程之间的跨进程通信,另一种是用于跨进程标识同一对象;token更重要的作用是后者;

AMS Token:
在AMS端创建一个Activity时会创建一个ActivityRecord作为该Activity的映像,其中会新建一个IApplicationToken.Stub类型的appToken,它向WMS提供了如下方法用来通知AMS关于window的消息:(以下简称AMS token)

(1)AMS Token创建:
第一次启动Activity,在AMS端创建ActivityRecord时会new一个token放在ActivityRecord中作为成员变量;

 class ActivityStarter {
        private int startActivity(.....) {
        	...
            ActivityRecord r = new ActivityRecord(mService,...);
        }
    }
    
    //创建ActivityRecord的时候还会new一个apptoken,这个token在AMS端和Client端都是Acitvity的唯一标识
 	ActivityRecord(...) {
        appToken = new Token(this);
   		...
	}

(2)AMS调用WMS的addAppToken接口,给WMS添加新建Activity的映像;
AMS端:把AppToken传递给WMS:

//className = ActivityStack
 final void startActivityLocked(ActivityRecord r, ...) {
         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, ...);
 }

WMS端:
WMS中有一个Map

class WindowManagerService {
	//这个map的键就是AppToken
	HashMap<IBinder,AppWindowToken> mTokenMap;
	public void addAppToken(IApplicationToken token, ...) {
        	...... 
        	synchronized(mWindowMap) {
            	AppWindowToken atoken = findAppWindowToken(token.asBinder());
            	if (atoken != null) {
                	return;
            	}
            	//一个AppToken对应一个AppWindowToken
            	//需要为没有AppWindowToken的Activity需要新建AppWindowToken
            	atoken = new AppWindowToken(this, token, voiceInteraction);
        	    mTokenMap.put(token.asBinder(), atoken);
    	   }
	}
}

(3)将token传递到Client进程:
AMS端:用ApplicationThread将binder传递给Client进程:

final boolean realStartActivityLocked(ActivityRecord r, ...) {
     	app.thread.scheduleLaunchActivity(r.appToken, ...);
}

Client端:建立一个Activity在Client端的映像:

public final void scheduleLaunchActivity(IBinder token, ...) {
        ActivityClientRecord r = new ActivityClientRecord();
        r.token = token;
        ...
        sendMessage(H.LAUNCH_ACTIVITY, r);
}

(4)添加窗口:
Client端:

public void setView(View view, WindowManager.LayoutParams attrs, ...) {
		...
		//mWindow是W类型,提供了Client端向WMS开放的服务;
		//attrs中包含了AMS Token
        res = mWindowSession.addToDisplay(session, mWindow, attrs, ...) ;
}

WMS端:根据AMS Token(可唯一映射到一个Activity)为依附于该Activity的Window建立Window在WMS端的唯一描述符;

final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>();
public int addWindow(Session session, IWindow client, WindowManager.LayoutParams attrs, ...) {
        ......
        boolean addToken = false;
        //可见mTokenMap 的key值为AMS Binder
        WindowToken token = mTokenMap.get(attrs.token);
        ......
        win = new WindowState(this, session, client, token,
                attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
        mWindowMap.put(client.asBinder(), win);
        ....
}

总结:
Activity中的token: 以上这个类的代理对象就是Activity中的token,每个Acvitity都对应这样一个token,并在Activity执行attach时赋值;同时在attach方法中,系统会创建Activity所属的Window;
Window中的token: 当Window对应一个Activity时其中的token就是Activity的token;当Window对应一个Dialog或系统弹框,这时token就为空;
WindowManager.LayoutParams中的token: 当LayoutParams对应的是Activity时token就是AMS token,一个AMS token又会对应一个WindowToken,这个Activity中的所有Window都会共享这一个WindowToken

WMS的Token:
WindowToken和AppWindowToken:父子类关系,WindowToken为父类;
每个Window都对应一个WindowToken,但只有Activity类型的Window才会有AppWindowToken;
AppWindowToken会持有AMS token的引用;
WMS中有一个Map ,其中Key就是AMS token;

附 各个token的描述:

AMS Token:
向WMS提供回调以便窗口发生变化时AMS做出相应的配合

interface IApplicationToken extends IApplicationToken.Stub {   				//(Binder)
 	private final ActivityManagerService mService;
    void windowsDrawn();
    void windowsVisible();
    void windowsGone();
    boolean keyDispatchingTimedOut(String reason);
    long getKeyDispatchingTimeout();
}

WindowToken:

class WindowToken {
   final WindowManagerService service;
   // The actual token.
   final IBinder token;
   final int windowType;
   AppWindowToken appWindowToken;
   // All of the windows associated with this token.
   final WindowList windows = new WindowList();

   WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) 
  
   void removeAllWindows() 
}

AppWindowToken

class AppWindowToken extends WindowToken {
  
}

你可能感兴趣的:(Token)