すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:よくある質問 (Android SDK)

最終更新日:Jun 11, 2026

OSS SDK for Android の一般的な問題と解決策について説明します。

説明

サンプルコードを使用する前に、HTTPDNS SDK for Android をインストールする必要があります。詳細については、「HTTPDNS SDK for Android のインストール」をご参照ください。

OSS SDK for Android は DNS 事前解決とキャッシュポリシーをサポートしていますか

はい、サポートしています。HTTPDNS SDK と OkHttp を組み合わせて使用することで、DNS 事前解決とキャッシュを実装できます。

  1. カスタム DNS 解決サービス用の API を実装します。

    public class OkHttpDns implements Dns {
        private static final Dns SYSTEM = Dns.SYSTEM;
        HttpDnsService httpdns;
        private static OkHttpDns instance = null;
        private OkHttpDns(Context context) {
            this.httpdns = HttpDns.getService(context, "account id");
        }
        public static OkHttpDns getInstance(Context context) {
            if(instance == null) {
                instance = new OkHttpDns(context);
            }
            return instance;
        }
        @Override
        public List<InetAddress> lookup(String hostname) throws UnknownHostException {
            // 非同期解決 API を使用して IP アドレスを取得します。
            String ip = httpdns.getIpByHostAsync(hostname);
            if(ip != null) {
                // IP アドレスが解決された場合は、ネットワークリクエストに使用します。
                List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
                Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
                return inetAddresses;
            }
            // IP アドレスが解決されなかった場合は、システム DNS サービスにフォールバックします。
            return Dns.SYSTEM.lookup(hostname);
        }
    }
  2. OkHttpClient インスタンスを作成し、DNS 事前解決とキャッシュを設定します。

    String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    ClientConfiguration conf = new ClientConfiguration();
    conf.setConnectionTimeout(15 * 1000); // 接続タイムアウト。デフォルト:15 秒。
    conf.setSocketTimeout(15 * 1000); // ソケットタイムアウト。デフォルト:15 秒。
    conf.setMaxConcurrentRequest(5); // 最大同時リクエスト数。デフォルト:5。
    conf.setMaxErrorRetry(2); // 最大リトライ回数。デフォルト:2。
    OkHttpClient.Builder builder = new OkHttpClient.Builder()
            .dns(OkHttpDns.getInstance(getApplicationContext()));
    // カスタム OkHttpClient を設定すると、一部の ClientConfiguration 設定が上書きされます。
    // これらの設定は、builder で直接設定してください。
    if (conf != null) {
        Dispatcher dispatcher = new Dispatcher();
        dispatcher.setMaxRequests(conf.getMaxConcurrentRequest());
        builder.connectTimeout(conf.getConnectionTimeout(), TimeUnit.MILLISECONDS)
                .readTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
                .writeTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
                .followRedirects(conf.isFollowRedirectsEnable())
                .followSslRedirects(conf.isFollowRedirectsEnable())
                .dispatcher(dispatcher);
        if (conf.getProxyHost() != null && conf.getProxyPort() != 0) {
            builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(conf.getProxyHost(), conf.getProxyPort())));
        }
    }
    // Android SDK 2.9.12 以降では、conf.setOkHttpClient() がサポートされています。
    conf.setOkHttpClient(builder.build());
    OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);

オブジェクトのダウンロード時に進捗コールバックで totalSize=-1 が返される理由

  • 原因: OkHttp が特定のコンテンツタイプ (text/cache-manifest、text/xml、text/plain、text/css、application/javascript、application/x-javascript、application/rss+xml、application/json、text/json) で 1 KB 以上のオブジェクトをダウンロードする場合、ユーザーが設定していなくても、自動的に Accept-Encoding: gzip ヘッダーを追加します。その結果、OSS は Content-Length ヘッダーを含まない gzip 形式でオブジェクトを返すため、進捗コールバックで totalSize=-1 が報告されます。

  • 解決策: リクエストに Range ヘッダーを設定します。これにより、OkHttp が Accept-Encoding: gzip を追加しなくなるため、OSS は Content-Length を返し、進捗コールバックで正しいサイズが報告されます。

    Map<String, String> header = new HashMap<>();
    header.put("x-oss-range-behavior", "standard");
    // examplebucket をバケット名に、exampledir/exampleobject.txt を完全なオブジェクトパスに置き換えてください。
    GetObjectRequest get = new GetObjectRequest("examplebucket", "exampledir/exampleobject.txt");
    get.setRange(new Range(0, -1));
    get.setRequestHeaders(header);
    OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
        @Override
        public void onSuccess(GetObjectRequest request, GetObjectResult result) {
            InputStream inputStream = result.getObjectContent();
            byte[] buffer = new byte[2048];
            int len;
            try {
                while ((len = inputStream.read(buffer)) != -1) {
                    // ダウンロードしたデータを処理します。
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onFailure(GetObjectRequest request, ClientException clientException, ServiceException serviceException) {
            if (clientException != null) {
                // ネットワークエラーなどのローカル例外を処理します。
                clientException.printStackTrace();
            }
            if (serviceException != null) {
                // サービス例外を処理します。
                Log.e("ErrorCode", serviceException.getErrorCode());
                Log.e("RequestId", serviceException.getRequestId());
                Log.e("HostId", serviceException.getHostId());
                Log.e("RawMessage", serviceException.getRawMessage());
            }
        }
    });

Kotlin で onFailure コールバックがトリガーされない

  • 原因

これは Kotlin の null 許容性の問題です。OSS Android SDK は Java 構文を使用して onFailure コールバックを定義しており、パラメータはデフォルトで非 null 許容となっています。

@Override
public void onFailure(GetObjectRequest request, ClientException clientException, ServiceException serviceException){
    if (clientException != null) {
        clientException.printStackTrace();
    }
    if (serviceException != null) {
        Log.e("ErrorCode", serviceException.getErrorCode());
        Log.e("RequestId", serviceException.getRequestId());
        Log.e("HostId", serviceException.getHostId());
        Log.e("RawMessage", serviceException.getRawMessage());
    }
}

Kotlin はこれらのパラメータを非 null 許容として扱うため、コールバックが期待通りにトリガーされない場合があります。関数シグネチャでパラメータを明示的に null 許容として宣言してください。

onFailure(request: GetObjectRequest?, clientException: ClientException?, serviceException: ServiceException?)