Разработка нативных приложений Tizen

Коммуникация по протоколу HTTP

Показывать лекцию целиком

Регистрация привилении

Коммуникация по протоколу HTTP используется для одновременной передачи большого объема данных. Это делает ее удобной для использования в мобильных приложениях. В этом разделе мы поговорим о том, что требуется для коммуникации и как загружать изображения с Интернета.

Создайте новый проект

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<manifest xmlns="http://tizen.org/ns/packages" api-version="2.3" package="org.example.httprequest" version="1.0.0">
<profile name="mobile"/>
<ui-application appid="org.example.httprequest" exec="httprequest" multiple="false" nodisplay="false" taskmanage="true" type="capp">
<label>httprequest</label>
<icon>httprequest.png</icon>
</ui-application>
<privileges>
<privilege>http://tizen.org/privilege/internet</privilege>
</privileges>
</manifest>

Запрос данных текстовой коммуникации

В этом разделе мы поговорим о реализации способности принимать текст с веб-сервера. Откройте файл исходного кода и внесите в него следующие изменения

#include "httprequest.h"

#include <curl/curl.h>
typedef struct MemoryStruct {
char *memory;
size_t size;
} memoryStruct;

typedef struct appdata {
Evas_Object *win;
Evas_Object *conform;
//Evas_Object *label;
Evas_Object *entry;
Evas_Object *icon;
memoryStruct ms;
} appdata_s;

Для коммуникации по протоколу HTTP используется библиотека CURL.

curl/curl.h — это заголовочный файл библиотеки CURL.

MemoryStruct — это структура в которой хранятся данные, полученные в результате коммуникации.

Icon — это объект Evas Image.

Мы реализуем возможность соединения с сервером и получение текстовых данных. Для этого нам потребуется добавить три функции выше create_base_gui().

static size_t
write_memory_cb(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
memoryStruct *mem = (memoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
dlog_print(DLOG_INFO, "tag", "not enough memory (realloc returned NULL)");
return 0;
}
memcpy((mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
void
get_http_data(const char* url, memoryStruct *data)
{
CURL *curl_handle;
CURLcode res;
data->memory = malloc(1); /* will be grown as needed by the realloc above */
data->size = 0;
/* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
/* specify URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_memory_cb);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)data);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* get it! */
res = curl_easy_perform(curl_handle);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
static void
btn_download_text(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = data;
char url[100]={0,};
sprintf(url, "http://api.openweathermap.org/data/2.5/weather?lat=37.498lon=127.027units=metric");
get_http_data(url, ad->ms);
elm_object_text_set(ad->label, ad->ms.memory);
free( ad->ms.memory);
}

write_memory_cb() - это функция события, которая принимает ответы от сервера. Ее параметры следующие: контент, блок байтов, размер памяти и данные пользователя.

Вы можете рассчитать общий объем памяти за счет умножения второго параметра а третий параметр. Блок байтов обычно равен 1.

Следующий код связывает память со свойством memory структуры memoryStruct, использующимся для функции realloc() и копирует данные с помощью функции memcpy().

Затем он добавляет размер памяти к свойству size структуры memoryStruct и заменяет конец данных нс 0 на метку завершения.

get_http_data() - это функция, которая пытается установить коммуникацию с сервером.

curl_global_init(long flags) - это API, который инициализирует библиотеку CURL. Для приложений, использующих CURL, этот API должен запускаться один раз в начале.

curl_easy_init(void) - это API, который создает объект CURL.

curl_easy_setopt(CURL *curl, CURLoption option, ...) - это API, который определяет опции для объекта CURL. Тип этих опции могут быть следующими:

  • CURLOPT_URL: определяет URL -адрес.
  • CURLOPT_WRITEFUNCTION: определяет вызывающую функцию, которая получает результаты коммуникации.
  • CURLOPT_WRITEDATA: определяет пользовательские данные.
  • CURLOPT_USERAGENT: определяет пользовательский агент.
  • curl_easy_perform(CURL *curl) — это API, который запускает коммуникацию с сервером.

    curl_easy_cleanup(CURL *curl) - это API, который удаляет данные CURL.

    curl_global_cleanup(void) — это API, который удаляет полные данные библиотеки CURL. После того, как CURL была использована, этот API должен быть вызван по меньшей мере раз перед закрытием приложения.

    btn_download_text() - это функция, которая при нажатии на кнопку получает текстовые данные с сервера и отображает результаты в метке.

    Запросим была ли передана информация о некотором месте с координатами 37.498 северной широты и 127.027 восточной долготы. Мы создадим кнопку, при нажатии на которую будут приниматься данные с сервера прогноза погоды. Добавьте код в конец функции create_base_gui() .

    /* Conformant */
    ad->conform = elm_conformant_add(ad->win);
    elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
    elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
    evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    elm_win_resize_object_add(ad->win, ad->conform);
    evas_object_show(ad->conform);
    
    /* Vertical box */
    Evas_Object *vbox = elm_box_add(ad->win);
    elm_box_padding_set(vbox, ELM_SCALE_SIZE(10), ELM_SCALE_SIZE(10));
    elm_object_content_set(ad->conform, vbox);
    evas_object_show(vbox);
    {
    /* Entry */
    ad->entry = elm_entry_add(ad->conform);
    evas_object_size_hint_weight_set(ad->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(ad->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
    elm_box_pack_end(vbox, ad->entry);
    evas_object_show(ad->entry);
    /* Button-1 */
    Evas_Object *btn = elm_button_add(ad->conform);
    elm_object_text_set(btn, "Text");
    evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0);
    evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0);
    evas_object_smart_callback_add(btn, "clicked", btn_download_text, ad);
    elm_box_pack_end(vbox, btn);
    evas_object_show(btn);
    }
    /* Show window after base gui is set up */
    evas_object_show(ad->win);
    }
    

    Мы создали элементы управления Box, Entry, и Button. Запустите пример. Нажмите на кнопку. На экране появятся данные о погоде в формате Json.

    Загрузка изображений

    В этом разделе мы реализуем возможность загружать изображения с сервера и отображать их в объекте Image. Добавьте код создания элементов управления Image и Button в функцию create_base_gui().

    {
    /* Entry */
    ad->entry = elm_entry_add(ad->conform);
    evas_object_size_hint_weight_set(ad->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(ad->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
    elm_box_pack_end(vbox, ad->entry);
    evas_object_show(ad->entry);
    /* Image */
    ad->icon = elm_image_add(ad->conform);
    evas_object_size_hint_weight_set(ad->icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(ad->icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
    elm_box_pack_end(vbox, ad->icon);
    evas_object_show(ad->icon);
    /* Button-1 */
    Evas_Object *btn = elm_button_add(ad->conform);
    elm_object_text_set(btn, "Text");
    evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0);
    evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0);
    evas_object_smart_callback_add(btn, "clicked", btn_download_text, ad);
    elm_box_pack_end(vbox, btn);
    evas_object_show(btn);
    /* Button-2 */
    btn = elm_button_add(ad->conform);
    elm_object_text_set(btn, "Image");
    evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0);
    evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0);
    evas_object_smart_callback_add(btn, "clicked", btn_download_image, ad);
    elm_box_pack_end(vbox, btn);
    evas_object_show(btn);
    }
    

    Мы создали объект Image и сохранили его в переменной icon структуры appdata. Затем мы создали вторую кнопку и определили имя вызывающей функции как btn_download_image. В заключение, нам нужно создать функцию -обработчик нажатия кнопки. Добавьте новую функцию выше create_base_gui() function.

    static void
    btn_download_image(void *data, Evas_Object *obj, void *event_info)
    {
    appdata_s *ad = data;
    char url[100]={0,};
    sprintf(url, "https://www.tizen.org/sites/all/themes/tizen_theme/logo.png");
    get_http_data(url, ad->ms);
    // update icon image.
    if ( elm_image_memfile_set( ad->icon, ad->ms.memory , ad->ms.size, "png", 0) == EINA_FALSE)
    {
    dlog_print(DLOG_DEBUG, "tag", "%s : image setting error " , __func__);
    }
    free( ad->ms.memory);
    }
    

    elm_image_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key) — это API, который вводит данные оригинального изображения в объект Evas Image. Его параметры следующие: объект Evas Image, image data, data size, и image type. Запустите пример. Убедитесь, что загруженная с Интернета картинка отображается на экране.

    Вернуться к учебному плану