我正在尝试获取有关Xamarin项目的电话服务信息。
当我致电var carrierHelper = DependencyService.Get<ICarrierHelper>();
时,我得到一个System.NullReferenceException: Object reference is not set to an instance of an object.
ICarrierHelper.cs
using System;
namespace MyProject
{
public interface ICarrierHelper
{
string GetPhoneCarrier();
}
}
MyProject.Droid / Helpers / CarrierHelper.cs
using MyProject.Droid;
using Android.Content;
using Android.Telephony;
using Xamarin.Forms;
[assembly: Dependency(typeof(CarrierHelper))]
namespace MyProject.Droid
{
public class CarrierHelper : ICarrierHelper
{
public string GetPhoneCarrier()
{
Console.WriteLine("****************************** MAIN ACTIVITY " + MainActivity.Current.ToString());
TelephonyManager mgr = MainActivity.Current.GetSystemService(Context.TelephonyService) as TelephonyManager;
Console.WriteLine("****************************** TELEPHONY MANAGER " + mgr.ToString());
return mgr.NetworkOperatorName;
//return mgr.SimOperatorName;
}
}
}
我在Droid CarrierHelper.cs中有一个断点,永远不会捕获。因此,我只能假设DependencyService根本找不到我的文件。
更新(添加更多信息和控制台日志。)
MyDevice.cs
using System;
using Plugin.DeviceInfo;
using Xamarin.Forms;
namespace MyProject
{
public class MyDevice
{
private static MyDevice current;
public static MyDevice Current
{
get
{
if (current == null)
current = new MyDevice();
return current;
}
}
public string platform { get; set; }
public string manufacturer { get; set; }
public string model { get; set; }
public string name { get; set; }
public string os_version { get; set; }
public string carrier { get; set; }
public string app_version { get; set; }
public string app_build { get; set; }
public MyDevice()
{
switch (Device.RuntimePlatform)
{
case Device.iOS:
platform = "iOS";
break;
case Device.Android:
platform = "Android";
break;
default:
platform = "UNKNOWN";
break;
}
manufacturer = CrossDeviceInfo.Current.Manufacturer;
model = CrossDeviceInfo.Current.Model;
name = CrossDeviceInfo.Current.DeviceName;
os_version = CrossDeviceInfo.Current.Version;
app_version = CrossDeviceInfo.Current.AppVersion;
app_build = CrossDeviceInfo.Current.AppBuild;
var carrierHelper = DependencyService.Get<ICarrierHelper>();
Console.WriteLine("----- CARRIER HELPER " + carrierHelper);
carrier = DependencyService.Get<ICarrierHelper>().GetPhoneCarrier();
Console.WriteLine("----- CARRIER: " + carrier);
}
}
}
以下控制台日志打印:
-----运营商帮助MyProject.Droid.CarrierHelper
更新(添加堆栈跟踪和信息。)
这是堆栈跟踪:
在/MyProject/Helpers/CarrierHelper.cs:14中的MyProject.Droid.CarrierHelper.GetPhoneCarrier()[0x00001] 在/MyProject.Core/Models/MyDevice.cs:57中的MyProject.MyDevice..ctor()[0x000d2] 在/MyProject.Core/Models/MyDevice.cs中的MyProject.MyDevice.get_Current()[0x0000d]:15 在/MyProject.Core/Services/UserDataStore.cs:197
中的MyProject.UserDataStore + d__16.MoveNext()[0x00057]
UserDataStore.cs
public async Task UpdateLocation(double lat, double lng)
{
try
{
if (!CrossConnectivity.Current.IsConnected)
throw new Exception("Not currently connected to the internet.");
var model = new
{
access_token = $"{Settings.AuthToken}",
latitude = lat,
longitude = lng,
device = MyDevice.Current,
format = "json"
};
var json = JsonConvert.SerializeObject(model);
var location_content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync(users_url + location_url, location_content);
if (!response.IsSuccessStatusCode)
throw new Exception(response.StatusCode.ToString() + " " + response.ReasonPhrase);
}
catch (Exception e)
{
Console.WriteLine("ERROR: " + e.Message); // this is where the stack trace is generated
await LocationDatabase.Connection.SaveLocationAsync(new Location(lat, lng));
await AppEventDatabase.Connection.SaveEventAsync(new AppEvent("location", e.Message, lat, lng));
}
}
这是上面文件中的错误消息:
错误:对象引用未设置为对象的实例。
答案 0 :(得分:0)
您遇到22分的情况。 GetPhoneCarrier()
要求MyDevice.Current
,这是通过MyDevice
的延迟加载构造函数实现的。该构造函数解析ICarrierHelper
并调用GetPhoneCarrier()
,这需要MyDevice.Current
...
我假设该解决方案表明它已经尝试解决该问题,但尚未完成,因此它返回null。
我建议您在MyDevice构造函数中减少操作。避免解决该依赖关系,直到您真正需要它为止。这样,构造函数就可以完成操作,避免了catch 22的问题。
还请注意,延迟加载的方法不是线程安全的。考虑使用Lazy<T>
,它很好地封装了双重检查的线程安全锁定。