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

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

最終更新日:Nov 30, 2025

このトピックでは、Android 向け Object Storage Service (OSS) SDK の一般的な問題とそのソリューションについて説明します。

説明

サンプルコードを使用する前に、Android 用 HTTPDNS SDK を統合してください。詳細については、「Android SDK 統合プロセス」をご参照ください。

Android SDK は DNS プリフェッチとキャッシュポリシーをサポートしていますか?

次の例では、HTTPDNS SDK と OkHttp を使用して、Android で DNS プリフェッチとキャッシュポリシーを実装する方法を示します。

  1. DNS インターフェイスをカスタマイズします。

    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 {
            // 非同期解析インターフェイスから IP アドレスを取得します。
            String ip = httpdns.getIpByHostAsync(hostname);
            if(ip != null) {
                // null 以外の IP アドレスが返された場合は、それを使用してネットワークリクエストを実行します。
                List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
                Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
                return inetAddresses;
            }
            // null の IP アドレスが返された場合は、システム DNS サービスを使用してドメイン名を解決します。
            return Dns.SYSTEM.lookup(hostname);
        }
    }
  2. okHttpClient インスタンスを生成し、OSS 用に設定します。

    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())));
        }
    }
    // conf.setOkHttpClient() メソッドは、Android SDK 2.9.12 以降でのみサポートされています。
    conf.setOkHttpClient(builder.build());
    
    OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);

一部のファイルをダウンロードする際に進捗コールバックで totalSize=-1 が表示される問題

  • 原因

    OSS は、サイズが 1 KB 以上で、Content-Type が text/cache-manifest、text/xml、text/plain、text/css、application/javascript、application/x-javascript、application/rss+xml、application/json、または text/json のファイルに対して、Gzip 圧縮データを返します。 この圧縮は、リクエストで Accept-Encoding:gzip ヘッダーが明示的に設定されている場合に発生します。 このヘッダーを設定しなくても、ファイルをダウンロードする際に OkHttp が自動的に追加します。 Gzip 圧縮ファイルのサイズは特定できないため、OSS は Content-Length ヘッダーを返しません。 その結果、進捗コールバックは totalSize=-1 を返します。

  • ソリューション

    範囲を設定して、OkHttp が自動的に Accept-Encoding:gzip ヘッダーを追加しないようにします。 これにより、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 clientExcepion, ServiceException serviceException) {      
            // リクエストは失敗しました。
            if (clientExcepion != null) {
                // ネットワークエラーなどのクライアント例外が発生しました。
                clientExcepion.printStackTrace();
            }
            if (serviceException != null) {
                // サービス例外が発生しました。          
                Log.e("ErrorCode", serviceException.getErrorCode());
                Log.e("RequestId", serviceException.getRequestId());
                Log.e("HostId", serviceException.getHostId());
                Log.e("RawMessage", serviceException.getRawMessage());
            }
        }
    });

OSS Android SDK で Kotlin を使用すると onFailure コールバックがトリガーされない問題

  • 原因

デフォルトでは、OSS Android SDK は次の図に示すように Java 構文を使用します:

image

Kotlin を使用する場合、前の図に示されている onFailure 構文は null 許容性の問題を引き起こす可能性があります。 この問題を解決するには、コードを次のように変更します:

onFailure(request: ResumableUploadRequest, clientExcepion:ClientException?, serviceException: ServiceException?)