> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 适用于原生 Java 和 Android Studio 的 Java 快速入门

> 下载 PlayFab Java 客户端 SDK JAR 文件、设置类路径，并在原生 Java 或 Android 中发起首次 LoginWithCustomID API 调用。

本快速入门帮助你使用 PlayFab JavaSDK 和一个简单的 Java 程序快速上手。

在调用任何 PlayFab API 之前，你必须拥有一个 [PlayFab 开发者帐户](https://developer.playfab.com)。

本教程的目标是：

* 获取所需的 JAR 文件。

* 将 JAR 文件添加到类路径中。

* 创建一个最简单的 Java 控制台应用程序，用于执行[自定义 ID 登录 API 调用](xref:titleid.playfabapi.com.client.authentication.loginwithcustomid)。

## 获取所需的 JAR 文件

为了使用 PlayFab JavaSDK，我们需要 PlayFab 客户端 JavaSDK 及其依赖项 Google GSON。

在[此处](https://github.com/PlayFab/JavaSDK/tree/versioned/builds)下载 PlayFab 客户端 JavaSDK JAR 库。查找 **client-sdk-\*.jar** 以及相应的 Java Doc \[可选但很有用]。

你可以在[此处](https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.0/)下载最新的 Google GSON。查找 **gson-\*.jar**。

## 使用 Intellij Idea 进行项目设置

初始化一个简单的 Intellij Idea Java 项目后，请确保按以下示例所示放置所需的 JAR 文件。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-proj-setup.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=85dc548792dd8ba7c4dffd3eaddd3d43" alt="Intellij - 项目设置" width="473" height="299" data-path="images/playfab/sdks/java/intellij-proj-setup.png" />

下一步是将 JAR 文件添加到类路径中。导航到 **File** -> **,**，如下例所示。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-add-jar-files-to-classpath.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=167ce0cbbce7cefb93979d2ccfa8b896" alt="Intellij - 将 jar 文件添加到类路径" width="388" height="435" data-path="images/playfab/sdks/java/intellij-add-jar-files-to-classpath.png" />

导航到 **Libraries**，然后按下图所示添加一个新的 Java 库。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-add-new-java-library.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=db7b46a3ccb01057f0d1e66474ab828c" alt="Intellij - 添加新的 Java 库" width="395" height="361" data-path="images/playfab/sdks/java/intellij-add-new-java-library.png" />

选择你添加到 libs 文件夹中的 JAR 文件，然后如下所示选择 **OK**。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-select-jar-files.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=e60d7b28a9a1880a0ddd32661d6c7765" alt="Intellij - 选择 jar 文件" width="574" height="529" data-path="images/playfab/sdks/java/intellij-select-jar-files.png" />

如果系统要求选择 **Module**，请选择列表中的第一个。确保所有 JAR 文件都已添加到库列表中。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-ensure-jar-files-added.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=6dc524df20ee6c2b4a2cb3a894fd83c2" alt="Intellij - 确保已添加 jar 文件" width="876" height="372" data-path="images/playfab/sdks/java/intellij-ensure-jar-files-added.png" />

## 使用任意 IDE 进行项目设置

主要要求是将 JAR 文件添加到类路径中。请查阅你所用 IDE 的指南，了解如何将 JAR 文件添加到类路径中。

## 设置你的第一个 API 调用

使用下面所示的代码作为你的主类代码。

```java theme={null}
import java.util.concurrent.*;
import java.util.*;

import com.playfab.PlayFabErrors.*;
import com.playfab.PlayFabSettings;
import com.playfab.PlayFabClientModels;
import com.playfab.PlayFabClientAPI;

public class Main
{
    private static boolean _running = true;

    public static void main(String[] args) {
        PlayFabSettings.TitleId = "144";

        PlayFabClientModels.LoginWithCustomIDRequest request = new PlayFabClientModels.LoginWithCustomIDRequest();
        request.CustomId = "GettingStartedGuide";
        request.CreateAccount = true;

        FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
        loginTask.run();

        while (_running) {
            if (loginTask.isDone()) { // You would probably want a more sophisticated way of tracking pending async API calls in a real game
                OnLoginComplete(loginTask);
            }

            // Presumably this would be your main game loop, doing other things
            try {
                Thread.sleep(1);
            } catch(Exception e) {
                System.out.println("Critical error in the example main loop: " + e);
            }
        }
    }

    private static void OnLoginComplete(FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask) {
        PlayFabResult<com.playfab.PlayFabClientModels.LoginResult> result = null;
        try {
            result = loginTask.get(); // Wait for the result from the async call
        } catch(Exception e) {
            System.out.println("Exception in PlayFab api call: " + e); // Did you assign your PlayFabSettings.TitleId correctly?
        }

        if (result != null && result.Result != null) {
            System.out.println("Congratulations, you made your first successful API call!");
        } else if (result != null && result.Error != null) {
            System.out.println("Something went wrong with your first API call.");
            System.out.println("Here's some debug information:");
            System.out.println(CompileErrorsFromResult(result));
        }

        _running = false; // Because this is just an example, successful login triggers the end of the program
    }

    // This is a utility function we haven't put into the core SDK yet. Feel free to use it.
    private static <RT> String CompileErrorsFromResult(PlayFabResult<RT> result) {
        if (result == null || result.Error == null)
            return null;

        String errorMessage = "";
        if (result.Error.errorMessage != null)
            errorMessage += result.Error.errorMessage;
        if (result.Error.errorDetails != null)
            for (Map.Entry<String, List<String>> pair : result.Error.errorDetails.entrySet() )
                for (String msg : pair.getValue())
                    errorMessage += "\n" + pair.getKey() + ": " + msg;
        return errorMessage;
    }
}
```

## 完成并执行

要运行应用程序：

1. 选择右上角的**播放箭头 >**。这将启动程序执行，并显示输出面板。
2. 找到**调试消息**。这表明 API 调用成功。

<img src="https://mintcdn.com/microsoft-4404708b/N3T1ucKV7zIMBudj/images/playfab/sdks/java/intellij-run-program.png?fit=max&auto=format&n=N3T1ucKV7zIMBudj&q=85&s=04ce4add6100b9b56db869bf97baadbb" alt="Intellij - 运行程序" width="968" height="719" data-path="images/playfab/sdks/java/intellij-run-program.png" />

此时，你可以开始进行其他 API 调用并构建你的游戏。

有关所有可用客户端 API 调用的列表，请参阅我们的 [PlayFab API 参考](/services/playfab/api-references)文档。

## 代码解析

这个可选的最后一节详细介绍 `GettingStarted.java` 中的每一行。

* 导入
  * 这是用于进行 PlayFab API 调用的最小导入集。

* public static void `main(String[] args) {`
  * 只是一个基本的循环，用于启动 API 调用并等待其完成。

  * `PlayFabSettings.TitleId = "xxxx"`;
    * 每个 PlayFab 开发者都会在 Game Manager 中创建一个 title。发布游戏时，你必须将该 titleId 编入游戏代码中。这可让客户端知道如何访问 PlayFab 中的正确数据。对于大多数用户来说，只需将其视为使 PlayFab 正常工作的必备步骤即可。

  * `PlayFabClientModels.LoginWithCustomIDRequest request = new PlayFabClientModels.LoginWithCustomIDRequest();`
    * 大多数 PlayFab API 方法都需要输入参数，这些输入参数被打包到一个请求对象中。

    * 每个 API 方法都需要一个唯一的请求对象，其中包含可选参数和必需参数的组合。
      * 对于 `LoginWithCustomIDRequest`，有一个必需参数 `CustomId`（唯一标识一个玩家）和 `CreateAccount`（允许通过此调用创建新帐户）。

    * 对于登录，大多数开发者会希望使用更合适的登录方法。
      * 有关所有登录方法及输入参数的列表，请参阅 PlayFab 登录文档。常用选项包括：
        * `LoginWithAndroidDeviceID`
        * `LoginWithIOSDeviceID`
        * `LoginWithEmailAddress`

  * `FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request)`;
    * 这将使用 Java FutureTask 框架启动对 `LoginWithCustomID` 的异步请求。

  * While (running) `{ if (loginTask.isDone()) { OnLoginComplete(loginTask); } }`
    * 运行一个简单的主循环，并异步等待 loginTask 完成。
    * 完成后调用 `OnLoginComplete`。

* `OnLoginComplete (loginTask)`
  * `result = loginTask.get()`;
    * 获取异步结果（这不会导致阻塞，因为我们已确认 FutureTask 已完成）。

  * 如果 (`result.Result != null`)，则 API 调用成功。
    * 成功时，许多 API 回调的 `result.Result` 对象将包含所请求的信息。

    * `LoginResult` 具体包含有关玩家的一些基本信息。但对大多数用户来说，登录只是调用其他 API 之前的必备步骤。

  * 如果 (`result.Error != null`)，则 API 调用失败。
    * API 调用可能因多种原因失败，你应始终尝试处理失败情况。
    * API 调用失败的原因（按可能性顺序排列）
      * 未设置 `PlayFabSettings.TitleId`。如果你忘记为你的 title 设置 `TitleId`，则任何操作都不会成功。
      * 请求参数。如果你没有为特定 API 调用提供正确或必需的信息，则调用将失败。详情请参阅 `error.errorMessage`、`error.errorDetails` 或 `error.GenerateErrorReport()`。
      * 设备连接问题。手机会不断丢失/恢复连接，因此任何时候的任何 API 调用都可能随机失败，然后立即恢复正常。进入隧道可能会使你完全断开连接。
      * PlayFab 服务器问题。与所有软件一样，可能会出现问题。请参阅我们的[发行说明](/services/playfab/release-notes)了解更新信息。
      * 互联网并非 100% 可靠。有时消息会损坏或无法到达 PlayFab 服务器。

  * 如果你在调试问题时遇到困难，且错误信息中的内容不够详尽，请访问我们的[论坛](https://community.playfab.com/index.html)。


## Related topics

- [适用于原生 JavaScript 和 Phaser 的 JavaScript 快速入门](/zh-CN/services/playfab/sdks/javascript/quickstart.md)
- [适用于 Windows 的 C++ 快速入门](/zh-CN/services/playfab/sdks/playfab-cpp/quickstart-windows.md)
- [适用于 Android 的 PlayFab Services](/zh-CN/services/playfab/sdks/platforms/android.md)
- [Android 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-android.md)
- [适用于 Linux 的 C++ 快速入门](/zh-CN/services/playfab/sdks/playfab-cpp/quickstart-linux.md)
