版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29461259/article/details/53436723
1.配置NDK环境
1. 打开一个项目,从菜单栏中选择 Tools > Android > SDK Manager。
2. 点击 SDK Tools 选项卡。
3. 勾选 LLDB,CMake 和 NDK。
3.点击 Apply,然后点击 OK。
4.当安装完成后,点击 Finish,然后点击 OK。
2.创建一个支持 C/C++ 的新项目
1.在 Configure your new project 选项中,勾选 Include C++ Support 选项。
2.点击 Next,后面的流程和创建普通的 Android studio 工程一样。
3.在Customize C++ Support 选项卡中:选择默认 CMake 设置的Toolchain Default 选项(默认即可)
5.点击 “Finish”。
3.工程中添加C代码
切换到Android视图
CPP文件夹会默认生成一个native-lib.cpp
在这个文件里我们创建JNI方法,上连JAVA native方法,下通我们需要的C/C++文件 我们在这里添加一个udpclient.c,并在native-lib.cpp包含该文件
native-lib.cpp
#include <jni.h>
#include <string>
#include "udpclient.c"
#include "base.h"
extern "C" {
JNIEXPORT void JNICALL
Java_org_udpclient_MainActivity_sendData(JNIEnv *env, jobject instance, jstring hostName_,
jint portno) {
const char *hostName = env->GetStringUTFChars(hostName_, 0);
// TODO
int portno_java = portno;
LOGI("native 发送 udp function");
main_send(hostName, portno_java);
LOGI("native 发送 udp function finish");
env->ReleaseStringUTFChars(hostName_, hostName);
}
}
udpclient.c文件
//
// Created by pactera on 2016/12/2.
//
/*
* udpclient.c - A simple UDP client
* usage: udpclient <host> <port>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "base.h"
#include <pthread.h>
#define BUFSIZE 1024
int main_send(const char *hostname_java, int portno_java) {
int sockfd, portno, n;
int serverlen;
struct sockaddr_in serveraddr;
char buf[BUFSIZE];
struct hostent *server;
const char *hostname;
hostname = hostname_java;
portno = portno_java;
/* socket: create the socket */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
LOGE("ERROR opening socket");
/* gethostbyname: get the server's DNS entry */
server = gethostbyname(hostname);
if (server == NULL) {
LOGE("no such host as");
return -1;
}
/* build the server's Internet address */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
/* init message data*/
strcpy(buf,"client send message");
/* send the message to the server */
serverlen = sizeof(serveraddr);
n = (int)sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr*)&serveraddr, serverlen);
if (n < 0)
LOGE("ERROR in sendto");
LOGI("client send complete");
n = (int)recvfrom(sockfd, buf, strlen(buf), 0, (struct sockaddr*)&serveraddr, (socklen_t*)&serverlen);
if (n < 0)
LOGE("ERROR in recvfrom");
return 0;
}
base.h文件
#ifndef UDPCLIENT_BASE_H
#define UDPCLIENT_BASE_H
#endif //UDPCLIENT_BASE_H
#include <android/log.h>
#define TAG "yueguang" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
cmakelist中参考下面的格式进行添加,别忘记换行,在小括号的包裹范围内
5.使用JNI调用native方法
Java代码中声明native方法
public native void sendData(String hostName,int portno);
Alt+Enter便可以在native-lib文件中生成对应的Jni方法,我们只要编写方法体就可以了
创建的JNI方法应该在extern "C" {....}包裹范围内,否则调用的时候会出错
Native method not found
JNIEXPORT void JNICALL
Java_org_udpclient_MainActivity_sendData(JNIEnv *env, jobject instance, jstring hostName_,
jint portno) {
const char *hostName = env->GetStringUTFChars(hostName_, 0);
// TODO
int portno_java = portno;
LOGE("native 发送 udp function");
main_send(hostName, portno_java);
env->ReleaseStringUTFChars(hostName_, hostName);
}
6.使用Android Log系统
新建个base..h把下面的代码拷贝进去
#include <android/log.h>
#define TAG "yueguang" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
然后在需要使用AndroidLog系统的.c或.cpp文件中#include "base.h"
//使用方法
LOGE("native 发送 udp function");
========================================================
致此大工告成,运行即可