DependencyService.Get <t>没有返回正确的实例

时间:2018-11-17 21:48:49

标签: android xamarin xamarin.forms

我是Xamarin的新手,到目前为止已经尝试了一些初学者教程。
现在,我想构建一些自定义内容,并需要请求当前位置。
为此,我安装了Xamarin.GooglePlayServices.Location以访问FusedLocationProviderClient类。

MainActivity中,我检索了FusedLocationProviderClient

public class MainActivity : FormsAppCompatActivity, ILocationProvider
{
    private FusedLocationProviderClient FusedLocationClient { get; set; }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        // snip

        FusedLocationClient = LocationServices.GetFusedLocationProviderClient(this);
    }
}

ILocationProvider需要实现方法TaskCompletionSource<Model.Location> GetPosition()

public TaskCompletionSource<Model.Location> GetPosition()
{
    // snip

    if (CheckSelfPermission(Manifest.Permission_group.Location) == Permission.Granted)
    {
        FusedLocationClient.LastLocation.AddOnCompleteListener(new OnLocationRequestCompleteListener(this, tcs));
    }

    // snip
}

UI上有一个用于请求当前位置的按钮。
每当用户单击按钮时,我都会通过ILocationProvider获得DependencyService并执行GetPosition方法:

private void GetPositionClicked(object sender, EventArgs e)
{
    var provider = DependencyService.Get<ILocationProvider>();

    if(provider != null)
    {
        var tcs = provider.GetPosition();

        // snip
    }
}

现在的问题是,一旦我尝试在CheckSelfPermission中执行GetPosition()方法,应用程序就会崩溃。
我在GetPosition()中设置了一个断点,并注意到FusedLocationClientnull,尽管在调用null之后显然不是OnCreate

然后我检查了thisOnCreate中的GetPosition,发现它们不是同一实例,这使我得出结论,这里显然有问题。

为解决此问题,我做了以下工作:

public class MainActivity : FormsAppCompatActivity, ILocationProvider
{
    internal static MainActivity Instance { get; private set; }

    private FusedLocationProviderClient FusedLocationClient { get; set; }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        // snip
        Instance = this
        // snip
    }

    // snip
    public TaskCompletionSource<Model.Location> GetPosition()
    {
        if (this != Instance)
        {
            return Instance.GetPosition();
        }

        // snip
    }
}

至少现在可以,但是我无法想象这是要走的路。
到目前为止,我了解到DependencyService似乎尚未获得已创建的实例,而是创建了一个实例(至少创建了一次)。
从共享的MainActivity库中调用.NET Standard中的方法的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

将这些方法从Activity类中移出到独立类中(在Xamarin.Android应用程序(或Xamarin.Android库项目中)内。

假设一个接口如:

public  interface ILocationProvider
{
    Task<Tuple<double, double>> GetPosition();
}

Android实现:

public class Location_Android: Java.Lang.Object, ILocationProvider
{
    private FusedLocationProviderClient FusedLocationClient { get; set; }

    public Location_Android()
    {
        FusedLocationClient = new FusedLocationProviderClient(Application.Context);
    }

    public async Task<Tuple<double, double>> GetPosition()
    {
        var loc =  await FusedLocationClient?.GetLastLocationAsync();
        return new Tuple<double, double>(loc.Latitude, loc.Longitude); 
    }
}