【问题标题】:ServiceConnection.onServiceConnected() and startService()ServiceConnection.onServiceConnected() 和 startService()
【发布时间】:2012-02-10 03:46:17
【问题描述】:

我有一个非常简单的 Activity:

public class MainActivity extends Activity
{
    private Intent      serviceIntent;
    public  MainService mainService;

    public ServiceConnection sc = new ServiceConnection()
    {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service)
        {
            mainService = ((MainService.MainServiceBinder)service).getService();
            Log.v("xxx", "[MainActivity]: onServiceConnected()");
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0)
        {
            mainService = null;
            Log.v("xxx", "[MainActivity]: onServiceDisconnected()");
        }
    };

    @Override 
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        serviceIntent = new Intent(this, MainService.class);
    }

    @Override
    public void osStart()
    {
        super.onStart();
        // To call onServiceConnected() if the service already started
        bindService(serviceIntent, sc, BIND_DEBUG_UNBIND)
    }

    @Override
    public void onStop()
    {
        unbindService(sc);
        super.onStop();
    }

    // android:onClick procedure for Button in layout/main.xml
    public void doStartStopService(View Sender)
    {
        if(null == mainService)
        {
            startService(serviceIntent);
        }
        else
        {
            stopService(serviceIntent);
        }
    }
}

还有一个非常简单的服务:

public class MainService extends Service implements Runnable
{
    private boolean isInterrupted = false;
    private Thread  thread;

    class MainServiceBinder extends Binder
    {
        MainService getService()
        {
            return MainService.this;
        }
    }

    @Override
    public void onCreate()
    {
        Log.v("xxx", "[MainService]: onCreate()");      
        super.onCreate();
        thread = new Thread(this);
        thread.start();
    }

    // 1.6 only
    @Override
    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        Log.v("xxx", "[MainService]: onStart()");       
    }

    @Override
    public void onDestroy()
    {
        Log.v("xxx", "[MainService]: onDestroy()");     
        if(thread.isAlive())
        {
            isInterrupted = true;
        }               
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        Log.v("xxx", "[MainService]: onBind()");        
        return new MainServiceBinder();
    }

    @Override
    public boolean onUnbind(Intent intent)
    {
        Log.v("xxx", "[MainService]: onUnbind()");      
        return true;
    }

    @Override
    public void run()
    {
        Log.v("xxx", "[MainService]: run() started");

        while(!isInterrupted)
        {
            // ...
        }

        Log.v("xxx", "[MainService]: run() exiting");
    }

}

当我在一个循环中调用 doStartStopService() 时,我得到了下一个日志:

[1] 首先startService():

02-10 07:31:49.775: V/xxx(16306): [MainService]: onCreate()
02-10 07:31:49.975: V/xxx(16306): [MainService]: onBind()
02-10 07:31:50.005: V/xxx(16306): [MainService]: onStart()
02-10 07:31:50.165: V/xxx(16306): [MainActivity]: onServiceConnected()
02-10 07:31:50.175: V/xxx(16306): [MainService]: run() started

[2] 首先stopService():

02-10 07:31:52.205: V/xxx(16306): [MainActivity]: onServiceDisconnected()
02-10 07:31:52.205: V/xxx(16306): [MainService]: onUnbind()
02-10 07:31:52.215: V/xxx(16306): [MainService]: onDestroy()
02-10 07:31:52.235: V/xxx(16306): [MainService]: run() exiting

[3] 第二个 startService() - 没有 onBind() 和没有 onServiceConnected() 调用:

02-10 07:31:54.355: V/xxx(16306): [MainService]: onCreate()
02-10 07:31:54.365: V/xxx(16306): [MainService]: onStart()
02-10 07:31:54.365: V/xxx(16306): [MainService]: run() started

为什么当我第二次调用 startService() 时,函数 onBind() 和 onServiceConnected() 没有被调用?

【问题讨论】:

    标签: android service


    【解决方案1】:

    如果你绑定到服务,服务onBind会调用,所以第二个startService调用,没有绑定到这个服务,你需要再次调用bindService(serviceIntent, sc, BIND_DEBUG_UNBIND)

    【讨论】:

    • 好的,我明白了。所以,我必须在 onServiceDisconnected() 函数中解除绑定并再次绑定我的服务。正如我所看到的,这可以正常工作,但是在 onServiceDisconnected() 函数中绑定和取消绑定服务是否安全?
    • @Vladimir,当然不安全。您是否认为当客户端断开连接时,您会在那时建立新的连接?这是“递归连接”,太有趣了:-)
    【解决方案2】:

    您只需在 onServiceDisconnected() 中取消绑定您的服务。为什么要在代码中取消绑定服务后绑定服务?

    不过,如果您想要同样的方法,只需在 onServiceDisconnected() 中取消绑定您的服务,并通过一个接口通知您的活动您刚刚取消绑定您的服务,一旦您的活动收到通知您已取消绑定您的服务,让它决定是否需要绑定还是不绑定。如果它想再次绑定,就让它做吧。

    【讨论】:

    • 我想在解除绑定后绑定服务以了解该服务是否会再次启动(该活动不是唯一可以启动该服务的活动)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多