Android Guide

Kii Cloud provides developers with a set of tools to support Android application development. Our Android SDK gives you the opportunity to develop applications without ever needing your own servers.

This guide will navigate you through the SDK's basic features. You can review what is possible with the Kii SDK, and even get a head start with some sample code snippets. After reviewing the guide, you'll be ready to dig into our SDK or check the detailed documentation available here.

Here are some guidelines for reading the guide.

Blocking vs. Non-Blocking API

Many of our SDK methods, such as registering a new user and uploading data, require network communication with the Kii Cloud. Kii SDK provides both blocking and non-blocking versions for these methods. Please read Network Access for the overview.

In the guides, we generally provide sample code snippets for both non-blocking and blocking APIs.

Unlike the iOS SDK, calling a blocking API from the main thread in the Android SDK will throw an exception. You need to call a blocking API from a background thread. This limitation is due to Android OS not allowing network access from the main thread.

Whether to use blocking APIs or non-blocking APIs depends on the situation. Typically, using non-blocking APIs will allow you to implement you application easily. If your application needs to execute multiple processes serially, however, you might want to create a background thread and use blocking APIs to execute the processes in the correct order.

Exception Handling

Some APIs in Kii Cloud SDK throw exceptions. In this section, we explain how you can handle the exceptions and how you can investigate the cause of the failure.

Sample Snippets in the Guides

In the guides, we provide sample code snippets to illustrate how you can leverage our SDKs. In these code snippets, the exception handling is usually simplified; the message output and error recovery are omitted.

For example, we present the following sample codes when we explain how to register new users:

Blocking API

When an error occurs in a blocking API call, an exception will be thrown. You can handle the exception with a try/catch block just like any other Java programs.

The sample snippets presented in the guides basically handle only abstract-level exceptions.

try {
  user.register(password);
} catch (IOException e) {
  // Please check IOExecption to see what went wrong...
  return;
} catch (AppException e) {
  // Please check AppException to see what went wrong...
  return;
}

Non-Blocking API

When an error occurs in a non-blocking API call, an exception object will be passed as a parameter of a callback method. If there is no error, this exception object will be null.

user.register(new KiiUserCallBack() {
  @Override
  public void onRegisterCompleted(int token, KiiUser user, Exception exception) {
    if (exception != null) {
      // Error handling
      return;
    }
  }
}, password);

Types of Exceptions

In general, your application needs to handle the following two types of exceptions (unless sample snippets say otherwise).

  • java.lang.IOException

    IOException occurs when you call an API that accesses the network, but there are some issues in the networking with the server. Most of the time, this error is due to the unstable or misconfigured network.

  • AppException

    AppException is the root exception in the exception class hierarchy (there is CloudException that is a superclass of AppException, but this is merely for the future extension). Usually, you will just need to catch AppException, as presented in sample snippets.

    When an API execution causes an error, Kii Android SDK will basically throw an exception object that is a subclass of AppException. If the API internally executes the REST API, it will throw the subclass exception that corresponds to the HTTP status returned by Kii Cloud as shown in the next table (if the HTTP status not listed in the table is returned, UndefinedException will be thrown).

    HTTP Status Type of Exception
    400 BadRequestException
    401 UnauthorizedException
    403 ForbiddenException
    404 NotFoundException
    409 ConflictException

These exceptions have the following hierarchy, so you can handle all of them by catching IOException and AppException in a try/catch block. For the complete list of all exceptions thrown by the SDK and the detailed explanation of the exceptions thrown by each API, please read Javadoc.

You need to validate the string (i.e. its length and the characters in the string) before you pass it to the API as a parameter. The client SDK will check the parameter and throw RuntimeException (e.g. java.lang.IllegalArgumentException) if the parameter is invalid. If you are using a blocking API, this will cause your application to crash. Please note that some non-blocking API also throws RuntimeException when the parameter is invalid.

There is BadRequestException defined as a subclass of AppException, but this will not cover the parameter error cases that are handled by IllegalArgumentException.

If you want to handle exceptions more precisely, you can check and handle individual exceptions as shown in the following snippet:

Blocking API

try {
  user.register(password);
} catch (ConflictException e) {
  // Registration failed because the user already exists
  return;
} catch (AppException e) {
  // Other exceptions in App layer
  return;
} catch (IOException e) {
  // Error occurred in Network layer
  return;
}

Non-Blocking API

user.register(new KiiUserCallBack() {
  @Override
  public void onRegisterCompleted(int token, KiiUser user, Exception exception) {
    if (exception instanceof ConflictException) {
      // Registration failed because the user already exists
      return;
    } else if (exception instanceof AppException) {
      // Other exceptions in App layer
      return;
    } else if (exception instanceof IOException) {
      // Error occurred in Network layer
      return;
    } else if (exception != null) {
      // Other exceptions
      return;
    }
  }
}, password);

It is difficult to cover all exceptions and error cases thrown by each API. We recommend you to catch only specific cases that you need to handle explicitly (e.g. user duplication and network error) and handle other cases as a general error. Please note that exceptions and error codes can be added and modified as we update the SDK and server.

Error Details

Sometimes you can get the details of the exception from AppException and its subclasses. The client SDK connects to Kii Cloud server via REST API. When the server returns an error, you can get the information returned by the server using the methods in the exception. The information is useful for determining the root cause of the error during your development.

For example, suppose that you try to register a user user_123456 but this user already exists in Kii Cloud. Executing the following code will cause a user duplication error. The snippet shows the error details you can get in this situation.

try {
  KiiUser user = KiiUser.builderWithName("user_123456").build();
  user.register(password);
} catch (ConflictException e) {
  System.out.println("-- getReason");
  System.out.println(e.getReason());
  System.out.println("-- getMessage");
  System.out.println(e.getMessage());
  return;
} catch (AppException e) {
  // Error handling
  return;
} catch (IOException e) {
  // Error handling
  return;
}
-- getReason
USER_ALREADY_EXISTS
-- getMessage
Error: null
HTTP Response Status: 409
HTTP Response Body: {
"errorCode" : "USER_ALREADY_EXISTS",
"message" : "User with loginName user_123456 already exists",
"value" : "user_123456",
"field" : "loginName"
}

This example shows the result of the user duplication. The error information obtainable differs by the situation. In your code, please make sure to handle the case when null is returned. For example, all REST API related details will be null if the error is raised solely by the client SDK inside).

  • getReason method

    This method returns the enum that explains the reason of failure. The enum is available when the REST API is called inside the client SDK. The method is available on the following exception classes: BadRequestException, NotFoundException, and ConflictException.

  • getMessage method

    This method returns the error details for debugging purposes. The return message includes the result of the getBody method, but it does not include the stack trace. If you just want to get the stack trace, you can use the printStackTrace method.

    If you encounter an unknown error while developing, you might get the error details by reading the message field of the HTTP Response BODY. In the above example, you can see that the specified user already exists in Kii Cloud.

There are more methods for getting the error details, but basically you should be able to investigate the problem with the exception type and the result of the getReason method.

When you are going to ask for some help (e.g. post a question in Kii community), we encourage you to provide this information as the reference.

For more details on errors, please check AppException class reference, including its superclass and subclasses.

If you want to control your Android code based on the error reason, we recommend coding your application as follows:

  1. Check the exception type. For example, you can learn that the user duplication occurs when ConflictException is thrown.

  2. If you cannot determine the error reason by the exception type (e.g. the same exception will be thrown in multiple situations), check the details with the getReason method and take the appropriate action.

Handling Access Token Refresh Failure

If you are going to leverage Refresh Token, we encourage you to design your application so as to handle the RefreshTokenFailedException case.

As explained in this section, you need to execute relogin with a username and password when you get the RefreshTokenFailedException exception; therefore your application needs to show the initial screen or the login screen so as to ask for user relogin. This check needs to be made for all API calls that access the network, so it is essential to design how to handle such a situation beforehand.

Tools for Investigating Errors

There are a couple of tools available to help you investigate the error root cause.

Developer Log

The error details are recorded in the developer log.

Please read Inspect Developer Log to learn how you can inspect the error log to spot the root cause while developing and troubleshooting.

The following log is a sample of logs that are recorded when the user duplication occurs:

2015-04-21T11:45:11.783+09:00 [ERROR] user.register description:User registration failed userID: login-name:user_123456 email-address:user_123456@example.com phone-number:+819012345678 exception:User with loginName user_123456 already exists

Data Browser

You can verify if the data updated in your application are properly set in Kii Cloud.

Please read Browsing Application User and Data for more details.

Troubleshooting

Here are some tips that might help you when you encounter errors. When you investigate the error root cause with the error details and logs, please also check these items.

  1. Are you using the latest SDK?

    The sample snippets are written based on the latest SDKs. Some issues could have been resolved in the latest version, so please make sure to use the latest SDKs.

  2. Are the AppID, AppKey and server location correct?

    Please make sure that the Kii.Initialize() is properly executed as described in Adding Kii Cloud SDK to your Application. If you are developing multiple applications, make sure that the correct AppID is specified. Also double check if the correct server location (JP/US/CN/SG) is specified.

  3. Do not mix the blocking API and non-blocking API

    Calling a blocking API in the main thread will throw an error. Make sure to implement your application with either blocking or non-blocking API, unless you mean to use both.