分离活动和GoogleApiClient的关注 [英] Separating the Concerns of Activity and GoogleApiClient
问题描述
像往常一样,有很多的code在我的 LoginActivity
,我真的会preFER分离活动
从谷歌的责任发挥登录担忧。
As usual there is a lot of code in my LoginActivity
and I really would prefer to separate the Activity
responsibilities from the Google Play sign in concerns.
重写此之后Ç几次,在许多不同的应用程序,轻松(和不那么优雅)的解决方案是 LoginActivity
$ C $创建谷歌的API客户端为应用程序
类对象。但是,由于连接状态影响UX流,我从来没有感到高兴使用这种方法。
After rewriting this LoginActivity
code several times, in many different apps, the easy (and not so elegant) solution was create the Google API client as a Application
class object. But, since the connection state affect the UX flow, I never was happy about with this approach.
有没有地方优雅的方式 GoogleApiClient
的活动之外
?
Is there an elegant way of place the GoogleApiClient
outside the Activity
?
推荐答案
有关的不耐烦codeR,下面的执行工作版本可以在<一个发现href="https://github.com/jpventura/google-play-services/tree/wip/Identity_Lessons_Final/UdacityPlus2_1"相对=nofollow> GitHub的。
0. TL;DR
For the impatient coder, a working version of the following implementation can be found on GitHub.
减少我们的问题,只有到的连接的概念的,我们可以认为:
Reducing our problem only to the connection concept, we may consider that:
- 在它有限的状态。
- 它封装了连接客户端。
- 这是(而)是唯一的。
- 在当前状态影响应用程序的行为。
这是一种行为模式允许一个对象来改变它的行为时,其内部状态的变化。该 GoF的设计模式一书描述该如何TCP连接可以被重新present图案(这也是我们的情况下)。
1. State Pattern
This is a behavioral pattern the allow an object to alter its behavior when its internal state changes. The GoF Design Patterns book describes how a TCP connection can be represent by this pattern (which is also our case).
这是一个状态机中的状态应该是单
,而最简单的客场做在爪哇是建立枚举
的国家
如下:
A state from a state machine should be a singleton
, and the easiest away of doing it in Java was to create Enum
named State
as follows:
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) {}
}
在活动
将通过这些方法的连接
抽象类(其中包含的背景下)进行通信连接()
,断开连接()
和撤销()
。目前的状态定义了这些方法的行为:
The Activity
will communicate with the Connection
abstract class (which holds the context) through the methods connect()
, disconnect()
, and revoke()
. The current state defines how these methods will behave:
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);
}
2。代理模式
类 GoogleConnection
从继承连接
和封装 GoogleApiClient
,所以它必须提供 ConnectionCallbacks
和 OnConnectionFailedListener
如下:
2. Proxy Pattern
The class GoogleConnection
inherits from Connection
and encapsulates the GoogleApiClient
, so it must provide both ConnectionCallbacks
and OnConnectionFailedListener
as follows:
@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
要求对这种解释的第二个步骤。
The methods onSignIn()
, onSignUp()
, onSignOut()
, and onRevokeAndSignOut
are required on the second step of this explanation.
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();
}
3。 Singleton模式
因为没有需要反复重现这个类,我们将它作为一个单:
3. Singleton Pattern
Since there is not need to recreate this class repeatedly, we provide it as a singleton:
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();
}
4。可观察到的模式
在连接
类扩展的Java 观测
,那么一个或多个活动,可以通过观察状态变化:
4. Observable Pattern
The Connection
class extends Java Observable
, so one or many activities can observe the state changes:
@Override
protected void onCreate(Bundle bundle) {
mConnection = GoogleConnection.getInstance(this);
mConnection.addObserver(this);
}
@Override
protected void onDestroy() {
mConnection.deleteObserver(this);
}
@Override
protected void onActivityResult(int request, int result, Intent data) {
if (Connection.REQUEST_CODE == request) {
mConnection.onActivityResult(result);
}
}
@Override
public void update(Observable observable, Object data) {
if (observable == mGoogleConnection) {
// UI/UX magic happens here ;-)
}
}
这篇关于分离活动和GoogleApiClient的关注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!