PopAsync导致ArgumentOutOfRangeException

时间:2019-06-27 13:24:38

标签: android xamarin.forms navigation

我对Xamarin.Forms很陌生。我在主页上显示了一个非常简单的功能

async public Task BaseAppearing()
    {
        if (UserID == null)
        {
            var page = new LoginPage();
            await App.Navigate(page);
        }
        else
        {
            stopWatch.Restart();
        }
    }

现在登录页面可以正常显示,问题是当我单击登录并尝试弹出导航堆栈时,在登录页面中出现以下错误

  

未处理的异常:

     

System.ArgumentOutOfRangeException:索引超出范围。一定是   非负数且小于集合的大小。参数名称:   索引

应用程序崩溃。

仅在Android(仿真器和真实版)中会发生异常。在UWP中可以正常工作

弹出代码也很简单

public static Task PopNavigation()
    {
        var nav = Current.MainPage.Navigation;
        Task ret;
        try
        {
            ret = nav.PopAsync();
        }
        catch (Exception ex)
        {
            ex.Log();
            ret = Navigate(Current.MainPage);
        }
        return ret;
    }

它不仅会引发错误,而且永远不会到达异常处理程序。

此外,我读到有时导航堆栈会损坏/为空。但是没有,NavigationStack有2个项目。 MainPage和LoginPage,我认为是正确的

所有导航都在同一堆栈上进行,因为我在应用程序中只有1个导航功能,这就是我所需要的导航功能

请告知可以做什么

更新 我尝试按照以下方式更改代码以使用NavigationPage,但没有帮助(同样,我在顶部获得了2个标题栏)

public async static Task Navigate(Page Page)
    {
        //await Current.MainPage.Navigation.PushAsync( Page);
        await Current.MainPage.Navigation.PushAsync( new NavigationPage( Page));
    }

如果这可以帮助某人,这是我的堆栈跟踪

  

在System.Collections.Generic.List`1 [T] .get_Item(System.Int32   索引)[0x00009]在   /Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:180   在   Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.GetFragment   (Xamarin.Forms.Page页面,已删除System.Boolean,System.Boolean   popToRoot)[0x00003]在   D:\ a \ 1 \ s \ Xamarin.Forms.Platform.Android \ AppCompat \ NavigationPageRenderer.cs:865   在   Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.SwitchContentAsync   (Xamarin.Forms.Page页面,System.Boolean动画,System.Boolean   删除,System.Boolean popToRoot)[0x0001a]在   D:\ a \ 1 \ s \ Xamarin.Forms.Platform.Android \ AppCompat \ NavigationPageRenderer.cs:768   在   Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnPopViewAsync   (Xamarin.Forms.Page页面,System.Boolean动画)在[0x00017]中   D:\ a \ 1 \ s \ Xamarin.Forms.Platform.Android \ AppCompat \ NavigationPageRenderer.cs:592   在   Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.PopViewAsync   (Xamarin.Forms.Page页面,System.Boolean动画)在[0x00000]中   D:\ a \ 1 \ s \ Xamarin.Forms.Platform.Android \ AppCompat \ NavigationPageRenderer.cs:154   在   Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnPopped   (System.Object发送者,   Xamarin.Forms.Internals.NavigationRequestedEventArgs e)[0x00000]在   D:\ a \ 1 \ s \ Xamarin.Forms.Platform.Android \ AppCompat \ NavigationPageRenderer.cs:573   在   Xamarin.Forms.NavigationPage + d__69.MoveNext   ()[0x0004c]在D:\ a \ 1 \ s \ Xamarin.Forms.Core \ NavigationPage.cs:297中   ---从上一个引发异常的位置开始的堆栈跟踪-   Xamarin.Forms.NavigationPage + d__68.MoveNext()   D:\ a \ 1 \ s \ Xamarin.Forms.Core \ NavigationPage.cs:280中的[0x0004c]   ---从Xamarin.Forms.NavigationPage + d__45.MoveNext抛出异常的先前位置开始的堆栈跟踪结束   ()[0x000cb]在D:\ a \ 1 \ s \ Xamarin.Forms.Core \ NavigationPage.cs:168中   ---从上一个引发异常的位置开始的堆栈跟踪---位于Qleeg.LoginPage + d__2.MoveNext()   D:\ Projects \ Qleeg \ Qleeg \ Qleeg \ Views \ LoginPage.xaml.cs:70中的[0x003f8]   ---从先前引发异常的位置开始的堆栈跟踪---(包装器动态方法)   System.Object.30(intptr,intptr)位于(包装器本机到托管)   System.Object.30(intptr,intptr)

我在做什么错了?

更新2

这是应用程序的构造函数

public App()
    {
        InitializeComponent();

        AppDomain.CurrentDomain.UnhandledException += (sender, args) => OnError(sender, args.ExceptionObject as Exception);
        TaskScheduler.UnobservedTaskException += (sender, args) => OnError(sender, args.Exception);
        MainPage = new NavigationPage(new MainPage());
   ......
}

这是我的导航代码

从MainPage到LoginPage

async public static Task BaseAppearing(this ContentPage Input)
{
    if (App.Current.UserID == null)
    {
        var page = new LoginPage();
        await Input.Navigation.PushAsync(page);
    }
    else
    {
        App.Current.stopWatch.Restart();
    }
}

然后返回

lblMessage.Text = "Welcome!";
lblMessage.TextColor = Color.Green;
Functions.WriteLog("Login", "pre nav pop");
//await App.PopNavigation();// App.Current.MainPage.Navigation.PopAsync();
await Navigation.PopAsync();//THIS IS LINE 70

更新3

我将MainPage代码切换为此:

    async private void MainPage_Appearing(object sender, EventArgs e)
    {
        if (App.Current.UserID == null) {await App.Current.MainPage.Navigation.PushAsync(new NavigationPage(new LoginPage ())); }
    }

现在,错误消失了(尽管我对此感到困惑),但是Navigaion.PopAsync()却什么也没做。没有错误,也没有导航。

此外,LoginPage现在会在顶部显示2个标题行/标题。

3 个答案:

答案 0 :(得分:1)

添加

Task.Delay(300)

在浏览页面之前。

我知道这是黑客 但是,如果您想在出现时导航到其他页面,则必须这样做。 导致整个页面尚未初始化。 因此我们必须等待几秒钟才能在导航堆栈中正确初始化页面

答案 1 :(得分:1)

如果您在Android上的dataFlowStatus = DataFlowJavaOperator( task_id='dataflowlabelstatus', jar=jar_pathr, gcp_conn_id='google_cloud_default', options={ 'project': project_id, 'region': gcp_region, 'usePublicIps': ip_condition, 'stagingLocation': staging_location, 'tempLocation': staging_location, 'subnetwork': gcp_sub_network, 'RTMaxDate': "{{ task_instance.xcom_pull(task_ids='validateDate', key='job_last_fetch_date') }}", 'oracleJDBCSource': oracle_connection_url, 'oracleUserName': rm_username, 'oraclePassword': rm_password, 'postgreUserName_RT': receipt_username, 'postgrePassword_RT': receipt_password, 'postgresDatabaseName_RT': receipt_schema, 'postgreUserName_Label': label_username, 'postgrePassword_Label': label_password, 'postgresDatabaseName_Label': label_schema, 'cloudSqlInstance_RT': receipt_cloud_instance, 'cloudSqlInstance_Label': label_cloud_instance, 'autoscalingAlgorithm': 'BASIC', 'maxNumWorkers': '50' }, dag=dag ) 中推入一个页面,则该页面将无法正确初始化,随后对OnAppearing的调用或仅按工具栏中的返回按钮将导致此错误。要绕过,您必须引入延迟,以便可以首先正确初始化主页。

PopAsync

答案 2 :(得分:0)

要将NavigationPage添加到您的根页面:

public App ()
{
  MainPage = new NavigationPage (new Page1Xaml ());
}

要简单地推送页面:

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PushAsync (new Page2Xaml ());
}

弹出页面:

async void OnPreviousPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PopAsync ();
}

要弹出到根页面:

async void OnRootPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PopToRootAsync ();
}

使用上面列出的代码在xamarin.forms中推送和弹出页面。我不明白您项目中的await App.Navigate(page);是什么。

  

我尝试将代码更改为使用NavigationPage,如下所示,但是   无济于事(我在顶部也有两个标题栏)

您的项目中只需要一个NavigationPage实例。不要像这样推送到新的NavigationPage:

await Current.MainPage.Navigation.PushAsync( new NavigationPage( Page));

只需将页面推送到您想要的页面即可:

 await Current.MainPage.Navigation.PushAsync(Page);