什么是AppGallery Connect云函数

云函数是一项Serverless计算服务,提供FaaS(Function as a Service)能力,可以帮助开发者大幅简化应用开发与运维相关事务,降低应用功能的实现门槛,快速构建业务能力。

  1. 云函数提供了高效可靠的函数开发与运行框架,替开发者完全解决传统应用开发与运维中的诸多复杂事务(如服务器配置与管理、代码部署、负载均衡、弹性伸缩、高可用保证等),开发者只须聚焦业务逻辑、开发并上传函数代码,即可构建高可用、可伸缩的Serverless应用。
  2. 云函数作为Serverless的核心与枢纽,支持连接和扩展周边云服务能力,开发者可以像拼搭积木一样自由便捷地组织各项服务来实现业务逻辑。

您将建立什么

在本次Codelab中,您将实现一个能够使用AppGallery Connect云函数与客户端进行交互的功能,您需要完成的功能将包含:

您将会学到什么

开发环境及技能要求

运行终端要求

集成AppGallery Connect云函数,需要完成以下准备工作

具体操作,请按照《AppGallery Connect应用集成准备》中的详细说明来完成。

开通云函数服务

  1. 登录AppGallery Connect网站,在AppGallery Connect页面点击"我的项目",在项目的应用列表中选择您需要开通云函数服务的应用,点击"构建 > 云函数"。如果您为首次使用云函数服务,请点击"立即开通"开通服务。
  2. 如果产品数据存储位置未设置,需要选择该产品的数据存储位置,具体操作请参见设置数据存储位置

集成SDK

针对Android Studio开发环境,华为提供了maven仓集成方式的SDK包,开发前需集成SDK到您的Android Studio项目中。

  1. 在AppGallery Connect页面点击"我的项目",在项目下的应用列表中选择您需要开通远程配置的应用。
  2. 在项目设置的"常规"页签下,点击"应用"栏下的"agconnect-services.json"下载配置文件。
  3. 将"agconnect-services.json"文件拷贝到应用级根目录下。
  4. 打开Android Studio应用级build.gradle文件,添加如下代码集成Cloud Function SDK。
    //配置如下地址 apply plugin: 'com.huawei.agconnect' dependencies { //配置如下地址 implementation 'com.huawei.agconnect:agconnect-function:1.4.1.300' }
  5. 点击界面上的"Sync Now"链接同步已完成的配置。

创建云函数

  1. 登录AppGallery Connect网站,在AppGallery Connect页面点击"我的项目",在项目的应用列表中选择您的应用,点击"构建 > 云函数"。
  2. 在"函数"页面,点击"创建函数"。
  3. 在创建界面中,完成函数定义。
  4. "函数名称"和"描述"栏输入函数名称与描述。
  5. "代码输入类型"选择"在线编辑"
  6. "部署信息"中输入部署信息,可使用默认配置。
  7. handler.js文件的代码输入框中输入以下代码。
    let myHandler = function(event, context, callback, logger) { var res = new context.HTTPResponse(context.env, { "res-type": "context.env", "faas-content-type": "json", }, "application/json", "200"); var year; if (event.body) { var _body = JSON.parse(event.body); year = _body.year; } else { year = event.year; } var body = { result:'' }; body.result = animal(year); res.body = body; context.callback(res); function animal(inputYear) { var resultString; if(!isNumber(inputYear)){ resultString = "input is not a number"; }else{ var remainder = inputYear%12; switch (remainder) { case 0: resultString = "Monkey"; break; case 1: resultString = "Chicken"; break; case 2: resultString = "Dog"; break; case 3: resultString = "Pig"; break; case 4: resultString = "Mouse"; break; case 5: resultString = "Cow"; break; case 6: resultString = "Tiger"; break; case 7: resultString = "Rabbit"; break; case 8: resultString = "Dragon"; break; case 9: resultString = "Snake"; break; case 10: resultString = "Horse"; break; case 11: resultString = "Sheep"; break; default: resultString = "No symbolic Animal"; } } return resultString; } function isNumber(input){ if (parseInt(input).toString == "NaN") { return false; } else { return true; } } }; module.exports.myHandler = myHandler;

测试函数

  1. 您可以通过两种方式进入函数测试页面。
  2. 点击函数详情界面右上角的"测试"按钮。
  3. 点击Cloud Functions主界面左侧导航栏的"测试"菜单。
  4. 选择刚刚创建的函数及其版本,在事件中输入如下代码:
    { "year": 2020 }
  5. 在执行结果中查看结果,判断是否与如下结果一致:

添加触发器

  1. 在函数列表中点击函数名称进入函数详情页面。如果是函数别名,则进入函数别名配置页面。
  2. 点击"配置"页签下的"添加触发器",显示触发器创建界面。
  3. "触发器类型"选择NOPATHHTTP,请求方式选择POST。
  4. 完成后点击"添加"并点击"保存"。
  5. 将"详细信息"中的"触发URL"的后缀保存,作为后续客户端请求时的触发器标识。

本次Codelab中您可以在您的Android Studio工程中创建一个布局页面,参照下图进行UI设计,具备简单的年份输入,云函数返回结果的展示功能即可。

具体的界面布局,可参考如下activity_main.xml文件中的相关代码:

<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.4"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/instruction"/> <EditText android:id="@+id/year_text" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <TextView android:id="@+id/rst_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/instruction_result" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.6"/> <Button android:id="@+id/rst_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/OK_button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.7"/>
  1. 在应用启动的onCreate方法中获取控件实例并设置按钮的点击事件。
    @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); resultBtn = findViewById(R.id.rst_btn); resultText = findViewById(R.id.rst_text); inputYear = findViewById(R.id.year_text); resultBtn.setOnClickListener(new ButtonClickListener()); }
  2. 在点击事件中,首先获取输入框的输入值进行判空,并对其合法性进行校验。
    String inputText = inputYear.getText().toString(); if (inputText.equals("") || !isInputLegit(inputText)){ resultText.setText(R.string.year_error); return; }
  3. IsInputLegit方法:

    private boolean isInputLegit(String input){ for (int i = 0; i < input.length(); i++){ System.out.println(input.charAt(i)); if (!Character.isDigit(input.charAt(i))){ return false; } } return true; }
  4. 初始化云函数服务。
    AGConnectFunction function = AGConnectFunction.getInstance();
  5. 生成云函数所需要的事件的map对象,这里因为我们的云函数中设置的事件的key值为"year",所以我们设置map的key值为"year"。
    HashMap<String, String> map = new HashMap<>(); map.put("year", inputText);
  6. 调用云函数SDK中的wrap方法指定触发器,call方法传入事件的map作为参数,发送事件的HTTP请求并使用云函数进行计算,并且添加请求的回调接受云函数的返回结果显示到Textview中。
    function.wrap("symbolic-animals-$latest").call(map) .addOnCompleteListener(new OnCompleteListener<FunctionResult>() { @Override public void onComplete(Task<FunctionResult> task) { if (task.isSuccessful()){ String value = task.getResult().getValue(); try { JSONObject object = new JSONObject(value); String result = (String)object.get("result"); resultText.setText(result); } catch (JSONException e) { e.printStackTrace(); } Log.i(TAG, value); } else { Exception e = task.getException(); if (e instanceof AGCFunctionException){ AGCFunctionException functionException = (AGCFunctionException)e; int errCode = functionException.getCode(); String message = functionException.getMessage(); Log.e(TAG, "errorCode: " + errCode + ", message: " + message); } } } });
  1. 运行Android Studio工程生成APK包,并在测试手机中安装APK包。
  2. 在输入框中输入任意一个年份,查看界面是否展示当年的生肖。

祝贺您,您已经成功地构建了您的第一个集成AppGallery Connect云函数服务的应用程序,并学到了:

本Codelab中所用Demo源码下载地址如下:

源码下载

已复制代码