与往常一样,我的LoginActivity
中有很多代码,我真的更愿意将Activity
职责与Google Play登录问题分开。
在多次重写此LoginActivity
代码后,在许多不同的应用中,简单(而不是那么优雅)的解决方案是将Google API客户端创建为Application
类对象。但是,由于连接状态会影响用户体验流程,因此我对此方法一直不满意。
是否有一种优雅的方式将GoogleApiClient
置于Activity
之外?
答案 0 :(得分:8)
对于不耐烦的编码器,可以在GitHub上找到以下实现的工作版本。
仅将问题减少到连接概念,我们可能会考虑:
这是一种行为模式,允许对象在其内部状态发生变化时改变其行为。 GoF Design Patterns book描述了这种模式如何表示TCP连接(这也是我们的例子)。
状态机的状态应该是singleton
,在Java中最简单的方法是创建名为Enum
的{{1}},如下所示:
State
public enum State {
CREATED {
void connect(Connection connection) {
connection.onSignUp();
}
},
OPENING {
void connect(Connection connection) {
connection.onSignIn();
}
},
OPENED {
void disconnect(Connection connection) {
connection.onSignOut();
}
void revoke(Connection connection) {
connection.onRevokeAndSignOut();
}
},
CLOSED {
void connect(Connection connection) {
connection.onSignIn();
}
};
void connect(Connection connection) {}
void disconnect(Connection connection) {}
void revoke(Connection connection) {}
}
将通过方法Activity
,Connection
和connect()
与disconnect()
抽象类(包含上下文)进行通信。当前状态定义了这些方法的行为方式:
revoke()
班级public void connect() {
currentState.connect(this);
}
public void disconnect() {
currentState.disconnect(this);
}
public void revoke() {
currentState.revoke(this);
}
private void changeState(State state) {
currentState = state;
setChanged();
notifyObservers(state);
}
继承自GoogleConnection
并封装Connection
,因此必须同时提供GoogleApiClient
和ConnectionCallbacks
:
OnConnectionFailedListener
此解释的第二步需要使用方法@Override
public void onConnected(Bundle connectionHint) {
changeState(State.OPENED);
}
@Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
if (state.equals(State.CLOSED) && result.hasResolution()) {
changeState(State.CREATED);
connectionResult = result;
} else {
connect();
}
}
public void onActivityResult(int resultCode) {
if (resultCode == Activity.RESULT_OK) {
connect();
} else {
changeState(State.CREATED);
}
}
,onSignIn()
,onSignUp()
和onSignOut()
。
onRevokeAndSignOut
由于不需要重复重新创建此类,我们将其作为单例提供:
public void onSignUp() {
try {
Activity activity = activityWeakReference.get();
changeState(State.OPENING);
connectionResult.startResolutionForResult(activity, REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
changeState(State.CREATED);
mGoogleApiClient.connect();
}
}
public void onSignIn() {
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
public void onSignOut() {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
changeState(State.CLOSED);
mGoogleApiClient.connect();
}
public void onRevokeAndSignOut() {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient);
changeState(State.CLOSED);
mGoogleApiClient = mGoogleApiClientBuilder.build();
mGoogleApiClient.connect();
}
public static Connection getInstance(Activity activity) {
if (null == sConnection) {
sConnection = new GoogleConnection(activity);
}
return sConnection;
}
public void onActivityResult(int result) {
if (result == Activity.RESULT_OK) {
changeState(State.CREATED);
} else {
changeState(State.CLOSED);
}
onSignIn();
}
private GoogleConnection(Activity activity) {
activityWeakReference = new WeakReference<>(activity);
googleApiClientBuilder = new GoogleApiClient
.Builder(activity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(new Scope("email"));
googleApiClient = googleApiClientBuilder.build();
currentState = State.CLOSED;
googleApiClient.connect();
}
类扩展了Java Connection
,因此一个或多个活动可以观察状态变化:
Observable