简体   繁体   中英

how to use a service in multiple activities?

I'm having a problem writing a service, that should work with multiple activities. I wrote a simple service and a mediator class the makes the bind and can return a service object. this is the simple service class:

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;
    }
}
}

this is the mediator class:

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;
}
}

The client Activity has the following data members:

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

And in onCreate() the following code:

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

problem is that after the onCreate(), the m_SrvConnection is always null .

If you have any other ways to implement this you are more than welcome to share..

Resurrecting the old post as I had the similar question, but there is no clear answer here. One of the ways to address this is like this:

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...
}

Note that "some stuff #1" will run right when onCreate() is called, "some stuff #2" will be executed almost right after that, but what you put in onPostExecute() will be run much later.

The reason for doing it this way and not just putting the code into onServiceConnected() is that the ServiceConnectionBinder can now be put outside of the Activity (in some singleton, or Application for example) and be used by multiple activities without the need for each of them to bind to the service.

Note, it may not be obvious, but things in onPostExecute() may (will) actually be run after all other standard callbacks (like onResume() etc.).

problem is that after the onCreate(), the m_SrvConnection is always null.

Of course. The binding request will not even begin until the main application thread gets control again (ie, you return control to the OS).

You cannot use m_SrvConnection until onServiceConnected() is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM