分离活动和GoogleApiClient的关注 [英] Separating the Concerns of Activity and GoogleApiClient

查看:227
本文介绍了分离活动和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:

  1. 在它有限的状态。
  2. 它封装了连接客户端。
  3. 这是(而)是唯一的。
  4. 在当前状态影响应用程序的行为。

这是一种行为模式允许一个对象来改变它的行为时,其内部状态的变化。该 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆