Как использовать сервис в нескольких видах деятельности? - PullRequest
3 голосов
/ 08 июня 2011

У меня проблема с написанием сервиса, который должен работать с несколькими действиями.Я написал простой сервис и класс-посредник, который связывает и может возвращать объект сервиса.это простой класс обслуживания:

public class ServerConnectionService extends Service{

private static final String TAG = "ServerConnectionService";
private final Binder binder=new LocalBinder();

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

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

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

public class LocalBinder extends Binder {
    ServerConnectionService getService() {
        return ServerConnectionService.this;
    }
}
}

это класс посредника:

public class ServiceConnectionBinder{

private ServerConnectionService m_SrvConnection=null;
private ServiceConnection m_OnService;
private boolean m_IsBound;
private Activity m_Client;

public ServiceConnectionBinder(Activity  i_Activity)
{
    m_IsBound = false;
    this.m_Client = i_Activity;
    this.m_OnService=new ServiceConnection() {
        public void onServiceConnected(ComponentName className,IBinder rawBinder) {
                m_SrvConnection=((ServerConnectionService.LocalBinder)rawBinder).getService();
            }

            public void onServiceDisconnected(ComponentName className) {
                m_SrvConnection=null;
            }
        };

    doBindService();
    Log.d("ServiceConnectionBinder", "finished Ctor");
}

private void doBindService() {
    if(!m_IsBound)
    {
        m_Client.bindService(new Intent(m_Client, ServerConnectionService.class), m_OnService, Context.BIND_AUTO_CREATE);
        m_IsBound = true;
    }

    if(m_SrvConnection == null)
    {
        Log.d("ServiceConnectionBinder",".doBindService cannot bind " + ServerConnectionService.class.toString() + " to " + this.toString());
    }
}

public void doUnbindService() {
    if (m_IsBound) {
        // Detach our existing connection.
        m_Client.unbindService(m_OnService);
        m_IsBound = false;
    }
}

public ServerConnectionService getServerConnectionService()
{
    if(m_IsBound)
    {
        Log.d("ServiceConnectionBinder", "getServerConnectionService m_IsBound = " + m_IsBound); 
    }
    return m_SrvConnection;
}
}

Клиентская активность имеет следующие члены данных:

private ServiceConnectionBinder m_SrvcConnectionBinder=null;
private ServerConnectionService m_SrvConnection=null;

Ив onCreate () следующий код:

m_SrvcConnectionBinder = new ServiceConnectionBinder(this);
m_SrvConnection = m_SrvcConnectionBinder.getServerConnectionService();

проблема заключается в том, что после onCreate () значение m_SrvConnection всегда равно нулю .

Если у вас есть другие способыДля реализации этого вы можете поделиться ..

Ответы [ 2 ]

0 голосов
/ 24 марта 2013

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

protected void onCreate(Bundle savedInstanceState){
    //... some stuff #1...

    new AsyncTask<Void, Void, Integer>(){
        protected void onPreExecute() { }
        protected Integer doInBackground(Void... params) {
            while(m_SrvConnection==null);
            return new Integer(1);
        }
        protected void onPostExecute(Integer result) {
             // service is up, m_SrvConnection is set
             // what you wanted to do with the service in onCreate() goes here
        }
     }.execute();

    //...some stuff #2...
}

Обратите внимание, что "некоторые вещи # 1" будут работать правильно, когда вызывается onCreate (), "некоторые вещи # 2" будут выполняться почти сразу после этого, но то, что вы добавили в OnPostExecute (), будет выполнено намного позже.

Причина, по которой вы делаете это таким образом, а не просто помещаете код в onServiceConnected (), заключается в том, что ServiceConnectionBinder теперь может быть помещен за пределы действия (в некоторых синглтонах или в приложении, например) и использоваться несколькими действиями без нужно для каждого из них привязать к сервису.

Обратите внимание, что это может быть неочевидно, но вещи в onPostExecute () могут (будут) фактически выполняться после всех других стандартных обратных вызовов (таких как onResume () и т. Д.).

0 голосов
/ 08 июня 2011

проблема в том, что после onCreate () m_SrvConnection всегда равно нулю.

Конечно.Запрос на связывание не будет даже начинаться , пока основной поток приложения не получит контроль снова (т. Е. Вы вернете управление ОС).

Вы не можете использовать m_SrvConnection, пока не будет вызван onServiceConnected().

...