このトピックでは、Object Storage Service (OSS) SDK for Androidを使用する際によく寄せられる質問に対する回答を提供します。
サンプルコードを使用する前に、HTTPDNS SDK for Androidをインストールする必要があります。 詳細については、「HTTPDNS SDK For Androidのインストール」をご参照ください。
OSS SDK for AndroidはDNS事前解決とキャッシュポリシーをサポートしていますか?
はい、OSS SDK for AndroidはDNS事前解決とキャッシュポリシーをサポートしています。 次のサンプルコードは、OSS SDK for AndroidをHTTPDNS SDKおよびOkHttpと共に使用してDNS事前解決およびキャッシュポリシーを実装する方法の例を示しています。
カスタムDNS解決サービスのAPIを実装します。
パブリッククラスOkHttpDnsがDnsを実装 { プライベート静的最終Dns SYSTEM = Dns.SYSTEM; HttpDnsService httpdns; プライベート静的OkHttpDnsインスタンス=null; プライベートOkHttpDns (コンテキストコンテキスト) { this.httpdns = HttpDns.getService (コンテキスト、"account id"); } public static OkHttpDns getInstance (コンテキストコンテキスト) { if(instance == null) { instance = new OkHttpDns (コンテキスト); } インスタンスを返します。 } @オーバーライド public List<InetAddress> lookup(String hostname) throws UnknownHostException { // 非同期解析操作を使用してIPアドレスを取得します。 文字列ip = httpdns.getIpByHostAsync (ホスト名); if(ip! =null) { // 返されたIPアドレスがnullでない場合は、返されたIPアドレスを使用してリクエストを送信します。 List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip)); Log.e("OkHttpDns" 、"inetAddresses:" + inetAddresses); inetAddressesを返します。 } // 返されたIPアドレスがnullの場合は、システムDNSサービスを使用してドメイン名を解決します。 Dns.SYSTEM.lookup (ホスト名) を返します。 } }
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); // The maximum number of concurrent requests. 既定値:5 conf.setMaxErrorRetry(2); // リトライの最大数。 デフォルト値:2 OkHttpClient.Builder builder = new OkHttpClient.Builder() . dns(OkHttpDns.getInstance(getApplicationContext())); // okHttpClientにカスタム値が指定されている場合、一部のClientConfiguration設定は無効になり、ビルダーで手動で指定する必要があります。 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()) . ディスパッチャー (ディスパッチャー); if (conf.getProxyHost() != null && conf.getProxyPort() != 0) { builder.proxy (新しいプロキシ (Proxy.Type.HTTP, new InetSocketAddress(conf.getProxyHost(), conf.getProxyPort()))); } } // Android 2.9.12以降のOSS SDKのみが、conf.setOkHttpClient(); メソッドをサポートしています。 conf.setOkHttpClient(builder.build()); OSS oss = new OSSClient(getApplicationContext() 、endpoint、credentialProvider、conf);
オブジェクトをダウンロードすると、プログレスコールバックがtotalSize=-1を返すのはなぜですか?
原因:
リクエストにAccept-Encoding:gzipヘッダーを明示的に指定して、Content-Typeがtext/cache-manifest、text/xml、text/plain、text/css、application/javascript、application/x-javascript、application/rss + xml、application/json、またはtext/jsonで、サイズが1 KB以上のオブジェクトをダウンロードする場合、OSSはgzip形式でデータを返します。 このようなオブジェクトをダウンロードするときにリクエストにAccept-Encodingヘッダーが指定されていない場合でも、OkHttpは自動的にAccept-Encoding:gzipをリクエストに含め、OSSはgzip形式のデータを返します。 OSSは、gzip形式のオブジェクトのサイズを識別できず、Content-Lengthレスポンスヘッダーを返しません。 この場合、進行コールバックは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 (新しいRange(0, -1)); get.setRequestHeaders (ヘッダー); OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() { @オーバーライド 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(); } } @オーバーライド 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()); } } });