当前位置: 首页 > news >正文

江苏九天建设有限公司网站/推广计划书范文

江苏九天建设有限公司网站,推广计划书范文,千万别去代理记账公司,商城购物网站建设1、WindowContainerTransaction是什么: windowContainerTransaction类的对象是用来存储对windowContainer的修改的一个集合,windowContainer。因为应用侧是无法直接操作windowContainer的,如果应用侧需要修改windowContainer的话&#xff0c…

1、WindowContainerTransaction是什么:

windowContainerTransaction类的对象是用来存储对windowContainer的修改的一个集合,windowContainer。因为应用侧是无法直接操作windowContainer的,如果应用侧需要修改windowContainer的话,需要通过系统侧对windowContainer进行修改,这就涉及了信息的跨进程传输了。所以首先,WindowContainerTransaction类应该是一个磕跨进程传输的类。看到定义:
public final class WindowContainerTransaction implements Parcelable
也证实了这个猜测,其实现了Parcelable接口。然后就是另一个问题,应用通过系统侧修改WindowContainer的话,必定会告诉他修改窗口的什么属性,然后进去这个类找找代码:

 * Sets whether a container or its children should be hidden. When {@code false}, the existing* visibility of the container applies, but when {@code true} the container will be forced* to be hidden.*/
@NonNull
public WindowContainerTransaction setHidden(@NonNull WindowContainerToken container, boolean hidden) {Change chg = getOrCreateChange(container.asBinder());chg.mHidden = hidden;chg.mChangeMask |= Change.CHANGE_HIDDEN;return this;
}

这里可以看到一个设置窗口及其子窗口是否被隐藏的接口,暂时不详细叙述这个方法的实现。这里可以看到修改这个hidden属性是通过一个Change类的对象实现的,Change类是WindowContainerTransaction的内部类,也是实现了Parcelable接口的。而且WindowContainerTransaction类内部也维护了一个包含Change类的Map:
private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
所以可以大概知道,对窗口的修改应该是通过Change类的对象去描述的。

所以目前可以得知WindowContainerTransaction类的作用,他的对象就是应用侧需要对窗口进行的修改的集合。而这个修改,则是通过Change类的对象描述的。
这里通过一个例子来展示下WindowContainerTransaction类的使用(例子引用自博客https://blog.csdn.net/ukynho/article/details/126747771):

public boolean splitPrimaryTask() {......final WindowContainerTransaction wct = new WindowContainerTransaction();// Clear out current windowing mode before reparenting to split task.wct.setWindowingMode(topRunningTask.token, WINDOWING_MODE_UNDEFINED);wct.reparent(topRunningTask.token, mSplits.mPrimary.token, true /* onTop */);mWindowManagerProxy.applySyncTransaction(wct);return true;
}

由上述示例可见这个WindowContainerTransaction类的使用过程为:1.创建一个WindowContainerTransaction对象;2.通过该对象设置你需要修改的属性;3.提交步骤2设置的修改。

2、如何通过WindowContainerTransaction修改窗口属性:

前面已经讲到了WindowContainerTransaction中的setHidden方法,那就继续分析这个方法:
public WindowContainerTransaction setHidden(@NonNull WindowContainerToken container, boolean hidden) {Change chg = getOrCreateChange(container.asBinder());chg.mHidden = hidden;chg.mChangeMask |= Change.CHANGE_HIDDEN;return this;
}

1)、看参数列表:

参数列表第一个是一个WindowContainerToken对象,看一下定义,这个类是什么含义:

public final class WindowContainerToken implements Parcelable {private final IWindowContainerToken mRealToken;/** @hide */public WindowContainerToken(IWindowContainerToken realToken) {mRealToken = realToken;}private WindowContainerToken(Parcel in) {mRealToken = IWindowContainerToken.Stub.asInterface(in.readStrongBinder());}/** @hide */public IBinder asBinder() {return mRealToken.asBinder();}…………………………………
}

从代码上看,这个类也是实现了Parcelable,然后主要是包装了一个IWindowContainerToken类型的对象。因为系统侧的WMS里要管理所有的WindowContainer,那么WMS中该如何区分每一个WindowContainer呢?那就得用唯一的身份标识,即这个IWindowContainerToken,通过这个Token,WMS可以区分不同的WindowContainer,可以简单理解成,我们每个人其实在国家的户籍管理的制度里,就是用一个身份证号进行辨识的,在人口管理的系统中,我们是以身份证号进行区分的,所以身份证号就是这个Token。而WMS也可以通过WindowContainerToken的asBinder()方法访问到对应WindowContainer的方法。
而我们怎么获取到这个WindowContainerToken方法呢?从示例代码中可见:
wct.setWindowingMode(topRunningTask.token, WINDOWING_MODE_UNDEFINED);
可以通过TaskInfo类的token属性获取。看到TaskInfo类的token属性,正是WindowContainerToken类型的对象。那问题又来了,我们的这个token属性是在什么时候进行的赋值操作的呢?
这里得找到Task.java中的fillTaskInfo()方法了,这里可见info.token的赋值:

void fillTaskInfo(TaskInfo info, boolean stripExtras, @Nullable TaskDisplayArea tda) {
………………………………………………………………info.token = mRemoteToken.toWindowContainerToken();
………………………………………………………………}

这里再提一个小小的疑问:mRemoteToken又是什么?看到Task类中没有定义,于是找到其父类中,最后在WindowContainer类中发现如下定义:
首先他实现了一个aidl接口的Stub类,所以其实RemoteToken就是一个binder的server端的抽象类Stub的子类的实现 。他包含了对WindowContainer的引用和WindowContainerToken。

static class RemoteToken extends IWindowContainerToken.Stub {final WeakReference<WindowContainer> mWeakRef;private WindowContainerToken mWindowContainerToken;RemoteToken(WindowContainer container) {mWeakRef = new WeakReference<>(container);}@NullableWindowContainer getContainer() {return mWeakRef.get();}static RemoteToken fromBinder(IBinder binder) {return (RemoteToken) binder;}WindowContainerToken toWindowContainerToken() {if (mWindowContainerToken == null) {mWindowContainerToken = new WindowContainerToken(this);}return mWindowContainerToken;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder(128);sb.append("RemoteToken{");sb.append(Integer.toHexString(System.identityHashCode(this)));sb.append(' ');sb.append(mWeakRef.get());sb.append('}');return sb.toString();}
}

而且在WindowContainerToken中的mRealToken其实就是IWindowContainerToken的对象,也就是说,mRealToken其实就是一个RemoteToken类型的对象,他才是能够通过弱引用真正的指向WindowContainer,同时还包含WindowContainerToken属性。这里再多说一个点,就是WindowContainerToken,只有Task和DisplayArea才会有。

然后第二个参数就是需要设置的属性了,就不再多说;

2)、setHidden方法的实现:

public WindowContainerTransaction setHidden(@NonNull WindowContainerToken container, boolean hidden) {Change chg = getOrCreateChange(container.asBinder());chg.mHidden = hidden;chg.mChangeMask |= Change.CHANGE_HIDDEN;return this;
}

该方法第一步,定义一个Change对象chg,定义后通过getOrCreateChange方法对chg进行赋值。继续查看该方法的实现。

private Change getOrCreateChange(IBinder token) {Change out = mChanges.get(token);if (out == null) {out = new Change();mChanges.put(token, out);}return out;
}

定义一个Change类型的对象out,然后在mChanges中去get一个Change,看下mChanges的定义发现,这是一个ArrayMap。Key是IBinder(这个IBinder的对象就是一个WindowContainerToken的对象,对应唯一的WindowContainer),value是Change。
private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
那就知道了,肯定有有地方会把这个键值对IBinder和Change组成的键值对放进mChanges中。这里如果是刚初始化的WindowContainerTransaction对象,mChanges肯定是空的,所以out == null,则会将token和out放进mChanges,并返回out。注意这里out只是一个默认的Change()方法构造出来的对象。

public static class Change implements Parcelable {public static final int CHANGE_FOCUSABLE = 1;public static final int CHANGE_BOUNDS_TRANSACTION = 1 << 1;public static final int CHANGE_PIP_CALLBACK = 1 << 2;public static final int CHANGE_HIDDEN = 1 << 3;public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5;public static final int CHANGE_FORCE_NO_PIP = 1 << 6;public static final int CHANGE_FORCE_TRANSLUCENT = 1 << 7;public static final int CHANGE_DRAG_RESIZING = 1 << 8;private final Configuration mConfiguration = new Configuration();private boolean mFocusable = true;private boolean mHidden = false;private boolean mIgnoreOrientationRequest = false;private boolean mForceTranslucent = false;private boolean mDragResizing = false;private int mChangeMask = 0;private @ActivityInfo.Config int mConfigSetMask = 0;private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;private Rect mPinnedBounds = null;private SurfaceControl.Transaction mBoundsChangeTransaction = null;private Rect mBoundsChangeSurfaceBounds = null;private int mActivityWindowingMode = -1;private int mWindowingMode = -1;public Change() {}
…………………………………………………………………………………………………
}

所以Out的属性都是默认值,接下来就是对这个Change进行赋值了,我们看的是setHidden方法,所以需要修改Hidden相关的属性。首先是修改chg.mHidden属性,然后修改chg.mChangeMask。
mHidden属性就可以简单的认为是否需要隐藏,下面的mChangeMask就是一个标志位,通过这个属性能得知提交的WindowContainerTransaction进行了哪些属性的修改。
通过Change的初始值可知,mChangeMask = 0;是int类型。CHANGE_HIDDEN = 1<<3; 通过将二者进行异或运算,就能将标志着HIDDEN属性变化的第三位设置为1.

于是,在系统侧应用WindowContainerTransaction的时候,可以看到,这里就会通过mChangeMask属性与标志位的结果进行判断后,再对修改进行应用。

private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) {int effects = applyChanges(tr, c, null /* errorCallbackToken */);final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) {effects = TRANSACT_EFFECTS_LIFECYCLE;}}if ((c.getChangeMask()& WindowContainerTransaction.Change.CHANGE_FORCE_TRANSLUCENT) != 0) {tr.setForceTranslucent(c.getForceTranslucent());effects = TRANSACT_EFFECTS_LIFECYCLE;}
…………………………………………………………………………………………
}

3)reparent方法的实现:

public WindowContainerTransaction reparent(@NonNull WindowContainerToken child,@Nullable WindowContainerToken parent, boolean onTop) {mHierarchyOps.add(HierarchyOp.createForReparent(child.asBinder(),parent == null ? null : parent.asBinder(),onTop));return this;
}

这里不是通过Change保存reparent操作,而是通过mHierarchyOps来保存修改的。看下定义,mHierarchyOps 是一个ArrayList类型的对象。里面存储的是HierarchyOp类型的变量。

private final ArrayList<HierarchyOp> mHierarchyOps = new ArrayList<>();

然后再看到HierarchyOp的构造方法,这里container就是需要重新设置parent的WindowContainer,然后reparent就是新的parent,toTop代表reparent操作后是否需要将子WindowContainer移动到父

WindowContainerToppublic static HierarchyOp createForReparent(@NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT).setContainer(container).setReparentContainer(reparent).setToTop(toTop).build();
}
http://www.jmfq.cn/news/5342905.html

相关文章:

  • 公路建设新闻网站/抖音营销推广怎么做
  • 销售网站建设考核指标/你对网络营销的理解
  • 网站建设能在家工作室/查询网址域名ip地址
  • 企业网站建设珠海/关键词爱站网
  • 网站建设的特征/天津百度爱采购
  • 深圳建筑业网站建设/百度小说风云榜今天
  • 安徽省安徽省建设工程信息网站/公司网站建设代理
  • 网站的建设模式是指什么/游戏广告联盟平台
  • 网站建设公司好做吗/推广策略
  • 无锡集团网站建设/深圳网络公司推广公司
  • 西安网站建设网站建设/十大小说网站排名
  • 网站建设设计师的工作内容/国外引流推广软件
  • 广州网站建设设计公司信息/企业邮箱怎么申请
  • 如何写网站建设方案/百度搜索风云榜小说
  • 山东地产网站建设/本地建站软件有哪些
  • 网站建设与网站优化销售/注册公司
  • 网站建设留言板怎么做/怎么上百度推广产品
  • 网站建设的成本与费用有哪些/百度网站推广排名优化
  • 汽车建设网站/seo秘籍优化课程
  • 武汉三网合一网站建设/app开发工具
  • 网站建设可行性分析报告/图片识别搜索引擎
  • 怎样免费设计网站建设/各种网站
  • 北京网站建设116net/西安seo优化培训
  • 学院评估+++网站建设整改/深圳seo优化推广公司
  • 安徽网站建设合肥网站建设/北京网站建设制作公司
  • 建设服装网站目的/长尾关键词举例
  • 网站建设 技术支持/友情链接的英文
  • 网站建设做的快/百度一下百度网页官
  • 安徽省外经建设集团有限公司网站/业务网站制作
  • 网站建设美国/百度云网页版登录入口