You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Xamarin.Android中AsyncTaskLoader的C#实现问题

Hey there! I totally get how frustrating it is when you're trying to implement AsyncTaskLoader in Xamarin.Android and can't find solid C# examples online—been there myself. Let me walk you through a complete, working example that covers the basics, plus some key gotchas to watch out for.

Complete C# Example for AsyncTaskLoader in Xamarin.Android

First, let's create the custom loader class. This will handle the background data loading and lifecycle management:

using Android.Content;
using Android.OS;
using System.Net.Http;
using System.Threading.Tasks;

public class DataLoader : AsyncTaskLoader<string>
{
    private string _loadedData;
    private readonly string _apiUrl;

    public DataLoader(Context context, string apiUrl) : base(context)
    {
        _apiUrl = apiUrl;
    }

    // Triggered when the loader starts loading data
    protected override void OnStartLoading()
    {
        // Deliver cached data immediately if we have it
        if (_loadedData != null)
        {
            DeliverResult(_loadedData);
        }

        // Force a reload if data changed or we don't have any yet
        if (TakeContentChanged() || _loadedData == null)
        {
            ForceLoad();
        }
    }

    // This runs on a BACKGROUND THREAD—do all heavy work here (network calls, DB queries, etc.)
    protected override async Task<string> LoadInBackground()
    {
        try
        {
            using (var httpClient = new HttpClient())
            {
                // Replace this with your actual data loading logic
                var response = await httpClient.GetAsync(_apiUrl);
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
        catch (System.Exception ex)
        {
            // Handle errors gracefully—log, return an error message, or null
            return $"Load failed: {ex.Message}";
        }
    }

    // Deliver the loaded data to the UI thread
    public override void DeliverResult(string data)
    {
        _loadedData = data; // Cache the data for future use
        base.DeliverResult(data);
    }

    // Clean up resources when the loader is reset
    protected override void OnReset()
    {
        base.OnReset();
        OnStopLoading();
        _loadedData = null; // Clear cached data
    }
}

Next, let's use this loader in an Activity. You'll need to implement LoaderManager.ILoaderCallbacks<string> to handle loader events:

using Android.App;
using Android.OS;
using Android.Widget;
using Android.Content;

[Activity(Label = "AsyncTaskLoader Demo")]
public class MainActivity : Activity, LoaderManager.ILoaderCallbacks<string>
{
    private const int DataLoaderId = 1001;
    private TextView _resultDisplay;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);

        _resultDisplay = FindViewById<TextView>(Resource.Id.resultTextView);

        // Initialize the loader—this kicks off the loading process
        LoaderManager.InitLoader(DataLoaderId, null, this);
    }

    // Create a new instance of our loader when requested
    public Loader<string> OnCreateLoader(int id, Bundle args)
    {
        // Replace with your actual data source URL or parameters
        string apiEndpoint = "https://jsonplaceholder.typicode.com/todos/1";
        return new DataLoader(this, apiEndpoint);
    }

    // Called when the loader finishes loading data—update UI here!
    public void OnLoadFinished(Loader<string> loader, string data)
    {
        _resultDisplay.Text = data;
    }

    // Called when the loader is reset—clean up any references to old data
    public void OnLoaderReset(Loader<string> loader)
    {
        _resultDisplay.Text = string.Empty;
    }
}

Key Things to Remember

  • UI Thread Safety: Never update UI elements in LoadInBackground()—that method runs on a background thread. All UI updates must happen in OnLoadFinished(), which runs on the main thread.
  • Caching: The example caches loaded data so the loader doesn't re-fetch data on configuration changes (like screen rotation). Use TakeContentChanged() if you need to manually trigger a reload when data changes.
  • Error Handling: Always wrap background operations in try/catch blocks to handle network issues, timeouts, or other exceptions.
  • Lifecycle Benefits: Unlike AsyncTask, loaders are lifecycle-aware—they survive configuration changes and automatically reconnect to your activity/fragment when it's recreated.

内容的提问来源于stack exchange,提问作者David Perez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:10:09