Запуск службы в AlertDialog и привязка к ней внешней активности

Прежде всего, я попытался найти это и не увенчался успехом. Если на мой вопрос уже есть ответ, может кто-нибудь указать мне на него? Большое спасибо за то, что помогли мне здесь, посмотрев на это, или даже пролистав это и указав мне в правильном направлении. Я действительно ценю это!

Моя дилемма: у меня есть действие, и в этом действии есть просмотр списка. В списке есть несколько элементов, которые больше всего нуждаются в вызове AlertDialog. AlertDialog вызывает службу, которая говорит: «Эй, вам нужно обновить некоторые данные». Служба прослушивает и успешно выполняет обновление.

Проблема, которая вступает в игру, заключается в том, что моя деятельность не подтверждает службу. Что меня интересует, так это то, что я не совсем понимаю, как работает служба, и можно ли запустить одну и ту же службу более одного раза.

Обратите внимание, что мой пример отчасти связан с идеей из Справочника по сервису для разработчиков Android.

Пример:

    public class MyActivity extends Activity implements IMainActivity 
    {
        ListView _list;

        private RefreshConnector _serviceConnector;

        private boolean _isBound;

        public MyActivity () {}

        public fillList()
            {
                    //this won't trigger within the service
            }

            private void doBindService()
            {
                    // Establish a connection with the service.  We use an explicit
                    // class name because we want a specific service implementation that
                    // we know will be running in our own process (and thus won't be
                    // supporting component replacement by other applications).
                    getApplicationContext().bindService(new Intent(this, UpdateScheduleService.class), _serviceConnector, BIND_AUTO_CREATE);
                    _isBound= true;
            }

            private void doUnbindService()
            {
                    if (_isScheduleBound)
                    {
                            // Detach our existing connection.
                            getApplicationContext().unbindService(_serviceConnector);
                            _isBound= false;
                    }
            }

            @Override
            protected void onDestroy()
            {
                    super.onDestroy();
                    doUnbindService();
            }

            @Override
            public void onCreate(Bundle savedInstanceState)
            {
                    super.onCreate(savedInstanceState);

                    _isBound= false;

                    _list = (ListView) findViewById(R.id.TheList);
                    _list.setOnItemClickListener(new AdapterView.OnItemClickListener()
                    {
                            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id)
                            {
                                    if (view != null)
                                    {
                                            CheckBox selectedFlag = (CheckBox) view.findViewById(R.id.selectedItem);
                                            selectedFlag.setOnClickListener(new View.OnClickListener()
                                            {
                                                    public void onClick(View view)
                                                    {
                                                           doBindService();
                                                           Bundle extras = new Bundle();
                                                           extras.putBoolean(BundleLocations.BUNDLE_ENABLED, ((CheckBox) view).isChecked());
                                                           extras.putLong(BundleLocations.BUNDLE_SCHEDULE_ID, 123); //123 is an example of an id being passed
                                                           extras.putString(BundleLocations.ACTION, BundleLocations.ACTION_SELECTED);
                                                           Intent updateSelection = new Intent("ChangeItems");
                                                           updateSelection.putExtras(extras);
                                                           view.getContext().startService(updateSelection);
                                                    }
                                           });

                                           TextView description = (TextView) view.findViewById(R.id.description);
                                           description.setText(s.getDescription());
                                           description.setOnClickListener(new View.OnClickListener()
                                           {
                                                    public void onClick(View view)
                                                    {
                                                             doBindService();
                                                             ChangeDescriptionDialog dia = new ChangeDescriptionDialog(view.getContext());
                                                             dia.setTitle(view.getContext().getResources().getString(R.string.DESCRIPTION_TITLE));
                                                             dia.setAction(BundleLocations.ACTION_DESCRIPTION);
                                                             dia.setDescription("something new"); //simplified for example...
                                                             dia.create();
                                                             dia.show();
                                                    }
                                           });
                                    }
                            }
                    };
            }

Обновить соединитель:

public class RefreshConnector implements ServiceConnection
{
    private UpdateService service;

    public IMainActivity getActivity()
    {
        return activity;
    }

    public void setActivity(IMainActivity value)
    {
        this.activity = value;
    }

    public UpdateScheduleService getService()
    {
        return service;
    }

    private IMainActivity activity;

    public void onServiceConnected(ComponentName componentName, IBinder iBinder)
    {
        service = ((UpdateService.UpdateBinder)iBinder).getService();

        if(activity != null)
            activity.fillList();
    }

    public void onServiceDisconnected(ComponentName componentName)
    {
        service = null;
    }
}

Служба обновления

public class UpdateService extends Service
{
    final public IBinder binder = new UpdateBinder();

    @Override
    public IBinder onBind(Intent intent)
    {
        return binder;
    }

    public class UpdateBinderextends Binder
    {
        public UpdateService getService()
        {
            return UpdateService .this;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        if (intent == null)
        {
            stopSelf();
            return START_STICKY;
        }

        if(action.equals(BundleLocations.ACTION_SELECTED))
        {
            long id = intent.getExtras().getLong(BundleLocations.BUNDLE_ID);
            boolean enabled = intent.getExtras().getBoolean(BundleLocations.BUNDLE_ENABLED);

            if(id < 0 )
            {
                return START_STICKY;
            }

            String item = intent.getExtras().getString(BundleLocations.BUNDLE_ITEM);

            if (item == null || action.equals("")) return START_STICKY;

            //do some work with saving the description, which it does

            return START_STICKY;
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }
}

DescriptionDialog усечен (конструктор). Кроме того, это расширение класса AlertDialog.Builder. У меня также есть класс, который является общим для всех диалогов, где в основном я храню _context. Так что в данном случае контекст сохраняется в файле super. _context защищен...

public ChangeDescriptionDialog(Context context)
    {
        super(context);

        DialogInterface.OnClickListener onClickListenerPositive = new DialogInterface.OnClickListener()
        {
            public void onClick(DialogInterface dialog, int id)
            {
                //dispatch change
                Intent ChangeItems = new Intent("ChangeItems");
                Bundle extras = new Bundle();
                    extras.putParcelable(BundleLocations.BUNDLE_ITEM, _description);
                extras.putString(BundleLocations.ACTION, _action);
                ChangeItems.putExtras(extras);

                //
                // my question is partly here
                // I start this service...
                //
                // How would my activity see it... right now it doesn't seem that way even though I do the binding before this call
                //
                _context.startService(ChangeItems);
        }
    };

    this.setPositiveButton(context.getResources().getString(R.string.DIALOG_POS), onClickListenerPositive);
}

Опять же, обратите внимание на привязку, которая происходит до появления всплывающего окна. Во-вторых, обратите внимание, что я запускаю службу в привязке. Что я делаю не так или просто не получаю?

Еще раз всем спасибо, Келли.


person KellyTheDev    schedule 15.10.2011    source источник
comment
Что вы хотите сделать после того, как ваш сервис обновит данные?   -  person Noel    schedule 15.10.2011
comment
Привет, Ноэль, я хочу, чтобы действие обновляло список данных.   -  person KellyTheDev    schedule 16.10.2011


Ответы (1)


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

Во-первых, вам, вероятно, следует расширить IntentService вместо Service. Это гарантирует, что ваша служба не будет работать в потоке пользовательского интерфейса. Вы запустите службу через намерение так же, как и сейчас.

Во-вторых, в реализации вашей службы гораздо проще отправить широковещательное сообщение, чтобы указать, что вы закончили, чем пытаться использовать BoundService. Итак, в вашем сервисе вы бы сделали что-то вроде:

Intent intent = new Intent(); // specify the intent filter appropriately here
sendBroadcast(intent);

Затем в своей деятельности вы захотите зарегистрировать BroadcastReciever, который будет уведомлен об этих изменениях. Дополнительные сведения см. в документе BroadcastReceiver.

person Noel    schedule 15.10.2011
comment
Спасибо, что поделились Ноэлем! Попробую и отчитаюсь. - person KellyTheDev; 18.10.2011