初期化済みの情報の保存と復元(ゲートウェイ)

初期化の際に作成した ThingIFAPIGatewayAPI のインスタンスが失われないよう、SDK では 2 通りの方法による保存と復元をサポートしています。

プロセス再起動時の保存と復元

アプリケーションがバックグラウンドに遷移したり言語設定が変更された場合に、アプリケーションや Activity などのインスタンスが Android のシステムによって再生成されます。その際に初期化処理で取得した ThingIFAPIGatewayAPI のインスタンスは失われます。

Activity などが再生成される際に Thing-IF SDK に関する情報を復元させるには、アプリの側でインスタンスを Bundle に保存します。Activity に用意されている Activity#onSaveInstanceState 内で ThingIFAPIGatewayAPI が実装している Parcelable インターフェイスを利用して、これらを保存してください。情報を復元するには、Activity#onCreate メソッドで復元処理を行ってください。

情報を保存・復元する例を以下に挙げます。ここではエンドノードを 3 件と仮定していますが、実際のモバイルアプリでは配列等の可変領域を使ってエンドノードを格納しているはずです。これらを同様に保存・復元します。

public class AppActivity extends Activity {
  private static final String BUNDLE_KEY_THING_IF_API_GATEWAY = "ThingIFAPIGateway";
  private static final String BUNDLE_KEY_GATEWAY_API = "GatewayAPI";
  private static final String BUNDLE_KEY_THING_IF_API_ENDNODE_1 = "ThingIFAPIEndNode1";
  private static final String BUNDLE_KEY_THING_IF_API_ENDNODE_2 = "ThingIFAPIEndNode2";
  private static final String BUNDLE_KEY_THING_IF_API_ENDNODE_3 = "ThingIFAPIEndNode3";

  private ThingIFAPI mApiGateway = null;
  private GatewayAPI mGatewayLocal = null;
  private ThingIFAPI mApiEndNode1 = null;
  private ThingIFAPI mApiEndNode2 = null;
  private ThingIFAPI mApiEndNode3 = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) {
      // Restore API instances.
      mApiGateway = savedInstanceState.getParcelable(BUNDLE_KEY_THING_IF_API_GATEWAY);
      mGatewayLocal = savedInstanceState.getParcelable(BUNDLE_KEY_GATEWAY_API);
      mApiEndNode1 = savedInstanceState.getParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_1);
      mApiEndNode2 = savedInstanceState.getParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_2);
      mApiEndNode3 = savedInstanceState.getParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_3);
    }

    setContentView(R.layout.activity_second);
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // Save API instances.
    outState.putParcelable(BUNDLE_KEY_THING_IF_API_GATEWAY, mApiGateway);
    outState.putParcelable(BUNDLE_KEY_GATEWAY_API, mGatewayLocal);
    outState.putParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_1, mApiEndNode1);
    outState.putParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_2, mApiEndNode2);
    outState.putParcelable(BUNDLE_KEY_THING_IF_API_ENDNODE_3, mApiEndNode3);
  }

}

Bundle のキー名はモバイルアプリの仕様に合わせて自由に変更できます。

上記の例では Activity#onCreate で復元していますが、Activity#onRestoreInstanceState で復元することも可能です。

なお、アクティビティのライフサイクルについては Google によるこちらのドキュメント を参照してください。

ストレージへのシリアライズ

作成した ThingIFAPIGatewayAPI のインスタンスを長期間にわたって保存したい場合、ストレージ(Android の SharedPreferences)へのシリアライズ機能を利用できます。

ストレージへの保存は SDK によって自動的に行われます。

プロセスの再起動時、読み込みは以下のように行います。ここではエンドノードの件数を 3 件としていますが、実際のモバイルアプリでは配列等の可変領域で扱うことになるはずです。この場合、エンドノードの件数はモバイルアプリ側で保存と読み込みを行う必要があります。

try {
  // Load API instances.
  ThingIFAPI apiGateway = ThingIFAPI.loadFromStoredInstance(getApplicationContext(), "gateway");
  GatewayAPI gatewayLocal = GatewayAPI.loadFromStoredInstance(getApplicationContext());
  ThingIFAPI apiEndNode1 = ThingIFAPI.loadFromStoredInstance(getApplicationContext(), "endnode1");
  ThingIFAPI apiEndNode2 = ThingIFAPI.loadFromStoredInstance(getApplicationContext(), "endnode2");
  ThingIFAPI apiEndNode3 = ThingIFAPI.loadFromStoredInstance(getApplicationContext(), "endnode3");
} catch (StoredThingIFAPIInstanceNotFoundException e) {
  // Handle the error.
}

ThingIFAPI.loadFromStoredInstance メソッドの第 2 引数にはタグ名を指定します。これは、初期化コードの実装(ゲートウェイ) で ThingIFAPI を作成する際、ThingIFAPIBuilder の setTag メソッドに指定したタグ名です。各インスタンスの保存先を識別するため、初期化の際に指定したタグ名と同じものを読み込み時に指定します。

removeStoredInstance メソッドによって保存されているインスタンスを削除することもできます。これら API の詳細については Javadoc を参照してください。

SharedPreferences へは ThingIFAPI_INSTANCEThingIFAPI_INSTANCE_タグ名GatewayAPI_INSTANCE、または、GatewayAPI_INSTANCE_タグ名 をキー名として値を保存します。これらのキー名で保存されている情報は上書きされます。