Xamarin Android不再需要调用异步方法

Vah*_*iri 1 c# android asynchronous xamarin

我有一个片段,用于返回从REST API收到的文章列表.async我正在使用REST API await等待它完成.完成后,我将数据(即List<Article>)传递给一个被调用的变量,listofarticles并使用它来创建一个ArrayAdapter.

我在OnCreate这个片段的方法中做了上面的代码,OnCreateView据我所知,它应该在之前运行.

我的代码在一个活动中工作,但不是片段.

问题: 不等待对等待REST方法的调用.

逐行调试时,它是这样的:

  • OnCreate叫做.加工线在那里我称之为awaitable方法(即是为了填补listofarticles),简单地跳到OnCreateView.因此listofarticles为空.

  • OnCreateView被调用和处理.此时程序只会回到它所调用的活动.

  • 我无法再调试它,因为Xamarin Studio认为我已经完成了但是在模拟器之后它只是在所有这些之后开始调用REST方法,因为内部的数据listofarticles是无用的,因为我现在无法将它传递给Adapter.

为什么会发生这种情况以及如何解决?

public class LatestNewsFragment : Android.Support.V4.App.Fragment, ListView.IOnItemClickListener
{
    private Context globalContext = null;
    private List<Article> listofarticles;
    private ArrayAdapter<Article> listAdapter;

    public LatestNewsFragment()
    {
        this.RetainInstance = true;
    }

    public async override void OnCreate (Bundle savedInstanceState)
    {
        base.OnCreate (savedInstanceState);
        globalContext = this.Context;

        //Create a progress dialog for loading
        ProgressDialog pr = new ProgressDialog(globalContext);
        pr.SetMessage("Loading data");
        pr.SetCancelable(false);

        var rest = new RestAccess();
        pr.Show();
        //Download the data from the REST API
        listofarticles = await rest.ListArticlesAsync ("SomeSource");
        pr.Hide();
        Console.WriteLine (listofarticles.Capacity);

        listAdapter = new ArrayAdapter<Article>(globalContext, Android.Resource.Layout.SimpleListItem1, listofarticles);
    }

    public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate(Resource.Layout.Fragment_LatestNews, null);
        ListView listView = view.FindViewById<ListView>(Resource.Id.list_latestnews);
        listView.Adapter = listAdapter;
        listView.OnItemClickListener = this;
        return view;
    }
}
Run Code Online (Sandbox Code Playgroud)

Flo*_*der 7

正如在这个答案/sf/answers/2285976521/中所解释的那样,在片段中执行OnCreate()相关视图并不是一个好主意.

此外,如果您将OnCreate()设置为异步方法,则会在await行之后立即调用其他片段生命周期事件(请参阅http://developer.android.com/guide/components/fragments.html).现在的问题是你不能依赖await之后的代码运行的顺序,如果你的REST API很慢OnCreateView()可能已经完成了你会很好,但是如果API很快OnCreateView()可能仍然会运行你的应用程序将崩溃.

为什么不使用OnActivityCreated()来加载数据?您可以确定所有内容都在该内容中初始化,例如:

private ListView listView;

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    var view = inflater.Inflate(Resource.Layout.Fragment_LatestNews, null);

    listView = view.FindViewById<ListView>(Resource.Id.list_latestnews);    
    listView.OnItemClickListener = this;

    return view;
}

public override async void OnActivityCreated(Bundle savedInstanceState)
{
    base.OnActivityCreated(savedInstanceState);

    //Download the data from the REST API
    var rest = new RestAccess();    
    var listofarticles = await rest.ListArticlesAsync("SomeSource");

    listView.Adapter = new ArrayAdapter<Article>(Context, Android.Resource.Layout.SimpleListItem1, listofarticles);
}
Run Code Online (Sandbox Code Playgroud)