一步步编写一个AndroidStudio_NDK UDPClient 程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29461259/article/details/53436723

1.配置NDK环境

1. 打开一个项目,从菜单栏中选择 Tools > Android > SDK Manager2. 点击 SDK Tools 选项卡。
3. 勾选 LLDB,CMake 和 NDK

3.点击 Apply,然后点击 OK4.当安装完成后,点击 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");

========================================================
致此大工告成,运行即可

猜你喜欢

转载自blog.csdn.net/qq_29461259/article/details/53436723