Tous les produits
Search
Centre de documentation

Object Storage Service:Foire aux questions (SDK Android)

Dernière mise à jour :Aug 18, 2026

Problèmes courants et solutions pour le SDK OSS pour Android.

Remarque

Avant d'utiliser l'exemple de code, installez le SDK HTTPDNS pour Android. Pour plus d'informations, consultez la rubrique Installer le SDK HTTPDNS pour Android.

Le SDK OSS pour Android prend-il en charge la pré-résolution DNS et les politiques de mise en cache ?

Oui. Utilisez conjointement le SDK HTTPDNS et OkHttp pour implémenter la pré-résolution DNS et la mise en cache.

  1. Implémentez l'API pour un service de résolution DNS personnalisé.

    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. Créez une instance OkHttpClient et configurez la pré-résolution DNS ainsi que la mise en 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);

Pourquoi le rappel de progression renvoie-t-il totalSize=-1 lors du téléchargement d'objets ?

  • Cause : Lorsqu'OkHttp télécharge des objets de certains types de contenu (text/cache-manifest, text/xml, text/plain, text/css, application/javascript, application/x-javascript, application/rss+xml, application/json, text/json) dont la taille est supérieure ou égale à 1 Ko, il ajoute automatiquement l'en-tête Accept-Encoding: gzip, même si vous ne l'avez pas défini. OSS renvoie alors l'objet au format gzip sans en-tête Content-Length, ce qui entraîne la valeur totalSize=-1 dans le rappel de progression.

  • Solution : Définissez un en-tête Range dans la requête. Cela empêche OkHttp d'ajouter Accept-Encoding: gzip, permettant ainsi à OSS de renvoyer l'en-tête Content-Length et au rappel de progression d'indiquer la taille correcte.

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

Rappel onFailure non déclenché dans Kotlin

  • Cause

Il s'agit d'un problème de nullabilité lié à Kotlin. Le SDK OSS pour Android définit le rappel onFailure en utilisant la syntaxe Java, où les paramètres sont non nullables par défaut :

@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 considère ces paramètres comme non nullables, ce qui peut empêcher le rappel de se déclencher comme prévu. Déclarez explicitement les paramètres comme nullables dans la signature de la fonction :

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