1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/franklinyang-OkHttp3

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
README.md 48 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 06.06.2025 04:12 1e11793

OkHttp3

Библиотека для выполнения сетевых запросов, основанная на OkHttp3

Основные функции

  • Поддержка протоколов HTTP/HTTPS
  • Поддержка синхронных и асинхронных запросов
  • Поддержка асинхронного задержанного выполнения
  • Поддержка методов запросов POST/GET/Put/Delete
  • Поддержка сохранения куки, сжатия Gzip
  • Поддержка настройки заголовков запроса
  • Поддержка двоичных параметров, JSON, отправки форм
  • Поддержка автоматического преобразования Unicode, кодирования параметров запроса и настройки кодирования ответа сервера
  • Поддержка четырех типов кэширования запросов: только сеть, только кэш, сначала сеть, затем кэш, сначала кэш, затем сеть
  • Поддержка настройки времени жизни кэша и очистки кэша
  • Автоматическое отменение всех сетевых запросов при уничтожении Activity/Fragment, поддержка отмены конкретного запроса
  • Автоматическое переключение ответа асинхронного запроса на UI-поток, исключение использования runOnUiThread
  • Настройка глобальных параметров в Application, добавление системных параметров по умолчанию
  • Поддержка загрузки файлов и изображений, массовой загрузки, синхронной и асинхронной загрузки, поддержка отображения прогресса* Поддержка возобновления загрузки файлов, отдельный модуль загрузки, исключающий устаревший метод записи точек возобновления в базе данных
  • Полное отслеживание логов и обработка исключений
  • Поддержка перехвата результатов запросов и исключений
  • Поддержка одиночного клиента, повышающего скорость выполнения сетевых запросов
  • В процессе оптимизации...## Скриншоты

Демонстрация сетевых запросов

Демонстрация сначала сети, затем кэша

Демонстрация сначала кэша, затем сети

Интерфейс загрузки изображений

Интерфейс возобновления загрузки файлов

Логи

  • GET-URL/POST-URL: адрес запроса
  • CostTime: время выполнения запроса (в секундах)
  • Response: ответ сервера## Примеры проекта Проект включает все примеры поддерживаемых бизнес-функций. Подробности см. в исходном коде проекта. ## Способ использования

Maven

<dependency>
  <groupId>com.zhousf.lib</groupId>
  <artifactId>okhttp3</artifactId>
  <version>2.8.9</version>
  <type>pom</type>
</dependency>

Gradle

compile 'com.zhousf.lib:okhttp3:2.8.9'

Если возникает конфликт версий support-annotations, используйте следующий способ зависимости:

compile ('com.zhousf.lib:okhttp3:2.8.9'){
    exclude(module: 'support-annotations')
}

ProGuard

Если вы используете ProGuard для минификации, добавьте следующую конфигурацию:

-dontwarn okio.**

Записи коммитов

  • 29.06.2016 Загрузка проекта
  • 04.07.2016
    • Изменение структуры проекта
    • Добавление глобальной конфигурации в приложение
    • Добавление системных настроек по умолчанию
    • Исправление ошибки освобождения памяти
  • 19.07.2016
    • Оптимизация кода, снижение藕合,修复已知错误。
    • Оптимизация кода, снижение藕合,исправление известных ошибок.
  • 09.08.2016
    • Добавление функции загрузки файлов, поддержка загрузки нескольких файлов одновременно
  • 10.08.2016
    • Добавление функции загрузки файлов, поддержка загрузки нескольких файлов одновременно и возобновления загрузки
  • 10.10.2016
    • Добавление функции перехвата результатов запроса и перехвата исключений
  • 25.10.2016
    • Поддержка сохранения куки, настройка заголовков HTTP
  • 12.12.2016
    • Добавление единого клиента, повышение скорости сетевых запросов, возможность отмены конкретных запросов
  • 03.03.2017
      • Исправление ошибки в параметрах загрузки файлов (спасибо Sanqi5401 за указание)
      1. 2017
      1. 2017
    • Добавление функции одновременной загрузки нескольких файлов
      1. 2017
    • Добавление функции запроса двоичных потоков, в демонстрационном примере добавлена функция динамического запроса разрешений
      1. 2017
    • Поддержка запросов PUT и DELETE
      1. 2017
    • Поддержка асинхронного выполнения с задержкой## Разрешения
    <!-- Добавление разрешений на чтение и запись -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!-- Разрешение на доступ к интернету -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
```## Настройка глобальных параметровВ Application настроено следующее:
```java
         String downloadFileDir = Environment.getExternalStorageDirectory().getPath() + "/okHttp_download/";
         String cacheDir = Environment.getExternalStorageDirectory().getPath() + "/okHttp_cache";
         OkHttpUtil.init(context)
                 .setConnectTimeout(15) // Время ожидания подключения
                 .setWriteTimeout(15) // Время ожидания записи
                 .setReadTimeout(15) // Время ожидания чтения
                 .setMaxCacheSize(10 * 1024 * 1024) // Размер кэша
                 .setCacheType(CacheType.FORCE_NETWORK) // Тип кэширования
                 .setHttpLogTAG("HttpLog") // Идентификатор логов запросов
                 .setIsGzip(false) // Gzip-сжатие (требуется поддержка сервера)
                 .setShowHttpLog(true) // Показывать логи запросов
                 .setShowLifecycleLog(false) // Показывать логи жизненного цикла Activity
                 .setRetryOnConnectionFailure(false) // Не повторять подключение при ошибке
                 .setCachedDir(new File(cacheDir)) // Установить директорию кэша
                 .setDownloadFileDir(downloadFileDir) // Установить директорию для сохранения загруженных файлов
                 .setResponseEncoding(Encoding.UTF_8) // Установить кодировку ответа сервера
                 .setRequestEncoding(Encoding.UTF_8) // Установить кодировку запроса
                 .addResultInterceptor(HttpInterceptor.ResultInterceptor) // Добавить интерцептор для обработки результатов запроса
                 .addExceptionInterceptor(HttpInterceptor.ExceptionInterceptor) // Добавить интерцептор для обработки исключений запроса
                 .setCookieJar(new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context))) // Установить куки как персистентные
                 .build();
``````## Получение единого экземпляра клиентского объекта для сетевых запросов
 ```java
 //Получение единого экземпляра (по умолчанию)
 Метод 1: OkHttpUtil.getDefault(this)//Привязка к жизненному циклу
             .doGetSync(HttpInfo.Builder().setUrl(url).build());
 Метод 2: OkHttpUtil.getDefault()//Без привязки к жизненному циклу
             .doGetSync(HttpInfo.Builder().setUrl(url).build());
Рекомендуется использовать метод OkHttpUtil.getDefault(this) для привязки запросов к представлению. Этот метод автоматически отменяет все запросы, связанные с текущим представлением, при уничтожении Activity/Fragment.
Типы идентификаторов запросов поддерживают Object, String, Integer, Float, Double.
**<font color=red>Идентификатор запроса должен быть уникальным</font>**.
```java
//*******Привязка идентификатора запроса при отправке запроса*******/
//Метод 1:
OkHttpUtil.Builder()
                .setReadTimeout(120)
                .build("запрос_идентификатор")//Привязка идентификатора запроса
                .doDownloadFileAsync(info);
//Метод 2:
OkHttpUtil.getDefault("запрос_идентификатор")//Привязка идентификатора запроса
            .doGetSync(info);
            
//*******Отмена конкретного запроса*******/
OkHttpUtil.getDefault().cancelRequest("запрос_идентификатор");
 
```## Параметры HttpInfo:
 * Заполнение параметров в виде пар ключ-значение с помощью методов addParam/addParams
 * Отправка данных в формате JSON с помощью метода addParamJson
 * Отправка данных в формате формы с помощью метода addParamForm
 * Отправка данных в виде двоичного потока с помощью метода addParamBytes
 * Загрузка файлов с помощью метода addDownloadFile
 * Загрузка файлов на сервер с помощью метода addUploadFile
 ```java
 HttpInfo.Builder()
         .setUrl(url)
         .setRequestType(RequestType.GET) //Тип запроса
         .addHead("head", "test") //Добавление заголовков
         .addParam("param", "test") //Добавление параметров запроса
         .addParams(new HashMap<String, String>()) //Добавление коллекции параметров запроса
         .addParamBytes("byte") //Добавление двоичного потока
         .addParamJson("json") //Добавление параметров в формате JSON
         .addParamFile(new File("")) //Добавление параметров в виде файла
         .addParamForm("form") //Добавление параметров в виде формы
         .addDownloadFile(new DownloadFileInfo("fileURL", "myMP4", null)) //Добавление параметров для загрузки файла
         .addUploadFile("interfaceParamName", "filePathWithName", null) //Добавление параметров для загрузки файла на сервер
         .setResponseEncoding(Encoding.UTF_8) //Установка кодировки ответа сервера
         .setRequestEncoding(Encoding.UTF_8) //Установка кодировки параметров запроса
         .setDelayExec(2, TimeUnit.SECONDS) //Задержка выполнения на 2 секунды
         .build()

Пример синхронного вызова в Activity

    /**
     * Синхронный запрос: поскольку сетевые операции не могут выполняться в UI-потоке, используется поток подзадач
     */
    private void sync() {
```        new Thread(new Runnable() {
            @Override
            public void run() {
                final HttpInfo info = HttpInfo.Builder()
                        .setUrl(url)
                        .setResponseEncoding(Encoding.UTF_8) // Установка кодировки ответа сервера для данного интерфейса
                        .setRequestEncoding(Encoding.UTF_8) // Установка кодировки запроса для данного интерфейса
                        .build();
                OkHttpUtil.getDefault(this)
                        .doGetSync(info);
                final String result = info.getRetDetail();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        resultTV.setText("Синхронный запрос: " + result);
                        setFromCacheTV(info);
                    }
                });
            }
        });```java
                   }
               });
           }
       }).start();
   }

Пример асинхронного вызова в Activity

    /**
     * Асинхронный запрос: метод обратного вызова может напрямую управлять UI
     */
    private void async() {
        OkHttpUtil.getDefault(this).doGetAsync(
                HttpInfo.Builder().setUrl(url).build(),
                new Callback() {
                    @Override
                    public void onFailure(HttpInfo info) throws IOException {
                        String result = info.getRetDetail();
                        resultTV.setText("Асинхронный запрос не удался: " + result);
                    }

                    @Override
                    public void onSuccess(HttpInfo info) throws IOException {
                        String result = info.getRetDetail();
                        resultTV.setText("Асинхронный запрос удался: " + result);
                        // Парсинг с помощью Gson
                        TimeAndDate time = new Gson().fromJson(result, TimeAndDate.class);
                        LogUtil.d("MainActivity", time.getResult().toString());
                        setFromCacheTV(info);
                    }
                });
    }

Только сетевой запрос

    /**
     * Только сетевой запрос
     */
    private void forceNetwork() {
        OkHttpUtil.Builder().setCacheType(CacheType.FORCE_NETWORK).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("FORCE_NETWORK: " + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("FORCE_NETWORK: " + info.getRetDetail());
                            }
                        }
                );
    }
```## Только кэширование запроса
```java
    /**
     * Только кэширование запроса
     */
    private void forceCache(){
        OkHttpUtil.Builder().setCacheType(CacheType.FORCE_CACHE).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("FORCE_CACHE: " + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("FORCE_CACHE: " + info.getRetDetail());
                            }
                        }
                );
    }

Сначала сеть, затем кэш

    /**
     * Сначала сеть, затем кэш: сначала запрос к сети, при неудаче — к кэшу
     */
    private void networkThenCache() {
        OkHttpUtil.Builder().setCacheType(CacheType.NETWORK_THEN_CACHE).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("NETWORK_THEN_CACHE: " + result);
                                setFromCacheTV(info);
                            }
``````java
    /**
     * Сначала кэш, потом сеть: сначала запрашиваем кэш, если неудача, запрашиваем сеть
     */
    private void cacheThenNetwork() {
        OkHttpUtil.Builder().setCacheType(CacheType.CACHE_THEN_NETWORK).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("CACHE_THEN_NETWORK:" + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("NETWORK_THEN_CACHE:" + info.getRetDetail());
                            }
                        }
                );
    }
``````java
    /**
     * Кэш, который истекает через 10 секунд: нажмите кнопку для тестирования, чтобы убедиться, что запросы в течение 10 секунд являются кэшированными, а запросы после 10 секунд запрашивают сеть
     */
    private void tenSecondCache(){
        //Используя один и тот же URL для тестирования, необходимо очистить кэш
        if(isNeedDeleteCache){
            isNeedDeleteCache = false;
            OkHttpUtil.getDefault().deleteCache();
        }
        OkHttpUtil.Builder()
                .setCacheType(CacheType.CACHE_THEN_NETWORK)
                .setCacheSurvivalTime(10)//Время жизни кэша 10 секунд
                .build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("Кэш, который истекает через 10 секунд: " + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("CACHE_THEN_NETWORK: " + info.getRetDetail());
                            }
                        }
                );
    }
                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("Кэш, который истекает через 10 секунд: " + info.getRetDetail());
                            }
                        }
                );
    }
```## Пример загрузки изображения в Activity
```java
/**
 * Асинхронная загрузка изображения: отображение прогресса загрузки
 */
private void doUploadImg() {
    HttpInfo info = HttpInfo.Builder()
            .setUrl(url)
            .addUploadFile("file", filePathOne, new ProgressCallback() {
                // onProgressMain — обратный вызов для UI-потока, который позволяет напрямую управлять UI
                @Override
                public void onProgressMain(int percent, long bytesWritten, long contentLength, boolean done) {
                    uploadProgressOne.setProgress(percent);
                    LogUtil.d(TAG, "Загрузка: " + percent);
                }
            })
           . build();
    OkHttpUtil.getDefault(this).doUploadFileAsync(info);
}
```## Пример однократной загрузки нескольких файлов в Activity
* Если сервер использует PHP, то для массива параметров следует добавить "[]" к имени параметра,
Пример: builder.addUploadFile("<font color=red>uploadFile[]</font>", path);
```java
/**
 * Однократная загрузка нескольких файлов: загрузка нескольких файлов в одном запросе
 */
private void doUploadBatch() {
    imgList.clear();
    imgList.add("/storage/emulated/0/okHttp_download/test.apk");
    imgList.add("/storage/emulated/0/okHttp_download/test.rar");
    HttpInfo.Builder builder = HttpInfo.Builder()
            .setUrl(url);
    // Цикл для добавления загружаемых файлов
    for (String path : imgList) {
        // Если сервер использует PHP, то для массива параметров следует добавить "[]" к имени параметра,
        // Пример: builder.addUploadFile("uploadFile[]", path);
        builder.addUploadFile("uploadFile", path);
    }
    HttpInfo info = builder.build();
    OkHttpUtil.getDefault(UploadFileActivity.this).doUploadFileAsync(info, new ProgressCallback() {
        @Override
        public void onProgressMain(int percent, long bytesWritten, long contentLength, boolean done) {
            uploadProgress.setProgress(percent);
        }

        @Override
        public void onResponseMain(String filePath, HttpInfo info) {
            LogUtil.d(TAG, "Результат загрузки: " + info.getRetDetail());
            tvResult.setText(info.getRetDetail());
        }
    });
}
```## Пример скачивания файла с остановками в активити
```java
@OnClick({R.id.downloadBtn, R.id.pauseBtn, R.id.continueBtn})
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.downloadBtn: // Скачивание
            download();
            break;
        case R.id.pauseBtn: // Остановка скачивания
            if (null != fileInfo)
                fileInfo.setDownloadStatus(DownloadStatus.PAUSE);
            break;
        case R.id.continueBtn: // Продолжение скачивания
            download();
            break;
    }
}
``````java
private void download() {
    if (null == fileInfo)
        fileInfo = new DownloadFileInfo(url, "fileName", new ProgressCallback() {
            @Override
            public void onProgressMain(int percent, long bytesWritten, long contentLength, boolean done) {
                downloadProgress.setProgress(percent);
                tvResult.setText(percent + "%");
                LogUtil.d(TAG, "Скачивание прогресс: " + percent);
            }

            @Override
            public void onResponseMain(String filePath, HttpInfo info) {
                if (info.isSuccessful()) {
                    tvResult.setText(info.getRetDetail() + "\nСостояние скачивания: " + fileInfo.getDownloadStatus());
                } else {
                    Toast.makeText(DownloadBreakpointsActivity.this, info.getRetDetail(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    HttpInfo info = HttpInfo.Builder().addDownloadFile(fileInfo).build();
    OkHttpUtil.Builder().setReadTimeout(120).build(this).doDownloadFileAsync(info);
}

Пример запроса с использованием двоичного потока

HttpInfo info = new HttpInfo.Builder()
        .setUrl("http://192.168.120.154:8082/StanClaimProd-app/surveySubmit/getFileLen")
        .addParamBytes(byte) // Добавление двоичного потока
        .build();
OkHttpUtil.getDefault().doPostAsync(info, new Callback() {
    @Override
    public void onSuccess(HttpInfo info) throws IOException {
        String result = info.getRetDetail();
        resultTV.setText("Запрос неудачен: " + result);
    }
});
```    @Override
    public void onFailure(HttpInfo info) throws IOException {
        resultTV.setText("Запрос успешен: " + info.getRetDetail());
    }
});
```## Пример интерцептора для предварительной обработки результатов запроса/интерцептора для перехвата информации об исключениях в цепочке запросов
Интерцепторы для предварительной обработки результатов запроса и перехвата информации об исключениях в цепочке запросов облегчают управление и настройку возвратных данных при выполнении сетевых запросов в проекте.
```java
/**
 * Http-интерцептор
 * 1. Интерцептор для предварительной обработки результатов запроса
 * 2. Интерцептор для перехвата информации об исключениях в цепочке запросов
 * @author zhousf
 */
public class HttpInterceptor {
```    /**
     * Интерцептор для предварительной обработки результатов запроса.
     * Этот интерцептор предварительно обрабатывает результаты всех сетевых запросов и изменяет их.
     */
    public static ResultInterceptor ResultInterceptor = new ResultInterceptor() {
        @Override
        public HttpInfo intercept(HttpInfo info) throws Exception {
            // Предварительная обработка результатов запроса: можно фильтровать и парсить с помощью Gson
            return info;
        }
    };    /**
      * Интерцептор для перехвата информации об исключениях в цепочке запросов
      * Этот интерцептор перехватывает информацию об исключениях, возникающих при отправке сетевых запросов
      */
     public static ExceptionInterceptor ExceptionInterceptor = new ExceptionInterceptor() {
         @Override
         public HttpInfo intercept(HttpInfo info) throws Exception {
             switch (info.getRetCode()){
                 case HttpInfo.NonNetwork:
                     info.setRetDetail("Сетевое соединение прервано");
                     break;
                 case HttpInfo.CheckURL:
                     info.setRetDetail("Неверный сетевой адрес [" + info.getNetCode() + "]");
                     break;
                 case HttpInfo.ProtocolException:
                     info.setRetDetail("Неверный тип протокола [" + info.getNetCode() + "]");
                     break;
                 case HttpInfo.CheckNet:
                     info.setRetDetail("Проверьте, что сетевое соединение установлено [" + info.getNetCode() + "]");
                     break;
                 case HttpInfo.ConnectionTimeOut:
                     info.setRetDetail("Соединение прервано по таймауту");
                     break;
                 case HttpInfo.WriteAndReadTimeOut:
                     info.setRetDetail("Превышено время ожидания чтения и записи");
                     break;
                 case HttpInfo.ConnectionInterruption:
                     info.setRetDetail("Соединение прервано");
                     break;
             }
             return info;
         }
     };
 }
 
 ## Пример сохранения куки
 В случае, когда глобальная конфигурация куки для приложения не настроена, можно использовать следующий подход:
 ```java
 OkHttpUtilInterface okHttpUtil = OkHttpUtil.Builder()
             .setCacheLevel(FIRST_LEVEL)
             .setConnectTimeout(25).build(this);
 // один объект okHttpUtil представляет один сетевой соединение
 okHttpUtil.doGetAsync(
                 HttpInfo.Builder().setUrl(url).build(),
                 new CallbackOk() {
                     @Override
                     public void onResponse(HttpInfo info) throws IOException {
                         if (info.isSuccessful()) {
                             String result = info.getRetDetail();
                             resultTV.setText("Асинхронный запрос: " + result);
                         }
                     }
                 });
 ```## Обратная связь
 Если у вас возникли какие-либо проблемы во время использования, пожалуйста, сообщите мне об этом. Вы можете связаться со мной по следующим контактам:* QQ: 424427633

## Благодарности
Благодарю следующие проекты, порядок не имеет значения:

* [OkHttp](https://github.com/square/okhttp/)
* [PersistentCookieJar](https://github.com/franmontiel/PersistentCookieJar)

## Связанные примеры

### Интерфейс OkHttpUtil
```java
/**
 * Интерфейс для сетевых запросов
 * @author zhousf
 */
public interface OkHttpUtilInterface {

    /**
     * Синхронный POST-запрос
     * @param info тело запроса
     * @return HttpInfo
     */
    HttpInfo doPostSync(HttpInfo info);

    /**
     * Синхронный POST-запрос
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для отслеживания прогресса
     * @return HttpInfo
     */
    HttpInfo doPostSync(HttpInfo info, ProgressCallback callback);

    /**
     * Асинхронный POST-запрос
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для получения результата
     */
    void doPostAsync(HttpInfo info, BaseCallback callback);

    /**
     * Асинхронный POST-запрос
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для отслеживания прогресса
     */
    void doPostAsync(HttpInfo info, ProgressCallback callback);

    /**
     * Синхронный GET-запрос
     * @param info тело запроса
     */
    HttpInfo doGetSync(HttpInfo info);

    /**
     * Асинхронный GET-запрос
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для получения результата
     */
    void doGetAsync(HttpInfo info, BaseCallback callback);

    /**
     * Асинхронная загрузка файла
     * @param info тело запроса
     */
    void doUploadFileAsync(final HttpInfo info);

    /**
     * Асинхронная загрузка нескольких файлов
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для отслеживания прогресса
     */
    void doUploadFileAsync(final HttpInfo info, ProgressCallback callback);
``````java
    /**
     * Синхронная загрузка файла
     * @param info тело запроса
     */
    void doUploadFileSync(final HttpInfo info);

    /**
     * Синхронная загрузка нескольких файлов
     * @param info тело запроса
     * @param callback интерфейс обратного вызова для отслеживания прогресса
     */
    void doUploadFileSync(final HttpInfo info, ProgressCallback callback);

    /**
     * Асинхронная загрузка файла
     * @param info тело запроса
     */
    void doDownloadFileAsync(final HttpInfo info);

    /**
     * Синхронная загрузка файла
     * @param info тело запроса
     */
    void doDownloadFileSync(final HttpInfo info);

    /**
     * Синхронный запрос DELETE
     * @param info тело запроса
     * @return HttpInfo
     */
    HttpInfo doDeleteSync(HttpInfo info);

    /**
     * Асинхронный запрос DELETE
     * @param info тело запроса
     * @param callback интерфейс обратного вызова результата
     */
    void doDeleteAsync(HttpInfo info, BaseCallback callback);

    /**
     * Синхронный запрос PUT
     * @param info тело запроса
     * @return HttpInfo
     */
    HttpInfo doPutSync(HttpInfo info);

    /**
     * Асинхронный запрос PUT
     * @param info тело запроса
     * @param callback интерфейс обратного вызова результата
     */
    void doPutAsync(HttpInfo info, BaseCallback callback);

    /**
     * Отмена запроса
     * @param requestTag идентификатор запроса
     */
    void cancelRequest(Object requestTag);

    /**
     * Получение по умолчанию HttpClient
     */
    OkHttpClient getDefaultClient();

    /**
     * Очистка кэша: очистка только кэша сетевых запросов, не очистка загруженных файлов
     */
    boolean deleteCache();

}

MainActivity


/**
 * Сетевые запросы: поддерживают синхронные/асинхронные, GET/POST, кэшированные запросы
 *
 * @author zhousf
 */
public class MainActivity extends BaseActivity {
```    @Bind(R.id.fromCacheTV)
    TextView fromCacheTV;
    @Bind(R.id.resultTV)
    TextView resultTV;
    /**
     * Внимание: при тестировании замените этот адрес
     */
    private String url = "http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";

    private boolean isNeedDeleteCache = true;

    @Override
    protected int initLayout() {
        return R.layout.activity_main;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }    @Override
    protected void onStart() {
        super.onStart();
    }

    @OnClick({
        R.id.sync_btn,
        R.id.async_btn,
        R.id.force_network_btn,
        R.id.force_cache_btn,
        R.id.network_then_cache_btn,
        R.id.cache_then_network_btn,
        R.id.ten_second_cache_btn,
        R.id.delete_cache_btn
    })
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.sync_btn: //синхронный запрос
                sync();
                break;
            case R.id.async_btn: //асинхронный запрос
                async();
                break;
            case R.id.force_network_btn: //только сеть
                forceNetwork();
                break;
            case R.id.force_cache_btn: //только кэш
                forceCache();
                break;
            case R.id.network_then_cache_btn: //сначала сеть, затем кэш
                networkThenCache();
                break;
            case R.id.cache_then_network_btn: //сначала кэш, затем сеть
                cacheThenNetwork();
                break;
            case R.id.ten_second_cache_btn: //кэш 10 секунд
                tenSecondCache();
                break;
            case R.id.delete_cache_btn: //очистить кэш
                deleteCache();
                break;
        }
    }

    /**
     * Синхронный запрос: поскольку нельзя выполнять сетевые запросы в UI-потоке, используется поток подзадач
     */
    private void sync() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                final HttpInfo info = HttpInfo.Builder()
                        .setUrl(url)
                        .setResponseEncoding(Encoding.UTF_8) // Установка кодировки ответа сервера
                        .build();
                OkHttpUtil.getDefault(this)
                        .doGetSync(info);
                final String result = info.getRetDetail();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        resultTV.setText("Синхронный запрос: " + result);
setFromCacheTV(info);
}
});
});
}).start();
needDeleteCache(true);
}    /**
     * Асинхронный запрос: метод обратного вызова может напрямую работать с UI
     */
    private void async() {
        OkHttpUtil.getDefault(this).doGetAsync(
                HttpInfo.Builder().setUrl(url).build(),
                new Callback() {
                    @Override
                    public void onFailure(HttpInfo info) throws IOException {
                        String result = info.getRetDetail();
                        resultTV.setText("Асинхронный запрос завершился ошибкой: " + result);
                    }

                    @Override
                    public void onSuccess(HttpInfo info) throws IOException {
                        String result = info.getRetDetail();
                        resultTV.setText("Асинхронный запрос завершился успешно: " + result);
                        // Парсинг с помощью Gson
                        TimeAndDate time = new Gson().fromJson(result, TimeAndDate.class);
                        LogUtil.d("MainActivity", time.getResult().toString());
                        setFromCacheTV(info);
                    }
                });
        needDeleteCache(true);
    }    /**
     * Только сетевой запрос
     */
    private void forceNetwork(){
        OkHttpUtil.Builder().setCacheType(CacheType.FORCE_NETWORK).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("FORCE_NETWORK: " + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("FORCE_NETWORK: " + info.getRetDetail());
                            }
                        }
                );
        needDeleteCache(true);
    }    /**
     * Только кэшированный запрос
     */
    private void forceCache(){
        OkHttpUtil.Builder().setCacheType(CacheType.FORCE_CACHE).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("FORCE_CACHE:" + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("FORCE_CACHE:" + info.getRetDetail());
                            }
                        }
                );
        needDeleteCache(true);
    }

    /**
     * Сначала сеть, затем кэш: сначала запрос к сети, если неудачно, то к кэшу
     */
    private void networkThenCache() {
        OkHttpUtil.Builder().setCacheType(CacheType.NETWORK_THEN_CACHE).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("NETWORK_THEN_CACHE:" + result);
                                setFromCacheTV(info);
                            }                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("СЕТЬ_ЗАТЕМ_КАША:" + info.getRetDetail());
                            }
                        }
                );
        needDeleteCache(true);
    }    
    /**
     * Сначала кэш, затем сеть: сначала запрашиваем кэш, если неудача, запрашиваем сеть
     */
    private void cacheThenNetwork() {
        OkHttpUtil.Builder().setCacheType(CacheType.CACHE_THEN_NETWORK).build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("КАША_ЗАТЕМ_СЕТЬ:" + result);
                                setFromCacheTV(info);
                            }
                        }
                );
    }```markdown
                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("CACHE_THEN_NETWORK:" + info.getRetDetail());
                            }
                        }
                );
        needDeleteCache(true);
    }

    /**
     * Кэш 10 секунд: непрерывное нажатие для тестирования, запросы в течение 10 секунд будут отвечены кэшем, запросы после 10 секунд приведут к истечению срока действия кэша и запросу сети
     */
    private void tenSecondCache(){
        //Используя один и тот же URL для тестирования, необходимо сначала очистить кэш
        if(isNeedDeleteCache){
            isNeedDeleteCache = false;
            OkHttpUtil.getDefault().deleteCache();
        }
        OkHttpUtil.Builder()
                .setCacheType(CacheType.CACHE_THEN_NETWORK)
                .setCacheSurvivalTime(10)//Срок службы кэша 10 секунд
                .build(this)
                .doGetAsync(
                        HttpInfo.Builder().setUrl(url).build(),
                        new Callback() {
                            @Override
                            public void onSuccess(HttpInfo info) throws IOException {
                                String result = info.getRetDetail();
                                resultTV.setText("Кэш 10 секунд:" + result);
                                setFromCacheTV(info);
                            }

                            @Override
                            public void onFailure(HttpInfo info) throws IOException {
                                resultTV.setText("Кэш 10 секунд:" + info.getRetDetail());
                            }
                        }
                );
    }

    private void needDeleteCache(boolean delete){
        isNeedDeleteCache = delete;
    }

    private void setFromCacheTV(HttpInfo info){
        fromCacheTV.setText(info.isFromCache() ? "Запрос из кэша" : "Запрос из сети");
    }
```    /**
     * Очистка кэша
     */
    private void deleteCache(){
        if (OkHttpUtil.getDefault().deleteCache()){
            ToastUtil.show(this, "Кэш успешно очищен");
        } else {
            ToastUtil.show(this, "Не удалось очистить кэш");
        }
    }

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/franklinyang-OkHttp3.git
git@api.gitlife.ru:oschina-mirror/franklinyang-OkHttp3.git
oschina-mirror
franklinyang-OkHttp3
franklinyang-OkHttp3
master