Невозможно получить доступ к данным из службы в действии - PullRequest
0 голосов
/ 01 мая 2018

Я создаю приложение Xamarin.Android. У меня есть работающая служба, и я пытаюсь передать данные из этой службы в свою деятельность. Я знаю, что люди расстраиваются из-за слишком большого количества кода, но я не уверен, где моя проблема. Я собираюсь опубликовать то, что я считаю необходимым:

Услуги

[Service]
public class DataService : Service
{

    public List<MyObjects> MyObjectList { get; private set; }
    public IBinder Binder { get; private set; }
    public override IBinder OnBind(Intent intent)
    {
        this.Binder = new DataServiceBinder(this);
        return this.Binder;
    }

    public override void OnCreate()
    {
        base.OnCreate();
        pendingIntent = PendingIntent.GetActivity(this, 0, new Intent(this, typeof(MainActivity)), 0);
        StartForeground(NotificationID, GetNotification("Started Sync"));
        //Do some work here to instantiate and populate the List
    }
}

Переплет услуг

public class DataServiceBinder : Binder
{
    public DataServiceBinder(DataService service)
    {
        Service = service;
    }

    public DataService Service { get; private set; }
}

Сервисное подключение

public class DataServiceConnection : Object, IServiceConnection
    {
        public DataService Service { get; private set; }
        public DataServiceBinder dataServiceBinder;
        public bool IsConnected { get; private set; }

        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            dataServiceBinder = service as DataServiceBinder;
            IsConnected = this.dataServiceBinder != null;

            Service = dataServiceBinder.Service;
            ServiceConnectionChanged?.Invoke(this, true);
        }

        public void OnServiceDisconnected(ComponentName name)
        {
            ServiceConnectionChanged?.Invoke(this, false);
            Service = null;
        }

        public event EventHandler<bool> ServiceConnectionChanged;
    }

Активность

public class MyDataActivity : AppCompatActivity
    {
        private DataServiceConnection DataServiceConnection;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            if (DataServiceConnection == null)
            {
                this.DataServiceConnection = new DataServiceConnection();
            }

            Intent serviceToStart = new Intent(this, typeof(DataService));
            BindService(serviceToStart, this.DataServiceConnection, Bind.AutoCreate);

            SetContentView(Resource.Layout.MyDataLayout);

            var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);
        }

        protected override void OnResume()
        {
            var intent = new Intent(this, typeof(DataService));
            BindService(intent, DataServiceConnection, Bind.AutoCreate);
            base.OnResume();
        }

        protected override void OnPause()
        {
            UnbindService(DataServiceConnection);
            base.OnPause();
        }

В моей деятельности, когда я пытаюсь передать адаптеру список из службы, «Служба» является нулевой, и там я получаю исключение нулевой ссылки. Почему мой сервис обнуляется? Я не связываю свои услуги должным образом? Для записи, их служба запускается в контексте приложения.

1 Ответ

0 голосов
/ 03 мая 2018

Хорошо, я нашел решение. Поскольку подключение к службе асинхронно, я не могу ожидать, что адаптер сможет получать данные синхронно, как показано ниже:

var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);

Вместо этого я изменил свою деятельность так:

public class MyDataActivity : AppCompatActivity
    {
        private DataServiceConnection DataServiceConnection;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            if (DataServiceConnection == null)
            {
                this.DataServiceConnection = new DataServiceConnection();
            }

            Intent serviceToStart = new Intent(this, typeof(DataService));
            BindService(serviceToStart, this.DataServiceConnection, Bind.AutoCreate);
            DataServiceConnection.ServiceConnectionChanged += ServiceConnectionChanged;
            SetContentView(Resource.Layout.MyDataLayout);

        }
        private void ServiceConnectionChanged(object sender, bool isConnected)
        {
            if(DataServiceConnection.Service == null)
            {
                return;
            }
            if(isConnected)
            {
                var adapter = new MyDataAdapter(DataServiceConnection.Service.MyObjectList);
            }
        }
        protected override void OnResume()
        {
            var intent = new Intent(this, typeof(DataService));
            BindService(intent, DataServiceConnection, Bind.AutoCreate);
            base.OnResume();
        }

        protected override void OnPause()
        {
            UnbindService(DataServiceConnection);
            base.OnPause();
        }

Я также изменил свое служебное соединение следующим образом:

public class DataServiceConnection : Object, IServiceConnection
    {
        public DataService Service { get; private set; }
        public MyDataActivity DataActivity;
        public event EventHandler<bool> ServiceConnectionChanged;

        public DataServiceConnection(MyDataActivity myDataActivity)
        {
            DataActivity = myDataActivity;
        }

        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            dataServiceBinder = service as DataServiceBinder;
            Service = dataServiceBinder.Service;
            ServiceConnectionChanged?.Invoke(this, true);
        }

        public void OnServiceDisconnected(ComponentName name)
        {
            ServiceConnectionChanged?.Invoke(this, false);
            Service = null;
        }
    }

Теперь мое решение пытается отправлять данные на адаптер только при подключенном сервисе. Это решение работает для меня, и я надеюсь, что оно поможет кому-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...