用C++ REST SDK瞄准Android

就在假期之前,我们发布了一个新版本,版本2.4.0 C++静态SDK . 库中添加的新特性之一是支持使用 Visual Studio 2015跨平台移动版 以及x86 Android仿真器。在这篇文章中,我将介绍如何创建一个使用C++ REST SDK的Android本地活动。

null

创建新的Android本机活动

在Visual C++ ->跨平台中使用本地活动应用程序(Android)项目模板创建一个新的Android应用程序。

图片[1]-用C++ REST SDK瞄准Android-yiteyi-C++库

一旦模板完成,你将有一个Android应用程序,当运行时,将通过在屏幕上显示纯色循环,如果触摸屏幕改变颜色。接下来,让我们安装C++ StestSDK来与应用程序一起使用。

添加C++ REST SDK NuGET封装

为了让瞄准Android成为一种简单的体验,我们发布了 NuGet包 对于Android的C++ REST SDK。该软件包包括针对ARM设备和x86仿真器的二进制文件。通过右键单击本机活动项目并单击“管理NuGet包…”,可以添加对NuGet包的引用。一旦对话框开始,搜索C++ REST SDK并选择Android包:

图片[2]-用C++ REST SDK瞄准Android-yiteyi-C++库

单击“安装”VisualStudio将负责下载C++ REST SDK包、其依赖关系、设置包含路径以及与正确的库链接。接下来,您需要对项目的C++属性做一些更改,以便使用C++ REST SDK。默认的Android模板不能启用C++休眠SDK所需要的所有C++特性。调出添加NuGet包的项目的配置属性,并进行以下更改:

  • C++ 11的更新:C+++语言-> C++语言标准= C++ 11
  • 打开C++异常:C++ +代码生成->启用C++异常=是
  • 更改为使用GNU标准库:General->use of STL=gnustlu static
  • 打开RTT:C++ +>语言->启用运行时类型信息=

C++ REST SDK是关于连接到服务的,所以为了使我们的Android应用能够访问Internet,需要将权限添加到清单中。打开AndroidManifest.xml文件并插入uses权限标记:

 ... <!-- This is the platform API where NativeActivity was introduced. --> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19"/>  <!-- Internet permissions --> <uses-permission android:name="android.permission.INTERNET" />  <!-- This .apk has no Java code itself, so set hasCode to false. --> <application android:label="@string/app_name" android:hasCode="false" android:debuggable="true"> ...

最后一个需要做的改变是在调用库中的任何API之前,用java虚拟机(JVM)初始化C++ REST SDK。这是通过调用cpprestu init函数来完成的。对于本机活动,最容易在androidu主入口点函数中添加cpprestu init调用。您可以从android应用程序结构访问JVM。将以下函数调用添加到您的androidu main:

/** * This is the main entry point of a native application that is using * android_native_app_glue. It runs in its own thread, with its own * event loop for receiving input events and doing other things. */ void android_main(struct android_app* state) {      cpprest_init(state->activity->vm);      struct engine engine; ...

如果您正在创建一个共享库而不是一个本机活动,那么您只需在JNIu OnLoad函数中调用cpprestu init(…)。现在应用程序都被设置为使用C++ REST SDK启动。

演练用C++ REST SDK请求

对于这个简单的演练,我们将修改应用程序,使其在触屏时向服务器发出HTTP请求。为此,我们将使用 httpU客户端 ,因此在main.cpp的顶部添加以下include和using namespace语句:

 #include <cpprest/http_client.h>  using namespace web::http; using namespace web::http::client;

我们将使用一个布尔变量来跟踪HTTP请求是否失败。在文件顶部找到struct savedu state声明,并添加一个新的布尔字段调用requestFailed:

 /** * Our saved state data. */ struct saved_state {    float angle;    int32_t x;    int32_t y;    bool requestFailed; };

如果HTTP请求失败,我们将使整个屏幕变成红色,而不是继续循环并在屏幕上显示不同的颜色。找到engineu drawu frame函数并检查引擎中保存的状态。如果请求失败,则调用glClearColor将颜色设置为红色。engineu drawu frame函数应如下所示:

/*** Just the current frame in the display.*/static void engine_draw_frame(struct engine* engine) {    if (engine->display == NULL) {        // No display.        return;    }    if (engine->state.requestFailed)    {        // Fill screen with RED color.        glClearColor(1, 0, 0, 1);    }    else    {        // Just fill the screen with a color.        glClearColor(((float) engine->state.x) / engine->width, engine->state.angle,((float) engine->state.y) / engine->height, 1);    }     glClear(GL_COLOR_BUFFER_BIT);    eglSwapBuffers(engine->display, engine->surface);} 

接下来添加代码以实际发出HTTP请求。找到engineu handleu input函数并将和HTTP请求发送到 http://www.bing.com ,如果发生动作按下事件。它应该是这样的:

/*** Process the next input event.*/static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {    struct engine* engine = (struct engine*)app->userData;    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {        engine->state.x = AMotionEvent_getX(event, 0);        engine->state.y = AMotionEvent_getY(event, 0);         // Only make an HTTP request if the motion even is a press down        // and a prior request hasn't failed.        if (!engine->state.requestFailed && AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN)        {            try            {                http_client client("http://www.bing.com");                 // Wait for response headers and check status code.                http_response response = client.request(methods::GET).get();                if (response.status_code() != status_codes::OK)                {                    engine->state.requestFailed = true;                    LOGW("Received HTTP status code other than 200.");                }                 // Wait for entire response body.                response.content_ready().wait();            }             catch (const http_exception &e)            {                engine->state.requestFailed = true;                LOGW(e.what());            }        }         return 1;    }    return 0;} 

注意,在这个例子中,我们对事件处理程序中发出的HTTP请求同步执行阻塞等待。在实际的应用程序中,对get()和wait()的调用可能不应该进行,而应该使用任务延续来异步处理。

最后,在引擎初始化显示中,确保将requestFailed变量初始化为false:

 ... engine->display = display; engine->context = context; engine->surface = surface; engine->width = w; engine->height = h; engine->state.angle = 0; engine->state.requestFailed = false; ... 

现在确保解决方案的当前配置和体系结构是Debug和x86,并构建应用程序,确保没有编译错误。

在x86仿真器中调试

通过应用程序构建,您可以在x86仿真器中运行它。在第169行附近的engineu handleu input函数中,在发出HTTP请求的位置添加一个断点。确保选中VS Emulator Android手机并开始调试。

图片[3]-用C++ REST SDK瞄准Android-yiteyi-C++库

一旦仿真器启动并启动应用程序,单击应用程序中的手机仿真器以模拟触摸事件。调试器应该在断点处停止,您可以单步执行HTTP请求。

图片[4]-用C++ REST SDK瞄准Android-yiteyi-C++库

除了在x86模拟器中进行调试外,如果连接了Android设备,您还可以部署到该设备。有关本帖中的说明以及有关如何在Android上使用C++ REST SDK的更多信息,请参见 CodePlex文档 . 这篇博文包括一个 zip文件 包含完整项目的VisualStudio解决方案。

其他Android NuGet软件包

作为我们的工作的一部分,为C++的REST SDK创建一个NoGET软件包,我们也为它的所有依赖创建了NuGET包。现在有NuGet包可用于Android for 助推,原子能 , 加速。计时 , Boost.Dateu时间 , Boost.文件系统 , Boost.区域设置 , 增强。随机 , 增压系统 , 推进。线程 , 利比孔夫 ,和 OpenSSL . 即使你不使用C++ REST SDK,你也可以很容易地在Android应用程序中使用这些库。

CppRestAndroid.zip文件

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享