/** * Change the root component measuring it on a background thread before updating the UI. * If this {@link LithoView} doesn't have a ComponentTree initialized, the root will be * computed synchronously. */ public void setComponentAsync(Component component) { if (mComponentTree == null) { setComponentTree(ComponentTree.create(getComponentContext(), component).build()); } else { mComponentTree.setRootAsync(component); } }
root3.testId = 2; componentTree.setRootAsync(root2);
root3.testId = 2; componentTree.setRootAsync(root2);
root2.unlockWaitingOnCreateLayout = unlockWaitingOnCreateLayout; componentTree.setRootAsync(root2);
@Test public void testSetRootAsyncFollowedByNonCompatibleMeasureComputesSyncLayout() { ComponentTree componentTree = ComponentTree.create(mContext, mComponent).build(); componentTree.setLithoView(new LithoView(mContext)); componentTree.measure(mWidthSpec, mHeightSpec, new int[2], false); componentTree.attach(); Component newComponent = TestDrawableComponent.create(mContext).color(1234).build(); componentTree.setRootAsync(newComponent); componentTree.measure(mWidthSpec2, mHeightSpec2, new int[2], false); assertThat(componentTree.getRoot()).isEqualTo(newComponent); assertThat(componentTree.hasCompatibleLayout(mWidthSpec2, mHeightSpec2)).isTrue(); assertThat(componentTree.getMainThreadLayoutState().isForComponentId(newComponent.getId())) .isTrue(); // Clear tasks mLayoutThreadShadowLooper.runToEndOfTasks(); }
componentTree.setRootAsync(newComponent);
@Test public void testSetRootAsyncFollowedByMeasureDoesntComputeSyncLayout() { ComponentTree componentTree = ComponentTree.create(mContext, mComponent).build(); componentTree.setLithoView(new LithoView(mContext)); componentTree.measure(mWidthSpec, mHeightSpec, new int[2], false); componentTree.attach(); Component newComponent = TestDrawableComponent.create(mContext).color(1234).build(); componentTree.setRootAsync(newComponent); assertThat(componentTree.getRoot()).isEqualTo(newComponent); componentTree.measure(mWidthSpec, mHeightSpec, new int[2], false); assertThat(componentTree.getMainThreadLayoutState().isForComponentId(mComponent.getId())) .isTrue(); mLayoutThreadShadowLooper.runToEndOfTasks(); assertThat(componentTree.getMainThreadLayoutState().isForComponentId(newComponent.getId())) .isTrue(); }
componentTree.setRootAsync(newComponent);
@Test public void testMeasureWithIncompatibleSetRootAsyncThatFinishes() { ComponentTree componentTree = ComponentTree.create(mContext, mComponent).build(); componentTree.setLithoView(new LithoView(mContext)); int widthSpec1 = SizeSpec.makeSizeSpec(1000, SizeSpec.EXACTLY); int heightSpec1 = SizeSpec.makeSizeSpec(1000, SizeSpec.AT_MOST); int widthSpec2 = SizeSpec.makeSizeSpec(1000, SizeSpec.EXACTLY); int heightSpec2 = SizeSpec.makeSizeSpec(0, SizeSpec.UNSPECIFIED); componentTree.measure(widthSpec2, heightSpec2, new int[2], false); componentTree.attach(); componentTree.measure(widthSpec1, heightSpec1, new int[2], false); Component newComponent = TestDrawableComponent.create(mContext).color(1234).build(); componentTree.setRootAsync(newComponent); runOnBackgroundThreadSync( new Runnable() { @Override public void run() { // "Commit" layout (it will fail since it doesn't have compatible size specs) mLayoutThreadShadowLooper.runToEndOfTasks(); } }); componentTree.measure(widthSpec2, heightSpec2, new int[2], false); assertThat(componentTree.getRoot()).isEqualTo(newComponent); assertThat(componentTree.hasCompatibleLayout(widthSpec2, heightSpec2)).isTrue(); assertThat(componentTree.getMainThreadLayoutState().isForComponentId(newComponent.getId())) .isTrue() .withFailMessage( "The main thread should calculate a new layout synchronously because the async layout will not be used once it completes"); }