谷歌中国开发者社区 (GDG)
  • 主页
  • 博客
    • Android
    • Design
    • GoogleCloud
    • GoogleMaps
    • GooglePlay
    • Web
  • 社区
    • 各地社区
    • 社区历史
    • GDG介绍
    • 社区通知
  • 视频
  • 资源
    • 资源汇总
    • 精选视频
    • 优酷频道

Moving Past GoogleApiClient

2017-11-22adminAndroidNo comments

Posted by Sam Stern, Developer Programs Engineer

The release of version 11.6.0 of the Google Play services SDK moves a number of popular APIs to a new paradigm for accessing Google APIs on Android. We have reworked the APIs to reduce boilerplate, improve UX, and simplify authentication and authorization.

The primary change in this release is the introduction of new Task
and GoogleApi
based APIs to replace the GoogleApiClient access pattern.

The following APIs are newly updated to eliminate the use of
GoogleApiClient:

  • Auth – updated the Google Sign In and Credentials APIs.
  • Drive – updated the Drive and Drive Resource APIs.
  • Fitness – updated the Ble, Config, Goals, History,
    Recording, Sensors, and Sessions APIs.
  • Games – updated the Achievements, Events, Games, Games
    Metadata, Invitations, Leaderboards, Notifications, Player Stats, Players,
    Realtime Multiplayer, Snapshots, Turn Based Multiplayer, and Videos APIs.
  • Nearby – updated the Connections and Messages
    APIs.

These APIs join others that made the switch in previous releases, such as the
Awareness, Cast, Places, Location, and Wallet APIs.

The Past: Using GoogleApiClient

Here is a simple Activity that demonstrates how one would access the Google
Drive API using GoogleApiClient using a previous version of the
Play services SDK:

public class MyActivity extends AppCompatActivity implements
        GoogleApiClient.OnConnectionFailedListener,
        GoogleApiClient.ConnectionCallbacks {

    private static final int RC_SIGN_IN = 9001;

    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        GoogleSignInOptions options =
               new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestScopes(Drive.SCOPE_FILE)
                        .build();

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addConnectionCallbacks(this)
                .addApi(Auth.GOOGLE_SIGN_IN_API, options)
                .addApi(Drive.API)
                .build();
    }

    // ...
    // Not shown: code to handle sign in flow
    // ...

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        // GoogleApiClient connection failed, most API calls will not work...
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        // GoogleApiClient is connected, API calls should succeed...
    }

    @Override
    public void onConnectionSuspended(int i) {
        // ...
    }

    private void createDriveFile() {
        // If this method is called before "onConnected" then the app will crash,
        // so the developer has to manage multiple callbacks to make this simple
        // Drive API call.
        Drive.DriveApi.newDriveContents(mGoogleApiClient)
            .setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
                // ...
            });
    }
}

The code is dominated by the concept of a connection, despite using the
simplified “automanage” feature. A GoogleApiClient is only
connected when all APIs are available and the user has signed in (when APIs
require it).

This model has a number of pitfalls:

  • Any connection failure prevents use of any of the requested APIs, but using
    multiple GoogleApiClient objects is unwieldy.
  • The concept of a “connection” is inappropriately overloaded. Connection
    failures can be result from Google Play services being missing or from
    authentication issues.
  • The developer has to track the connection state, because making some calls
    before onConnected is called will result in a crash.
  • Making a simple API call can mean waiting for two callbacks. One to wait
    until the GoogleApiClient is connected and another for the API call
    itself.

The Future: Using GoogleApi

Over the years the need to replace GoogleApiClient became apparent,
so we set out to completely abstract the “connection” process and make it easier
to access individual Google APIs without boilerplate.

Rather than tacking multiple APIs onto a single API client, each API now has a
purpose-built client object class that extends GoogleApi. Unlike
with GoogleApiClient there is no performance cost to creating many
client objects. Each of these client objects abstracts the connection logic,
connections are automatically managed by the SDK in a way that maximizes both
speed and efficiency.

Authenticating with GoogleSignInClient

When using GoogleApiClient, authentication was part of the
“connection” flow. Now that you no longer need to manage connections, you
should use the new GoogleSignInClient class to initiate
authentication:

public class MyNewActivity extends AppCompatActivity {

    private static final int RC_SIGN_IN = 9001;

    private GoogleSignInClient mSignInClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        GoogleSignInOptions options =
               new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestScopes(Drive.SCOPE_FILE)
                        .build();

        mSignInClient = GoogleSignIn.getClient(this, options);
    }

    private void signIn() {
        // Launches the sign in flow, the result is returned in onActivityResult
        Intent intent = mSignInClient.getSignInIntent();
        startActivityForResult(intent, RC_SIGN_IN);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = 
                    GoogleSignIn.getSignedInAccountFromIntent(data);
            if (task.isSuccessful()) {
                // Sign in succeeded, proceed with account
                GoogleSignInAccount acct = task.getResult();
            } else {
                // Sign in failed, handle failure and update UI
                // ...
            }
        }
    }
}

Making Authenticated API Calls

Making API calls to authenticated APIs is now much simpler and does not require
waiting for multiple callbacks.

    private void createDriveFile() {
        // Get currently signed in account (or null)
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);

        // Synchronously check for necessary permissions
        if (!GoogleSignIn.hasPermissions(account, Drive.SCOPE_FILE)) {
            // Note: this launches a sign-in flow, however the code to detect
            // the result of the sign-in flow and retry the API call is not
            // shown here.
            GoogleSignIn.requestPermissions(this, RC_DRIVE_PERMS, 
                    account, Drive.SCOPE_FILE);
            return;
        }

        DriveResourceClient client = Drive.getDriveResourceClient(this, account);
        client.createContents()
                .addOnCompleteListener(new OnCompleteListener<DriveContents>() {
                    @Override
                    public void onComplete(@NonNull Task<DriveContents> task) {
                        // ...
                    }
                });
    }

Before making the API call we add an inline check to make sure that we have
signed in and that the sign in process granted the scopes we require.

The call to createContents() is simple, but it’s actually taking
care of a lot of complex behavior. If the connection to Play services has not
yet been established, the call is queued until there is a connection. This is in
contrast to the old behavior where calls would fail or crash if made before
connecting.

In general, the new GoogleApi-based APIs have the following
benefits:

  • No connection logic, calls that require a connection are queued until a
    connection is available. Connections are pooled when appropriate and torn down
    when not in use, saving battery and preventing memory leaks.
  • Sign in is completely separated from APIs that consume
    GoogleSignInAccount which makes it easier to use authenticated APIs
    throughout your app.
  • Asynchronous API calls use the new Task API rather than
    PendingResult, which allows for easier management and
    chaining.

These new APIs will improve your development process and enable you to make
better apps.

Next Steps

Ready to get started with the new Google Play services SDK?

  • Use
    GoogleSignInClient to add sign in to your Android app
  • Use the Tasks
    API to control asynchronous operations

Happy building!

code {
font-size: 100%;
}



Source: Moving Past GoogleApiClient

除非特别声明,此文章内容采用知识共享署名 3.0许可,代码示例采用Apache 2.0许可。更多细节请查看我们的服务条款。

Tags: Android

Related Articles

Tips from developers Peak and Soundcloud on how to grow your startup on Google Play

2017-01-19admin

Google Play Billing Library 1.0 released

2017-09-20admin

The Google Assistant can help control your Android media apps

2017-10-10admin

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Recent Posts

  • Introducing the CVPR 2018 On-Device Visual Intelligence Challenge
  • Kubernetes best practices: How and why to build small container images
  • DeepVariant Accuracy Improvements for Genetic Datatypes
  • Congratulations to our US Grow with Google Developer Scholars!
  • Cloud SQL for PostgreSQL now generally available and ready for your production workloads

Recent Comments

  • 鸿维 on Google 帐号登录 API 更新
  • admin on 推出 CVPR 2018 学习图像压缩挑战赛
  • Henry Chen on 推出 CVPR 2018 学习图像压缩挑战赛
  • 王中 on Google 推出的 31 套在线课程
  • Francis Wang on Google 推出的 31 套在线课程

Archives

  • April 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • July 2015
  • June 2015
  • January 1970

Categories

  • Android
  • Design
  • Firebase
  • GoogleCloud
  • GoogleDevFeeds
  • GoogleMaps
  • GooglePlay
  • Google动态
  • iOS
  • Uncategorized
  • VR
  • Web
  • WebMaster
  • 社区
  • 通知

Meta

  • Register
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

最新文章

  • Introducing the CVPR 2018 On-Device Visual Intelligence Challenge
  • Kubernetes best practices: How and why to build small container images
  • DeepVariant Accuracy Improvements for Genetic Datatypes
  • Congratulations to our US Grow with Google Developer Scholars!
  • Cloud SQL for PostgreSQL now generally available and ready for your production workloads
  • Exploring container security: Protecting and defending your Kubernetes Engine network
  • BigQuery arrives in the Tokyo region
  • What’s new in Firebase Authentication?
  • Showcase your innovations at the 2018 China-US Young Makers Competition
  • Protecting WebView with Safe Browsing

最多查看

  • 谷歌招聘软件工程师 (19,918)
  • Google 推出的 31 套在线课程 (18,087)
  • 如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion (14,903)
  • Seti UI 主题: 让你编辑器焕然一新 (11,117)
  • Android Studio 2.0 稳定版 (8,419)
  • Android N 最初预览版:开发者 API 和工具 (7,752)
  • 像 Sublime Text 一样使用 Chrome DevTools (5,611)
  • Google I/O 2016: Android 演讲视频汇总 (5,387)
  • 用 Google Cloud 打造你的私有免费 Git 仓库 (4,896)
  • 面向普通开发者的机器学习应用方案 (4,734)
  • 生还是死?Android 进程优先级详解 (4,709)
  • 面向 Web 开发者的 Sublime Text 插件 (4,002)
  • 适配 Android N 多窗口特性的 5 个要诀 (3,838)
  • 参加 Google I/O Extended,观看 I/O 直播,线下聚会! (3,419)
© 2018 中国谷歌开发者社区 - ChinaGDG