一步步編寫一個AndroidStudio_NDK UDPClient 程式
阿新 • • 發佈:2018-11-14
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");
======================================================== 致此大工告成,執行即可