1. 准备工作
此 Codelab 是“移动文本分类入门”开发者在线课程中的第 2 项活动。
在此 Codelab 中,您将构建一个简单的即时通讯应用。在此开发者在线课程的后续部分,您将使用机器学习模型更新此应用,以过滤应用中的垃圾信息。
前提条件
- 具备使用 Kotlin 进行 Android 开发的基础知识,以及(可选)使用 Swift 进行 iOS 开发的基础知识
构建内容
- 一款简单的即时通讯应用
所需条件
- 对于 Android,您需要先安装 Android Studio,然后才能开始使用。请确保已安装并完全更新,然后再继续。
- 对于 iOS,您需要 Xcode。您可以在 App Store 中找到此应用。(如果您只想编写 iOS 应用,请直接跳至第 5 步。
获取代码
如果您不想按部就班地操作,而只想查看此开发者在线课程的最终代码,请访问
git clone https://github.com/googlecodelabs/odml-pathways
在此处,找到 TextClassificationOnMobile 目录,然后您会看到 Android 和 iOS 子目录。这些目录将包含 TextClassificationStep1 子目录,其中分别包含 Android 和 iOS 上的应用。

2. 在 Android Studio 中创建新项目
- 启动 Android Studio。

- 选择创建新项目。系统会显示一个对话框,要求您选择项目模板。
- 选择 Empty Activity,然后点击 Next。接下来,系统会要求您配置项目。您可以随意选择,但请确保语言为 Kotlin,且最低 SDK 为 API 23。
- 点击完成。完成后,Android Studio 将打开并显示您的项目。它可能需要几分钟时间来执行 Gradle 同步,以确保一切正常,尤其是在您首次使用 Android Studio 时。
3. 创建界面
Android 应用的界面是使用名为布局文件的 XML 文件创建的。
- 打开文件。在 Android Studio 中,使用资源管理器依次点击 app > res > layout > activity_main.xml。

在屏幕右上角,您应该会看到一个包含“代码”“拆分”和“设计”标签页的选择器,如下所示:

请确保已选择“代码”,然后再继续执行下一步。
- 将代码替换为以下 XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter a string:"></TextView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txtInput"></EditText>
</LinearLayout>
<TextView
android:id="@+id/txtOutput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Output Goes here"
android:textSize="36sp"></TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnSendText"
android:text="Send"></Button>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
这样一来,您便会获得一个包含输入区域的基本界面,其中包含一个 TextView,提示您输入字符串,以及一个名为 txtInput 的 EditText,可用于输入字符串。下方是一个用于呈现输出的 TextView,以及一个用户将按下来触发分类的按钮。
下一步是编写用于激活此界面的代码。
4. 连接控件并创建应用
您可以找到 MainActivity 代码文件,然后修改相应活动的代码。
- 在 Android Studio 中,依次点击 app > java > MainActivity。

- 打开 MainActivity 文件,进入代码编辑器。将此文件中的所有内容(除了以“package”开头的第一行)替换为以下代码:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
lateinit var txtInput: EditText
lateinit var btnSendText: Button
lateinit var txtOutput: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
txtInput = findViewById(R.id.txtInput)
txtOutput = findViewById(R.id.txtOutput)
btnSendText = findViewById(R.id.btnSendText)
btnSendText.setOnClickListener {
var toSend:String = txtInput.text.toString()
txtOutput.text = toSend
}
}
}
此代码将布局中的控件连接到 txtInput、txtOutput 和 btnSendText,以便在代码中引用它们。然后,它会为按钮设置一个 OnClickListener,以便当用户触摸该按钮时,系统会读取 txtInput 中的文本,将其转换为字符串,然后将 txtOutput.text 属性设置为该字符串。
5. 在 iOS 上创建基本应用
以下步骤要求您对 Xcode 和使用 Swift 进行 iOS 开发有一定的了解。
如果您不想完成创建流程,可以克隆该代码库并直接打开应用。它名为 TextClassificationStep1,位于代码库的 iOS 文件夹中。
若要创建基本应用,您将从 Xcode 开始。
- 使用基本模板创建新的应用:

- 为新项目选择选项。为您的商品指定名称和组织标识符。您可以输入所需内容,也可以按照以下示例操作:(但请务必将界面设置为 Storyboard,并将生命周期设置为 UIKitApp Delegate,如图所示。)

6. 修改分镜脚本
- 打开 Main.storyboard。您会看到一个设计界面,您可以在其中添加控件。
- 如需添加控件,请点击 Xcode 窗口顶部的 + 按钮。

- 使用此功能将 TextView 控件、Button 控件和 Label 控件放置到设计界面上。输出应如下所示:

- 使用助理打开并排视图,使 storyboard 和 ViewController.swift 文件同时处于打开状态。助理是屏幕右上角的一个小图标,如图所示:

- 按住 CONTROL 键,然后将 TextView 控件拖动到代码界面。拖动时,您应该会看到一个蓝色箭头。
- 放置到类声明正下方的代码上。系统会显示一个弹出式窗口,询问您连接类型。输出应如下所示:

- 选择 Outlet 并将其命名为 txtInput。
- 对标签执行相同的操作,然后将连接类型设为 Outlet,并将其命名为 txtOutput。
- 最后,拖动按钮,但这次选择操作作为连接类型。(请勿使用 Outlet 作为连接类型。)
- 将操作命名为 btnSendText。
完成后,类顶部的代码应如下所示:
@IBOutlet weak var txtInput: UITextView!
@IBOutlet weak var txtOutput: UILabel!
@IBAction func btnSendText(_ sender: Any) {
}
7. 完成基本 iOS 应用的编码
由于此视图使用 UITextView,因此为了让它响应此视图上的事件,它需要是 UITextViewDelegate。
您可以通过将类声明更改为以下内容来获取此信息:
class ViewController: UIViewController, UITextViewDelegate {
然后,在 viewDidLoad 函数中,将 UITextView(您在设置 outlet 时将其称为 txtInput)的委托设置为此类,如下所示:
override func viewDidLoad() {
super.viewDidLoad()
txtInput.delegate = self
}
最后,您希望在用户按键盘上的 Enter 键后处理键盘从显示中移除的情况。这是通过您刚刚设置的委托完成的,您可以在 ViewController 上实现此方法来处理它。
func textView(_ textView: UITextView, shouldChangeTextIn range:
NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
return false
}
return true
}
对于此应用,按钮操作非常简单,我们只需将用户输入的内容传递给输出即可。稍后,您将了解 NLP 模型如何过滤此文本。不过,我们现在先将其连接起来,以模拟直通。
您已创建操作 btnSendText,现在只需向其中添加代码即可:
@IBAction func btnSendText(_ sender: Any) {
txtOutput.text = "Sent :" + txtInput.text
}
8. 恭喜!
您已完成此 Codelab!
在下一个开发者在线课程中,您将学习如何创建 NLP 模型,稍后您将返回到此应用,让它能够过滤用户文本中的垃圾评论!