//
// Created by Administrator on 2019/10/13.
//
#include “login.h”
#include “cJSON.h”
#include <android/log.h>
#include “curl/curl.h”
//默认服务器返回数据的长度
#define RESPONSE_DATA_LEN 4096
//用来接收服务器一个buffer
typedef struct login_response_data
{
//构造函数
login_response_data() {
//分配空间
memset(data, 0, RESPONSE_DATA_LEN);
data_len = 0;
}
char data[RESPONSE_DATA_LEN];
int data_len;
}response_data_t;
//处理从服务器返回的数据ptr,将数据拷贝到arg中
size_t deal_response(void *ptr, size_t n, size_t m, void *arg)
{
int count = m*n;
response_data_t response_data = (response_data_t)arg;
memcpy(response_data->data, ptr, count);
response_data->data_len = count;
return response_data->data_len;
}
/*
*/
JNIEXPORT jboolean JNICALL Java_com_ldw_hello_BridgeUtils_login
(JNIEnv * env, jobject obj, jstring jni_username, jstring jni_password, jboolean jni_isdriver)
{
const char *username = env->GetStringUTFChars(jni_username, 0);
const char *passwd = env->GetStringUTFChars(jni_password, 0);
const char *isDriver = jni_isdriver == JNI_TRUE?“yes”:“no”;
char *post_str = NULL;
CURL* curl = NULL;//初始化一个curl指针
CURLcode res;//服务器返回的结果
response_data_t responseData;//专门用来存放从服务器返回的数据
curl = curl_easy_init();
if(curl == NULL){
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login: curl init error \n”);
return JNI_FALSE;
}
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login: username = %s, passwd = %s, isDriver = %s”,
username, passwd, isDriver);
//封装一个数据协议
/*
给服务端的协议
http://ip:port/login [json_data]
{
username: “gailun”,
password: “123123”,
driver: “yes”
}
//(1)封装一个json字符串
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, “username”, username);
cJSON_AddStringToObject(root, “password”, passwd);
cJSON_AddStringToObject(root, “driver”, isDriver);
post_str = cJSON_Print(root);
cJSON_Delete(root);//释放root的空间
root = NULL;
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login: post_str = [%s]\n”, post_str);
//(2) 想web服务器 发送http请求 其中post数据 json字符串
//1 设置curl url
curl_easy_setopt(curl, CURLOPT_URL, “http://101.200.190.150:7777/login”);
//2 开启post请求开关
curl_easy_setopt(curl, CURLOPT_POST, true);
//3 添加post数据
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);
//4 设定一个处理服务器响应的回调函数,deal_response是回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);
//5 给回调函数传递一个形参
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
//6 向服务器发送请求,等待服务器的响应
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login:perform ERROR, rescode= [%d]\n”,
res);
return JNI_FALSE;
}
//(3) 等待服务器的响应 此刻的responseData就是从服务器获取的数据
/*
//成功
{
result: “ok”,
}
//失败
{
result: “error”,
reason: “why…”
}
//(4) 解析服务器返回的json字符串
root = cJSON_Parse(responseData.data);
cJSON *result = cJSON_GetObjectItem(root, “result”);
if(result && strcmp(result->valuestring, “ok”) == 0) {
//登陆成功
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login:login succ!!!”);
return JNI_TRUE;
}
else {
//登陆失败
cJSON* reason = cJSON_GetObjectItem(root, “reason”);
if (reason) {
//已知错误
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login:login error, reason = %s!!!”, reason->valuestring);
}
else {
//未知的错误
__android_log_print(ANDROID_LOG_ERROR,TAG,“JNI-login:login error, reason = Unknow!!!”);
}
return JNI_FALSE;
}
return JNI_TRUE;
}
服务器代码如下http_server.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //for getopt, fork
#include <string.h> //for strcat
//for struct evkeyvalq
#include <sys/queue.h>
#include <event.h>
//for http
//#include <evhttp.h>
#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/http_compat.h>
#include <event2/util.h>
#include <signal.h>
#include <cJSON.h>
#define MYHTTPD_SIGNATURE “MoCarHttpd v0.1”
//处理模块
void httpd_handler(struct evhttp_request *req, void *arg) {
char output[2048] = “\0”;
char tmp[1024];
//获取客户端请求的URI(使用evhttp_request_uri或直接req->uri)
const char *uri;
uri = evhttp_request_uri(req);
#if 0
sprintf(tmp, “uri=%s\n”, uri);// /data?cmd=new…
strcat(output, tmp);
#endif
sprintf(tmp, “uri=%s\n”, req->uri);
strcat(output, tmp);
//decoded uri
char *decoded_uri;
decoded_uri = evhttp_decode_uri(uri);
sprintf(tmp, “decoded_uri=%s\n”, decoded_uri);// /data?cmd= newFile …
strcat(output, tmp);
//http://127.0.0.1:8080/username=gailun&passwd=123123
//解析URI的参数(即GET方法的参数)
struct evkeyvalq params;//key —value, key2— value2// cmd — newfile fromId == 0
//将URL数据封装成key-value格式,q=value1, s=value2
evhttp_parse_query(decoded_uri, ¶ms);
//得到q所对应的value
sprintf(tmp, “username=%s\n”, evhttp_find_header(¶ms, “username”));
strcat(output, tmp);
//得到s所对应的value
sprintf(tmp, “passwd=%s\n”, evhttp_find_header(¶ms, “passwd”));
strcat(output, tmp);
free(decoded_uri);
//获取POST方法的数据
char *post_data = (char *) EVBUFFER_DATA(req->input_buffer);
sprintf(tmp, “post_data=%s\n”, post_data);
strcat(output, tmp);
/*
具体的:可以根据GET/POST的参数执行相应操作,然后将结果输出
…
*/
//入库
/* 输出到客户端 */
//HTTP header
evhttp_add_header(req->output_headers, “Server”, MYHTTPD_SIGNATURE);
evhttp_add_header(req->output_headers, “Content-Type”, “text/plain; charset=UTF-8”);
evhttp_add_header(req->output_headers, “Connection”, “close”);
//输出的内容
struct evbuffer *buf;
buf = evbuffer_new();
evbuffer_add_printf(buf, “It works!\n%s\n”, output);
//将封装好的evbuffer 发送给客户端
evhttp_send_reply(req, HTTP_OK, “OK”, buf);
evbuffer_free(buf);
}
//处理模块
void login_handler(struct evhttp_request *req, void *arg) {
printf("got connection ");
char reque
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
**开源项目:【qq.cn.hn/FTe】 **
st_data[4096] = {0};
//获取POST方法的数据
size_t post_size = EVBUFFER_LENGTH(req->input_buffer);
char *post_data = (char *) EVBUFFER_DATA(req->input_buffer);
memcpy(request_data, post_data, post_size);
printf(“post_data = [%s], len =%ld\n”, post_data, post_size);
char username[256] = {0};
char password[256] = {0};
char isDriver[10] = {0};
/*
具体的:可以根据GET/POST的参数执行相应操作,然后将结果输出
…
*/
/*
给服务端的协议
http://ip:port/login [json_data]
{
username: “gailun”,
password: “123123”,
driver: “yes”
}
cJSON *root = cJSON_Parse(request_data);
cJSON* username_obj = cJSON_GetObjectItem(root, “username”);
strcpy(username, username_obj->valuestring);
cJSON* password_obj = cJSON_GetObjectItem(root, “password”);
strcpy(password, password_obj->valuestring);
cJSON* isDriver_obj = cJSON_GetObjectItem(root, “driver”);
strcpy(isDriver, isDriver_obj->valuestring);
printf(“username = %s, password = %s, isDriver = %s\n”, username, password, isDriver);
cJSON_Delete(root);
printf("----\n");
//查询数据库 得到查询结果
//给前段回复一个响应结果
cJSON*response_root = cJSON_CreateObject();
cJSON_AddStringToObject(response_root, “result”, “ok”);
char *response_str = cJSON_Print(response_root);
/* 输出到客户端 */
//HTTP header
evhttp_add_header(req->output_headers, “Server”, MYHTTPD_SIGNATURE);
evhttp_add_header(req->output_headers, “Content-Type”, “text/plain; charset=UTF-8”);
结尾
最后,针对上面谈的内容,给大家推荐一个Android资料,应该对大家有用。
首先是一个知识清单:(对于现在的Android及移动互联网来说,我们需要掌握的技术)
泛型原理丶反射原理丶Java虚拟机原理丶线程池原理丶 注解原理丶注解原理丶序列化 Activity知识体系(Activity的生命周期丶Activity的任务栈丶Activity的启动模式丶View源码丶Fragment内核相关丶service原理等) 代码框架结构优化(数据结构丶排序算法丶设计模式) APP性能优化(用户体验优化丶适配丶代码调优) 热修复丶热升级丶Hook技术丶IOC架构设计 NDK(c编程丶C++丶JNI丶LINUX) 如何提高开发效率? MVC丶MVP丶MVVM 微信小程序 Hybrid Flutter
接下来是资料清单:(敲黑板!!!)
1.数据结构和算法
2.设计模式
3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记
4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)
不论遇到什么困难,都不应该成为我们放弃的理由!共勉~
如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。
栈丶Activity的启动模式丶View源码丶Fragment内核相关丶service原理等)
代码框架结构优化(数据结构丶排序算法丶设计模式) APP性能优化(用户体验优化丶适配丶代码调优) 热修复丶热升级丶Hook技术丶IOC架构设计 NDK(c编程丶C++丶JNI丶LINUX) 如何提高开发效率? MVC丶MVP丶MVVM 微信小程序 Hybrid Flutter
[外链图片转存中…(img-4HjfN1tw-1641546488530)]
接下来是资料清单:(敲黑板!!!)
1.数据结构和算法
[外链图片转存中…(img-PG1NLl0E-1641546488531)]
2.设计模式
[外链图片转存中…(img-mmPxs9ZJ-1641546488532)]
3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记
[外链图片转存中…(img-60HcjPVV-1641546488532)]
4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)
[外链图片转存中…(img-nFebqqn0-1641546488533)]
不论遇到什么困难,都不应该成为我们放弃的理由!共勉~
如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。
[外链图片转存中…(img-IKEzRko8-1641546488533)]
本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录
|