Todos os produtos
Search
Central de documentação

Object Storage Service:Perguntas frequentes (Android SDK)

Última atualização: Jul 03, 2026

Problemas comuns e soluções do OSS SDK for Android.

Nota

Antes de usar o código de exemplo, instale o HTTPDNS SDK for Android. Para mais informações, consulte Instale o HTTPDNS SDK for Android.

O OSS SDK for Android oferece suporte a pré-resolução de DNS e políticas de cache?

Sim. Use o HTTPDNS SDK com o OkHttp para implementar a pré-resolução de DNS e o cache.

  1. Implemente a API de um serviço personalizado de resolução de 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 {
            // Use the asynchronous resolution API to get the IP address.
            String ip = httpdns.getIpByHostAsync(hostname);
            if(ip != null) {
                // IP address resolved — use it for the network request.
                List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
                Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
                return inetAddresses;
            }
            // No IP address resolved — fall back to the system DNS service.
            return Dns.SYSTEM.lookup(hostname);
        }
    }
  2. Crie uma instância de OkHttpClient e configure a pré-resolução de DNS e o cache.

    String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    ClientConfiguration conf = new ClientConfiguration();
    conf.setConnectionTimeout(15 * 1000); // Connection timeout. Default: 15 seconds.
    conf.setSocketTimeout(15 * 1000); // Socket timeout. Default: 15 seconds.
    conf.setMaxConcurrentRequest(5); // Maximum concurrent requests. Default: 5.
    conf.setMaxErrorRetry(2); // Maximum retries. Default: 2.
    OkHttpClient.Builder builder = new OkHttpClient.Builder()
            .dns(OkHttpDns.getInstance(getApplicationContext()));
    // If you set a custom OkHttpClient, it overrides some ClientConfiguration settings.
    // Set those settings directly on the 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 and later support conf.setOkHttpClient().
    conf.setOkHttpClient(builder.build());
    OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);

Por que o callback de progresso retorna totalSize=-1 ao baixar objetos?

  • Causa: Ao baixar objetos de determinados tipos de conteúdo (text/cache-manifest, text/xml, text/plain, text/css, application/javascript, application/x-javascript, application/rss+xml, application/json, text/json) com tamanho igual ou superior a 1 KB, o OkHttp adiciona automaticamente o cabeçalho Accept-Encoding: gzip, mesmo sem definição explícita. Assim, o OSS retorna o objeto em formato gzip sem o cabeçalho Content-Length, fazendo o callback de progresso reportar totalSize=-1.

  • Solução: Defina um cabeçalho Range na solicitação. Isso impede que o OkHttp adicione o Accept-Encoding: gzip, permitindo que o OSS retorne o Content-Length e o callback de progresso informe o tamanho correto.

    Map<String, String> header = new HashMap<>();
    header.put("x-oss-range-behavior", "standard");
    // Replace examplebucket with your bucket name and exampledir/exampleobject.txt with the full object path.
    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) {
                    // Process the downloaded data.
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
            if (clientExcepion != null) {
                // Handle a local exception, such as a network error.
                clientExcepion.printStackTrace();
            }
            if (serviceException != null) {
                // Handle a service exception.
                Log.e("ErrorCode", serviceException.getErrorCode());
                Log.e("RequestId", serviceException.getRequestId());
                Log.e("HostId", serviceException.getHostId());
                Log.e("RawMessage", serviceException.getRawMessage());
            }
        }
    });

Callback onFailure não acionado no Kotlin

  • Causa

Esse comportamento decorre da nulabilidade do Kotlin. O OSS Android SDK define o callback onFailure com sintaxe Java, na qual os parâmetros são não nulos por padrão:

@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());
    }
}

O Kotlin trata esses parâmetros como não nulos, o que pode impedir o acionamento esperado do callback. Declare explicitamente os parâmetros como anuláveis na assinatura da função:

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