Application.mk
--------------
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := mylib
#--------------------------------------------------------------------------------
【以下是几个c文件】
NativeHello.c ,主要的C文件,调用其它普通linux native c
-----------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>
#include "HttpGet.h"
JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz)
{
printf("hello in c native code./n");
mmain();
return (*env)->NewStringUTF(env, "-------------hello world mmain().-------------");
}
#define JNIREG_CLASS "org/eshock/jnitest/JNITest"//指定要注册的类
//注意:是类名
/** * Table of methods associated with a single class. */
static JNINativeMethod gMethods[] = {
{ "hello", "()Ljava/lang/String;", (void*)native_hello },//绑定
}; /* * Register several native methods for one class. */
static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL)
{
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
{
return JNI_FALSE;
}
return JNI_TRUE; }
/* * Register native methods for all classes we know about. */
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, sizeof(gMethods) / sizeof(gMethods[0])))
{
return JNI_FALSE;
}
return JNI_TRUE;
}
/* * Set some test stuff up. * * Returns the JNI version on success, -1 on failure.
*当Android的VM(Virtual Machine)执行到System.loadLibrary()函数时,首先会去执行C组件里的JNI_OnLoad()函数。
*它的用途有二:
*(1)【版本】告诉VM此C组件使用那一个JNI版本。如果你的*.so档没有提供JNI_OnLoad()函数,VM会默认该*.so档是使用最老的JNI 1.1版本。
* 由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI 1.4的java.nio.ByteBuffer,
* 就必须藉由JNI_OnLoad()函数来告知VM。
*(2)【初始化】由于VM执行到System.loadLibrary()函数时,就会立即先呼叫JNI_OnLoad(),所以C组件的开发者可以藉由JNI_OnLoad()
* 来进行C组件内的初期值之设定(Initialization) 。
* */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
{
return -1;
}
assert(env != NULL);
if (!registerNatives(env))//注册
{
return -1;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
return result;
}
--------------------------------------------
HttpGet.c
#include "HttpGet.h"
#include <android/log.h>
int GetHttpResponseHead(int sock,char *buf,int size)
{
int i;
char *code,*status;
memset(buf,0,size);
for(i=0; i<size-1; i++){
if(recv(sock,buf+i,1,0)!=1){
perror("recv error");
return -1;
}
if(strstr(buf,"\r\n\r\n"))
break;
}
if(i >= size-1){
puts("Http response head too long.");
return -2;
}
code=strstr(buf," 200 ");
status=strstr(buf,"\r\n");
if(!code || code>status){
*status=0;
printf("Bad http response:\"%s\"\n",buf);
return -3;
}
return i;
}
int HttpGet(const char *server,const char *url)
{
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter HttpGet function!");
int sock=socket(PF_INET,SOCK_STREAM,0);
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "%d",sock);
struct sockaddr_in peerAddr;
char buf[2048];
int ret;
//const char *filename;
//FILE *fp=NULL;
peerAddr.sin_family=AF_INET;
peerAddr.sin_port=htons(80);
peerAddr.sin_addr.s_addr=inet_addr(server);
ret=connect(sock,(struct sockaddr *)&peerAddr,sizeof(peerAddr));
if(ret != 0){
perror("connect failed");
close(sock);
return -1;
}
sprintf(buf,
"GET %s HTTP/1.1\r\n"
"Accept: */*\r\n"
"User-Agent: cnzhuhai@163.com\r\n"
"Host: %s\r\n"
"Connection: Close\r\n\r\n",
url,server);
send(sock,buf,strlen(buf),0);
if(GetHttpResponseHead(sock,buf,sizeof(buf))<1){
close(sock);
return -1;
}
//filename=strrchr(url,'/')+1;
//if(!filename[0])
//filename="index.html";
//fp=fopen(filename,"wb");
//if(fp)
//{
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter HttpGet function's while!");
while((ret=recv(sock,buf,sizeof(buf),0)) > 0)
{
//fwrite(buf,ret,1,fp);
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "hello, this is my number %s log message!", buf);
}
//}
//fclose(fp);
shutdown(sock,SHUT_RDWR);
close(sock);
return 0;
}
//"http://192.168.7.222/index.html"
int mmain(void)
{
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter mmain function!");
char *head,*tail;
char server[128]={0};
/* if(argc<2){
printf("Usage:%s url\n",argv[0]);
return -1;
}
if(strlen(argv[1])>1500){
puts("Url too long.");
return -1;
}*/
//head=strstr("http://192.168.10.101/gi/1.html","//");
head=strstr("http://220.181.111.148/index.html","//");
if(!head){
puts("Bad url format");
return -1;
}
head+=2;
tail=strchr(head,'/');
if(!tail){
return HttpGet(head,"/");
}else if(tail-head>sizeof(server)-1){
puts("Bad url format");
return -1;
}else{
memcpy(server,head,tail-head);
return HttpGet(server,tail);
}
}
HttpGet.h
---------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int GetHttpResponseHead(int sock,char *buf,int size);
int HttpGet(const char *server,const char *url);
int mmain(void);
android.mk
--------------------
include $(CLEAR_VARS)
LOCAL_LDLIBS := -lm -llog
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := \
NativeHello.c \
HttpGet.h \
HttpGet.c \
include $(BUILD_SHARED_LIBRARY)
#--------------------------------------------------------------------------------