AWS Lambda
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

教程:将 AWS Lambda 与 适用于 Android 的 移动软件开发工具包 结合使用

在本教程中,您将创建一个简单的 Android 移动应用程序,该应用程序使用 Amazon Cognito 获取凭证和调用 Lambda 函数。

该移动应用程序从 Amazon Cognito 身份池检索 AWS 凭证,并使用它们通过包含请求数据的事件调用 Lambda 函数。该函数处理请求并向前端返回响应。

先决条件

本教程假设您对基本 Lambda 操作和 Lambda 控制台有一定了解。如果尚不了解,请按照开始使用 AWS Lambda中的说明创建您的第一个 Lambda 函数。

为了遵循本指南中的步骤,您需要命令行终端或外壳,以便运行命令。命令显示在列表中,以提示符 ($) 和当前目录名称(如果有)开头:

~/lambda-project$ this is a command this is output

对于长命令,使用转义字符 (\) 将命令拆分到多行中。

在 Linux 和 macOS 中,可使用您首选的外壳程序和程序包管理器。在 Windows 10 中,您可以 安装 Windows Subsystem for Linux,获取 Ubuntu 和 Bash 与 Windows 集成的版本。

创建执行角色

创建执行角色,向您的函数授予访问 AWS 资源的权限。

创建执行角色

  1. 打开 IAM 控制台中的“角色”页面

  2. 选择 Create role (创建角色)

  3. 创建具有以下属性的角色。

    • 可信任的实体AWS Lambda

    • 权限AWSLambdaBasicExecutionRole

    • 角色名称 (角色名称)lambda-android-role

AWSLambdaBasicExecutionRole 策略具有函数将日志写入 CloudWatch Logs 所需的权限。

创建函数

以下示例使用数据来生成字符串响应。

注意

有关使用其他语言的示例代码,请参阅 示例函数代码

例 index.js

exports.handler = function(event, context, callback) { console.log("Received event: ", event); var data = { "greetings": "Hello, " + event.firstName + " " + event.lastName + "." }; callback(null, data); }

创建函数

  1. 将示例代码复制到名为 index.js 的文件中。

  2. 创建部署程序包。

    $ zip function.zip index.js
  3. 使用 create-function 命令创建 Lambda 函数。

    $ aws lambda create-function --function-name AndroidBackendLambdaFunction \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs8.10 \ --role arn:aws:iam::123456789012:role/lambda-android-role

测试 Lambda 函数。

使用示例事件数据手动调用函数。

测试 Lambda 函数 (AWS CLI)

  1. 将下面的示例事件 JSON 保存到文件 input.txt 中。

    { "firstName": "first-name", "lastName": "last-name" }
  2. 执行下面的 invoke 命令:

    $ aws lambda invoke --function-name AndroidBackendLambdaFunction \ --payload file://file-path/input.txt outputfile.txt

创建 Amazon Cognito 身份池

在这一部分,您将创建一个 Amazon Cognito 身份池。该身份池有两个 IAM 角色。您将更新未经身份验证的用户的 IAM 角色,并授予执行 AndroidBackendLambdaFunction Lambda 函数的权限。

有关 IAM 角色的详细信息,请参阅 IAM 用户指南 中的 IAM 角色。有关 Amazon Cognito 服务的更多信息,请参阅 Amazon Cognito 产品详细信息页面。

创建身份池

  1. 打开 Amazon Cognito 控制台

  2. 新建一个名为 JavaFunctionAndroidEventHandlerPool 的身份池。在按照过程创建身份池前,请注意以下几点:

    • 您创建的身份池必须允许访问未经身份验证的身份,因为我们的示例移动应用程序不要求用户登录。因此,请确保选择 Enable access to unauthenticated identities (启用未经验证的身份的访问权限) 选项。

    • 将以下语句添加到与未经身份验证的身份关联的权限策略。

      { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "arn:aws:lambda:us-east-1:123456789012:function:AndroidBackendLambdaFunction" ] }

      得到的策略应如下所示:

      { "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "mobileanalytics:PutEvents", "cognito-sync:*" ], "Resource":[ "*" ] }, { "Effect":"Allow", "Action":[ "lambda:invokefunction" ], "Resource":[ "arn:aws:lambda:us-east-1:account-id:function:AndroidBackendLambdaFunction" ] } ] }

    有关如何创建身份池的说明,请登录 Amazon Cognito 控制台,然后根据 New Identity Pool (新建身份池) 向导的指示进行操作。

  3. 记下身份池 ID。您将在创建于下一节的移动应用程序中指定此 ID。应用程序在向 Amazon Cognito 请求临时安全凭证时将使用此 ID。

创建 Android 应用程序

创建一个简单的 Android 移动应用程序来生成事件并通过以参数形式传递事件数据调用 Lambda 函数。

以下操作不受已用 Android studio 进行了验证。

  1. 使用下面的配置创建名为 AndroidEventGenerator 的新 Android 项目:

    • 选择 Phone and Tablet 平台。

    • 选择 Blank Activity

  2. 在 build.gradle (Module:app) 文件的 dependencies 部分中添加以下内容:

    compile 'com.amazonaws:aws-android-sdk-core:2.2.+' compile 'com.amazonaws:aws-android-sdk-lambda:2.2.+'
  3. 构建项目,以便根据需要下载必需的依赖项。

  4. 在 Android 应用程序清单 (AndroidManifest.xml) 中,添加以下权限,以使您的应用程序能够连接 Internet。可以将它们添加在 </manifest> 结束标签之前。

    <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  5. MainActivity 中,添加以下导入:

    import com.amazonaws.mobileconnectors.lambdainvoker.*; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.regions.Regions;
  6. package 部分中,添加以下两个类(RequestClassResponseClass)。请注意,此 POJO 与您在上一节中的 Lambda 函数中创建的 POJO 相同。

    • RequestClass。此类的实例将充当包含名字和姓氏的事件数据的 POJO (Plain Old Java Object)。如果您使用的是在上一节中创建的 Lambda 函数的 Java 示例,则此 POJO 与您在 Lambda 函数代码中创建的 POJO 相同。

      package com.example....lambdaeventgenerator; public class RequestClass { String firstName; String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public RequestClass(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public RequestClass() { } }
    • ResponseClass

      package com.example....lambdaeventgenerator; public class ResponseClass { String greetings; public String getGreetings() { return greetings; } public void setGreetings(String greetings) { this.greetings = greetings; } public ResponseClass(String greetings) { this.greetings = greetings; } public ResponseClass() { } }
  7. 在相同的程序包中,创建名为 MyInterface 的接口,以用于调用 AndroidBackendLambdaFunction Lambda 函数。

    package com.example.....lambdaeventgenerator; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunction; public interface MyInterface { /** * Invoke the Lambda function "AndroidBackendLambdaFunction". * The function name is the method name. */ @LambdaFunction ResponseClass AndroidBackendLambdaFunction(RequestClass request); }

    代码中的 @LambdaFunction 注释将该特定的客户端方法映射到同名的 Lambda 函数。有关此注释的更多信息,请参阅 适用于 Android 的 AWS 移动软件开发工具包 Developer Guide 中的 AWS Lambda

  8. 为使应用程序保持简单,我们将在 onCreate() 事件处理程序中添加调用 Lambda 函数的代码。在 MainActivity 中,向 onCreate() 代码末尾处添加以下代码。

    // Create an instance of CognitoCachingCredentialsProvider CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider( this.getApplicationContext(), "identity-pool-id", Regions.US_WEST_2); // Create LambdaInvokerFactory, to be used to instantiate the Lambda proxy. LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(), Regions.US_WEST_2, cognitoProvider); // Create the Lambda proxy object with a default Json data binder. // You can provide your own data binder by implementing // LambdaDataBinder. final MyInterface myInterface = factory.build(MyInterface.class); RequestClass request = new RequestClass("John", "Doe"); // The Lambda function invocation results in a network call. // Make sure it is not called from the main thread. new AsyncTask<RequestClass, Void, ResponseClass>() { @Override protected ResponseClass doInBackground(RequestClass... params) { // invoke "echo" method. In case it fails, it will throw a // LambdaFunctionException. try { return myInterface.AndroidBackendLambdaFunction(params[0]); } catch (LambdaFunctionException lfe) { Log.e("Tag", "Failed to invoke echo", lfe); return null; } } @Override protected void onPostExecute(ResponseClass result) { if (result == null) { return; } // Do a toast Toast.makeText(MainActivity.this, result.getGreetings(), Toast.LENGTH_LONG).show(); } }.execute(request);
  9. 运行代码并按以下方式验证它:

    • Toast.makeText() 显示返回的响应。

    • 验证 CloudWatch Logs 能够显示 Lambda 函数创建的日志。它应显示事件数据(名字和姓氏)。您也可以在 AWS Lambda 控制台中对此进行验证。