9

我有一个绑定服务。一个活动正在绑定它。它在 Activity 的onStop()方法上取消绑定服务。

问题是,如果 Activity 发生运行时更改(例如,方向更改),则重新创建 Activity。因此,onStop()从 Activity 调用方法,并且 Activity 在该方法中取消绑定 Service,这导致 Service 的破坏(并重新启动它)。

我想防止服务在运行时更改中被破坏,同时在活动不可见时保持服务停止。您可以说尝试startService(),但它使服务在 Activity 不可见时不会停止。如果我添加 stopService Activity 的onStop(),则结果与bindService()and相同unbindService()

AcitivityunbindService()中的 PostDelayingonStop()可以部分解决这个问题,但是延迟时间会是任意的,这会导致 Activity 有一段时间无法获得 GC。我想要一个更清晰的解决方案。

我不想要这样的解决方案,android:configChanges="orientation"因为还有其他运行时更改,这是处理运行时更改的一种不鼓励的方式。

简而言之,我希望服务表现得像一个名为setRetainInstance(true). 但是,片段没有类似bindService(). 我应该怎么办?

4

3 回答 3

9

但是,Fragments 没有 bindService() 之类的东西。

但他们可以bindService()Application上下文中使用:

public class BshFragment extends Fragment implements OnClickListener,
    ServiceConnection {
  private IScript service=null;
  private Button btn=null;

  public View onCreateView(LayoutInflater inflater,
                           ViewGroup container,
                           Bundle savedInstanceState) {
    View result=inflater.inflate(R.layout.main, container, false);

    btn=(Button)result.findViewById(R.id.eval);
    btn.setOnClickListener(this);
    btn.setEnabled(false);

    setRetainInstance(true);

    return(result);
  }

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

    getActivity().getApplicationContext()
                 .bindService(new Intent(getActivity(),
                                         BshService.class), this,
                              Context.BIND_AUTO_CREATE);
  }

  @Override
  public void onDestroy() {
    getActivity().getApplicationContext().unbindService(this);
    disconnect();

    super.onDestroy();
  }

  @Override
  public void onClick(View view) {
    EditText script=(EditText)getView().findViewById(R.id.script);
    String src=script.getText().toString();

    service.executeScript(src);
  }

  @Override
  public void onServiceConnected(ComponentName className, IBinder binder) {
    service=(IScript)binder;
    btn.setEnabled(true);
  }

  @Override
  public void onServiceDisconnected(ComponentName className) {
    disconnect();
  }

  private void disconnect() {
    service=null;
    btn.setEnabled(false);
  }
}

(如本示例项目所示,本书涵盖)

通过使用Application上下文,我们可以将其Context用于绑定和解除绑定。通过保留片段,我们可以避免在配置更改时取消绑定和重新绑定。

就个人而言,我只是尽量避免绑定模式。我是松耦合接口的粉丝,因此我更喜欢通过命令模式和startService().

于 2013-05-22T23:40:41.137 回答
1

在 onCreate 中调用 startService,然后在 onStop 中调用

@Override
protected void onStop()
{
    super.onStop();
    if (!isChangingConfigurations ())
    {
          // call stopService
    }
}
于 2013-05-22T23:50:48.187 回答
0

在运行时更改期间保持唯一绑定服务的另一种方法是在服务类中定义如下方法keepAlive

public void keepAlive(boolean value) {
    if (value) startService(new Intent(getApplicationContext(), getClass()));
    else stopSelf();
}

@Override
public void onRebind(Intent intent) {
    keepAlive(false);
}

@Override
public boolean onUnbind(Intent intent) {
    return true;
}

onRebind()唯一绑定服务状态被重置。

于 2014-03-07T20:22:01.910 回答