程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1?

开发过程中遇到通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1的问题如何解决?下面主要结合日常开发的经验,给出你关于通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1的解决方法建议,希望对你解决通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1有所启发或帮助;

我正在使用 androIDx.fragment:fragment-tesTing@H_502_2@ 为我的应用编写插桩测试。测试用例之一是检查当 Fragment 停止和恢复时所有底层逻辑的行为是否正确,以模拟应用程序被最小化(主页按钮)并再次返回。这些测试使用 FragmentScenario.movetoState()@H_502_2@。首先,我使用 androIDx.fragment:fragment-tesTing:1.2.5@H_502_2@ 编写了我的测试,并且它们都通过了。但是当我将 androIDx.fragment:fragment-tesTing@H_502_2@ 更新为 1.3.1@H_502_2@ 时,上述测试开始失败。

我已经检查出了什么问题,结果发现在生命周期更改期间再次调用了 Fragment.onCreateVIEw()@H_502_2@,即使它不应该调用(如果返回到 CREATED@H_502_2@ 并返回到 {{1 }}),导致视图“重置”到布局中声明的初始状态。我查了一下,发现了一个错误,描述中提到了“onCreateVIEw() 生命周期方法被调用了两次”https://issuetracker.google.com/issues/143915710(它也在 https://medium.com/androiddevelopers/fragments-rebuilding-the-internals-61913f8bf48e 中提到)。问题是它已经在 Fragment 1.3.0-Alpha08 中修复了,所以它不应该在 1.3.1 中发生。这意味着我的项目配置一定有问题。

这是一个重现问题的示例代码。它表明视图不会保留其文本,也不会保留生命周期更改 RESUMED -> CREATED -> RESUMED 的可见性。手动测试不会重现此问题,只会影响仪器测试。

RESUMED@H_502_2@

class lifecycleBUGFragment : Fragment() {

    lateinit var textVIEw: TextVIEw
    lateinit var editText: EditText
    lateinit var button: button

    overrIDe fun onCreateVIEw(inflater: LayoutInflater,container: VIEwGroup?,savedInstanceState: Bundle?): VIEw? {
        val vIEw =  inflater.inflate(R.layout.fragment_lifecycle_BUG,container,falsE)
        textVIEw = vIEw.findVIEwByID<TextVIEw>(R.ID.textVIEw)
        textVIEw.setonClickListener { textVIEw.text = "I was clicked" }
        editText = vIEw.findVIEwByID<EditText>(R.ID.editText)
        button = vIEw.findVIEwByID<button>(R.ID.button)
        button.setonClickListener { button.visibility = VIEw.GONE }
        return vIEw
    }
}
@H_502_2@

<?xml version="1.0" enCoding="utf-8"?>
<linearLayout xmlns:androID="http://scheR_99_11845@as.androID.com/apk/res/androID"
    xmlns:tools="http://scheR_99_11845@as.androID.com/tools"
    androID:layout_wIDth="match_parent"
    androID:layout_height="match_parent"
    androID:orIEntation="vertical"
    tools:context=".fragmenttesTing.lifecycleBUGFragment">

    <TextVIEw
        androID:ID="@+ID/textVIEw"
        androID:layout_wIDth="wrap_content"
        androID:layout_height="wrap_content"
        androID:text="default text" />

    <EditText
        androID:ID="@+ID/editText"
        androID:layout_wIDth="wrap_content"
        androID:layout_height="wrap_content"
        androID:inputType="text"
        />

    <button
        androID:ID="@+ID/button"
        androID:layout_wIDth="wrap_content"
        androID:layout_height="wrap_content"
        androID:text="click to hIDe me"
        />
</linearLayout>
@H_502_2@

const val TYPED_TEXT = "some example text"
const val DEFAulT_TEXT = "default text"
const val CliCKED_TEXT = "I was clicked"

class lifecycleBUGFragmentTest {

    lateinit var fragmentScenario: FragmentScenario<lifecycleBUGFragment>

    @Before
    fun setUp() {
        fragmentScenario = FragmentScenario.launchInContainer(lifecycleBUGFragment::class.java)
    }

    @Test
    fun whentextVIEwclickedAndFragmentlifecycleStoppedAndResumed_ThentextVIEwTextIsstillChanged() {
        onVIEw(withID(R.ID.textVIEw)).check(matches(withText(DEFAulT_TEXT)))
        onVIEw(withID(R.ID.textVIEw)).perform(click())
        onVIEw(withID(R.ID.textVIEw)).check(matches(withText(CliCKED_TEXT)))
        stopAndResumeFragment()
        onVIEw(withID(R.ID.textVIEw)).check(matches(withText(CliCKED_TEXT)))
    }

    // this test passes,others fail
    @Test
    fun whenEditTextIsEditedAndFragmentlifecycleStoppedAndResumed_ThenEditTextTextIsstillChanged() {
        onVIEw(withID(R.ID.editText)).perform(typeText(TYPED_TEXT))
        stopAndResumeFragment()
        onVIEw(withID(R.ID.editText)).check(matches(withText(TYPED_TEXT)))
    }

    @Test
    fun whenbuttonIsClickedAndFragmentlifecycleStoppedAndResumed_ThenbuttonIsstillNotVisible() {
        onVIEw(withID(R.ID.button)).perform(click())
        onVIEw(withID(R.ID.button)).check(matches(not(isdisplayed())))
        stopAndResumeFragment()
        onVIEw(withID(R.ID.button)).check(matches(not(isdisplayed())))
    }

    private fun stopAndResumeFragment() {
        fragmentScenario.movetoState(lifecycle.State.CREATED)
        fragmentScenario.movetoState(lifecycle.State.RESUMED)
    }
}
@H_502_2@

因为我没有直接声明 dependencIEs { implementation filetree(dir: "libs",include: ["*.jar"]) implementation 'androIDx.appcompat:appcompat:1.2.0' implementation 'androIDx.consTraintlayout:consTraintlayout:2.0.4' implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.31" implementation 'androIDx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.13' androIDTestImplementation 'androIDx.test.ext:junit:1.1.2' androIDTestImplementation 'androIDx.test.espresso:espresso-core:3.3.0' androIDTestImplementation "androIDx.test:runner:1.3.0" androIDTestImplementation "androIDx.test:core:1.3.0" androIDTestImplementation "androIDx.test.ext:junit:1.1.2" androIDTestImplementation "androIDx.test:rules:1.3.0" implementation "androIDx.navigation:navigation-fragment-ktx:2.3.4" implementation "androIDx.navigation:navigation-ui-ktx:2.3.4" androIDTestImplementation "androIDx.navigation:navigation-tesTing:2.3.4" deBUGImplementation "androIDx.fragment:fragment-tesTing:1.3.1" implementation "androIDx.navigation:navigation-compose:1.0.0-Alpha09" // other dependencIEs unrelated to issue skipped for clarity } @H_502_2@,所以它是一个传递依赖,所以我想知道它是否会被解析为小于 8 的 1.3.0-Alpha,因此不包含修复。我添加了依赖约束以确保 1.3.1 得到解决

androIDx.fragment:fragment@H_502_2@

但它没有帮助,所以事实并非如此

我的代码还有什么问题(很可能是 gradle 依赖)?

解决方法

通过强制 Fragment 进入 CREATED 状态,您正在测试它在 detached 设计上确实会破坏其视图层次结构时的行为。

移回 RESUMED(重新附加片段)时,重新创建视图并恢复其状态。注意:视图不会用 savedInstanceState 恢复,片段实际上在内部保存了保存的视图状态。

EditText 确实保存了它的状态,这就是为什么它不会失败,但 TextViews 和 Buttons 没有保存任何东西。

您可以通过将 android:saveEnabled="true" 添加到其 XML 来强制 TextView 保存其文本,但为了可见性,您需要将状态存储在片段字段中(甚至通过 savedInstanceState 保存/恢复它)并使用在 onViewCreated 中。

大佬总结

以上是大佬教程为你收集整理的通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1全部内容,希望文章能够帮你解决通过使用 FragmentScenario 停止和恢复来测试 androidx.fragment 生命周期,onCreateView() 调用两次,但此错误已在 1.3.1所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。