0

我有一个在用户交互时启动更多自身实例的活动。此活动绑定到维护蓝牙连接的服务。目前这是这样实现的:

@Override
public void onResume()
{
    super.onResume();
    //bind the activity to the service when it is not bound yet.
    if (!this.isBound)
    {
        //Application context, because the Connection shall be kept over configuration change, and the activity will be replaced then.
        Intent serviceIntent = new Intent(this.getApplicationContext(), ConnectionService.class);
        bindService(serviceIntent, this.connection, Context.BIND_AUTO_CREATE);
        this.isBound = true;
    }
    else
    {
        this.connection = (ServiceConnection)getLastNonConfigurationInstance();
    }
    this.visible = true;
}

/**
 * Saves the bound state.
 */
@Override
public void onSaveInstanceState(Bundle outState)
{
    outState.putBoolean("isBound", this.isBound);
}

/**
 * Loads the bound state.
 */
@Override
public void onRestoreInstanceState(Bundle inState)
{
    this.isBound = inState.getBoolean("isBound");
}

/**
 * Called by system, gives the current ServiceConnection to the system to be retrieved again after restart.
 */
@Override
public Object onRetainNonConfigurationInstance() {
    return this.connection;
}

@Override
public void onPause()
{
    //unbind the activity to the service when it is finishing.
    super.onPause();
    this.visible = false;
    if (this.isFinishing() && this.isBound)
    {
        unbindService(this.connection);
        this.isBound = false;
    }
}

现在我的问题是:当我在应用程序运行时更改方向时,一切正常,我按下后退按钮。然后

07-05 12:07:03.039: E/ActivityThread(17850): Activity mm.android.prototype.uilayer.DatapointActivity has leaked ServiceConnection mm.android.prototype.uilayer.DatapointActivity$1@408bcbb8 that was originally bound here  

07-05 12:07:03.039: E/ActivityThread(17850): android.app.ServiceConnectionLeaked: Activity mm.android.prototype.uilayer.DatapointActivity has leaked ServiceConnection mm.android.prototype.uilayer.DatapointActivity$1@408bcbb8 that was originally bound here

写在 Log 上,应用在 unbind 命令的 onPause() 方法中崩溃。我已经在谷歌论坛上阅读了 Dianne Hackborn 关于这件事的帖子,我不能依赖 ServiceConnection,但我没有找到任何解决方案来应对它。你能帮我摆脱这个错误和/或解释为什么我的应用程序会这样吗?

4

1 回答 1

2

我通过将 ServiceConnection 设为静态并在 myActivity 的每个实例中重用它来解决它。我还添加了一个统计实例的静态计数器,如果最后一个实例关闭,则取消绑定。这也解决了配置更改问题:

private boolean isBound = false;

private static int bindCount = 0;

// handles the service connection.
protected static ServiceConnection connection = new ServiceConnection(){
// ...
}

@Override
public void onResume()
{
    super.onResume();
    //bind the activity to the service when it is not bound yet.
    if (!this.isBound)
    {
        if (bindCount == 0) {
            //Application context, because the Connection shall be kept over configuration change, and the activity will be replaced then.
            Intent serviceIntent = new Intent(this.getApplicationContext(), ConnectionService.class);
            bindService(serviceIntent, DatapointActivity.connection, Context.BIND_AUTO_CREATE);
            this.isBound = true;
        }
        bindCount++;
        this.isBound = true;
    }
    this.visible = true;
}

/**
 * Saves the bound state.
 */
@Override
public void onSaveInstanceState(Bundle outState)
{
    outState.putBoolean("isBound", this.isBound);
}

/**
 * Loads the bound state.
 */
@Override
public void onRestoreInstanceState(Bundle inState)
{
    this.isBound = inState.getBoolean("isBound");
}

@Override
public void onPause()
{
    //unbind the activity of the service when it is finishing.
    super.onPause();
    this.visible = false;
    if (this.isFinishing())
    {
        if(bindCount <= 1 && this.isBound )
        {
            unbindService(DatapointActivity.connection);                
        }
        bindCount--;
    }

}
于 2012-07-05T12:51:22.230 回答