【问题标题】:Why does MVVM Light's NavigateTo create new activities instead of reusing them?为什么 MVVM Light 的 NavigateTo 创建新活动而不是重用它们?
【发布时间】:2017-04-08 13:42:22
【问题描述】:

我从这里 mvvmlight.net 开始关注 Android Xamarin 示例。 这两个活动都扩展了 ActivityBase。当我使用正确的键调用 _nav.NavigateTo 时,会打开另一个活动,但每次都会调用 OnCreate,并且 savedInstanceState 始终为空。 OnDestroy() 和 OnSaveInstanceState() 永远不会被调用。似乎 NavigateTo 创建了一个新活动而不破坏最后一个活动。它是否正确?

查看 Android Activity 生命周期时,OnCreate 应该只被调用一次。我怎样才能恢复其他活动而不是每次都重新创建它?

登录活动:

[Activity(Label = "Login", MainLauncher = true, Icon = null)]
public class LoginActivity : ActivityBase
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.LoginLayout);

        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        var nav = new NavigationService();

        nav.Configure(Constants.Keys.Main, typeof(MainActivity));
        nav.Configure(Constants.Keys.Login, typeof(LoginActivity));
        nav.Configure(Constants.Keys.Live, typeof(LiveActivity));
        ...

        SimpleIoc.Default.Register<INavigationService>(() => nav);

LoginLayout.axml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="5dp">
... some buttons etc
</LinearLayout>

主活动:

public class MainActivity : ActivityBase
{
    private INavigationService _nav;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);
        _nav = ServiceLocator.Current.GetInstance<INavigationService>();
    }

    private void Settings_Click(object sender, EventArgs e)
    {
        _nav.NavigateTo(Constants.Keys.Settings, null);
    }

main.axml:

            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:local="http://schemas.android.com/apk/res-auto"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/MainLayout">
          <include
              android:id="@+id/toolbar"
              layout="@layout/toolbar" />
          <LinearLayout
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:id="@+id/main_content"
              android:layout_below="@id/toolbar">
            <Button
                android:text="Live"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/buttonLive"
                android:layout_marginTop="20dp"/>
            <Button
                android:text="Alerts"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/buttonAlerts" />
            <Button
                android:text="Settings"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/buttonSettings" />
          </LinearLayout>
        </RelativeLayout>

【问题讨论】:

    标签: android mvvm xamarin mvvm-light light


    【解决方案1】:

    在每个启动活动意图上创建一个新活动是默认的 Android 行为,这与 MVVMLight 没有任何关系。 如果您想重用相同的活动,可以通过配置活动启动意图来实现。看看Android documentation

    对于 MVVMLight,Android 上默认的 NavigationService.NavigateTo(string pageKey, object parameter) 实现似乎不允许自定义启动意图。

    如果您想实现它,您将必须重新实现自己的 INavigationService 支持,以使用 intent.AddFlags(ActivityFlags.ClearTop) 将标志添加到您的意图中。

    【讨论】:

    • 那么是GC收集的旧活动吗?据我所知, OnDestroy() 从未被调用过。我应该如何清理它们?
    • 我对 MVVMLight 不是很熟悉...我希望它不会保留对活动的引用以允许收集它们。然后,根据内存压力,本机 GC 何时收集它们并不是真正可预测的。出于开发目的,您可以强制 Android 在您离开活动后立即销毁活动(在开发人员设置中,Nexus 5X 中的“不要保留活动”)
    猜你喜欢
    • 2021-04-22
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2016-07-24
    • 2013-01-02
    • 2015-04-27
    • 2023-01-24
    相关资源
    最近更新 更多