android JNI使用curl库进行文件下载和http请求
来源:互联网 发布:粤11选5遗漏数据查询 编辑:程序博客网 时间:2024/05/16 19:27
1.CURL几个基本函数的说明:
1) curl_global_init();这个函数是进行curl库的初始化,这个函数与curl_global_cleanup配套使用,当调用了一次后,在没有调用curl_global_cleanup之前不要再次调用。
2) curl_global_cleanup();对curl_global_init进行的一些操作进行清理。
3) CURL *curl_easy_init( );用于产生一个CURL对象用于进行网络相关的操作,此对象类似于文件指针,不使用它的时候需要进行清理释放。
4) void curl_easy_cleanup(CURL *curl);用于对CURL*的清理释放。
5) void curl_easy_reset(CURL *handle );重新初始化CURL句柄的选项设置。
6) CURLcode curl_easy_getinfo(CURL *curl,CURLINFO info, ... );查询CRUL会话的内部信息,具体说明请参考curl自带文档。
7.) CURLcode curl_easy_setopt(CURL *curl,CURLoption option, ...);此函数是curl中最核心的函数,基本所有的网络操作的设定都需要它去进行,他的参数等也非常的复杂,建议自行搜索这个函数相关的内容。
8) CURLcode curl_easy_perform(CURL *curl);针对curl_easy_setopt设置好的内容参数进行相应的网络操作。
2.CURL库在Android JNI中的具体使用(HTTP请求和文件下载):
创建android工程以后需要在AndroidManifest.xml文件中添加使用权限:
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
使用curl封装的一个简单的http请求类HttpPostModule
HttpPostModule.h
- #ifndef HTTP_POST_MODULE_H
- #define HTTP_POST_MODULE_H
-
- #include <string>
- #include "curl/curl.h"
- #include <iostream>
- using namespace std;
- typedef size_t (*WriteFunc)(char *ptr, size_t size, size_t nmemb,
- void *userdata);
-
-
-
-
- class HttpPostModule
- {
- public:
- HttpPostModule();
- virtual ~HttpPostModule();
-
- static void Init();
- static void Cleanup();
- public:
-
- bool SetTimeOut(unsigned short usSecond);
-
-
- bool SetURL(const string& strURL);
-
- bool SetHttpHead(const string& strHttpHead);
-
- bool SetWriteFunction(WriteFunc pFunc);
-
- int SendPostRequest(void);
-
- private:
- CURL* m_pCurl;
- public:
-
- };
-
- #endif
HttpPostModule.cpp
- #include "HttpPostModule.h"
-
- HttpPostModule::HttpPostModule() :
- m_pCurl(NULL)
- {
- m_pCurl = curl_easy_init();
- curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
- }
- HttpPostModule::~HttpPostModule()
- {
- curl_easy_cleanup(m_pCurl);
- m_pCurl = NULL;
- }
- void HttpPostModule::Init()
- {
- curl_global_init(CURL_GLOBAL_ALL);
-
- }
- void HttpPostModule::Cleanup()
- {
- curl_global_cleanup();
-
- }
- bool HttpPostModule::SetTimeOut(unsigned short usSecond)
- {
- if (m_pCurl == NULL)
- return false;
- int nRet = curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, usSecond);
- if (nRet == CURLE_OK)
- return true;
- else
- {
- cout << "SetTimeOut ERROR code =" << nRet << endl;
- return false;
- }
- }
- bool HttpPostModule::SetURL(const string& strURL)
- {
- if (m_pCurl == NULL)
- return false;
- int nRet = curl_easy_setopt(m_pCurl, CURLOPT_URL, strURL.c_str());
- if (nRet == CURLE_OK)
- return true;
- else
- {
- cout << "SetURL ERROR code =" << nRet << endl;
- return false;
- }
- }
- bool HttpPostModule::SetHttpHead(const string& strHttpHead)
- {
- if (m_pCurl == NULL)
- return false;
- curl_slist *plist = curl_slist_append(NULL, strHttpHead.c_str());
- int nRet = curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, plist);
- if (nRet == CURLE_OK)
- return true;
- else
- {
- cout << "SetHttpHead ERROR code =" << nRet << endl;
- return false;
- }
- }
- bool HttpPostModule::SetWriteFunction(WriteFunc pFunc)
- {
- if (m_pCurl == NULL)
- return false;
- curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, NULL);
- int nRet = curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, pFunc);
- if (nRet == CURLE_OK)
- return true;
- else
- {
- cout << "SetCallbackFunc ERROR code =" << nRet << endl;
- return false;
- }
- }
-
- int HttpPostModule::SendPostRequest(void)
- {
- if (m_pCurl == NULL)
- return -1;
- int nRet = curl_easy_perform(m_pCurl);
- if (nRet == CURLE_OK)
- return 0;
- else
- {
- return nRet;
- }
- }
使用curl封装的一个简单的文件下载类DownloadModule,文件下载支持断点续传。
DownloadModule.h
- #ifndef DOWNLOAD_MODULE_H
- #define DOWNLOAD_MODULE_H
- #include <string>
- #include "curl/curl.h"
- using namespace std;
-
- class DownLoadModule
- {
- public:
- DownLoadModule();
- virtual ~DownLoadModule();
- static void Init();
- static void Cleanup();
-
- public:
- static size_t DownLoadPackage(void *ptr, size_t size, size_t nmemb,
- void *userdata);
- private:
- long GetLocalFileLenth(const string& strFileName);
- public:
-
-
-
-
-
-
- int DownLoad(std::string strUrl, std::string strStoragePath,
- std::string strFileName);
- private:
- CURL *m_pCurl;
- };
-
- #endif
DownloadModule.cpp- #include <sys/stat.h>
- #include <unistd.h>
- #include "DownloadModule.h"
-
-
- DownLoadModule::DownLoadModule() :
- m_pCurl(NULL)
- {
- m_pCurl = curl_easy_init();
- }
- DownLoadModule::~DownLoadModule()
- {
- curl_easy_cleanup(m_pCurl);
- m_pCurl = NULL;
- }
- void DownLoadModule::Init()
- {
- curl_global_init(CURL_GLOBAL_ALL);
-
- }
- void DownLoadModule::Cleanup()
- {
- curl_global_cleanup();
-
- }
-
- size_t DownLoadModule::DownLoadPackage(void *ptr, size_t size, size_t nmemb,
- void *userdata)
- {
- FILE *fp = (FILE*) userdata;
- size_t written = fwrite(ptr, size, nmemb, fp);
- return written;
- }
-
- long DownLoadModule::GetLocalFileLenth(const string& strFileName)
- {
- unsigned long filesize = 0;
- struct stat statbuff;
- if (stat(strFileName.c_str(), &statbuff) < 0)
- {
- return filesize;
- }
- else
- {
- filesize = statbuff.st_size;
- }
- return filesize;
-
- }
- int DownLoadModule::DownLoad(std::string strUrl, std::string strStoragePath,
- std::string strFileName)
- {
- Init();
-
- if (0 != access(strStoragePath.c_str(), F_OK))
- mkdir(strStoragePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- ;
- const string outFileName = strStoragePath + "/" + strFileName;
-
- long localLen = GetLocalFileLenth(outFileName.c_str());
- FILE *fp = fopen(outFileName.c_str(), "a+b");
- if (!fp)
- {
- return -1;
- }
- fseek(fp, 0, SEEK_END);
-
-
- CURLcode res;
- curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str());
- curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, DownLoadPackage);
- curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, fp);
- curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, true);
-
- curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
- curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L);
- curl_easy_setopt(m_pCurl, CURLOPT_NOBODY, 0L);
- curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM, localLen);
-
- res = curl_easy_perform(m_pCurl);
- Cleanup();
-
- if (res != 0)
- {
- fclose(fp);
- return res;
- }
- fclose(fp);
- return 0;
- }
具体功能实现:下载一个APK文件和发送一个百度地图API的Http请求。
Java端代码 MainActivity.class
- package com.example.curltest;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class MainActivity extends Activity {
- static {
- System.loadLibrary("curl");
- System.loadLibrary("curlTest");
- }
- public native void Init();
- public native void Cleanup();
- public native void TestDownload();
- public native void TestHttpPost();
- private final String TAG = "curlTest";
- private void postDispose(String Data)
- {
- Log.i(TAG, Data);
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Init();
- Button btnPost = (Button) findViewById(R.id.main_post);
- Button btnDownload = (Button) findViewById(R.id.main_download);
- btnPost.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
-
- TestHttpPost();
- }
- });
- btnDownload.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
-
- TestDownload();
- }
- });
-
- }
- @Override
- protected void onDestroy() {
-
- super.onDestroy();
- Cleanup();
- }
- }
JNI代码Main.cpp
- #include <jni.h>
- #include "DownloadModule.h"
- #include "HttpPostModule.h"
- #include "JNIUtil.h"
- extern "C"
- {
- jobject g_objAc = NULL;
- void Java_com_example_curltest_MainActivity_TestDownload(JNIEnv* env,
- jobject obj)
- {
- DownLoadModule download;
- const char* url =
- "http://s3.amazonaws.com/hum9-lwg8-qa2w/PsiphonAndroid.apk";
- int nRet = download.DownLoad(url, "/sdcard/Download", "PsiphonAndroid.apk");
- if (nRet == 0)
- LOGI("download success!");
- else
- LOGE("download error code:%d", nRet);
- }
- size_t PostDispose(char *buffer, size_t size, size_t nmemb, void *userdata)
- {
- JNIUtil util;
- jobject jdata = util.String2Jstring(buffer);
- JNIEnv* env = util.GetJNIEnv();
- jclass cMainActivity = env->GetObjectClass(g_objAc);
- jmethodID methodPostDispose = env->GetMethodID(cMainActivity, "postDispose",
- "(Ljava/lang/String;)V");
- env->CallVoidMethod(g_objAc, methodPostDispose, jdata);
- return nmemb;
- }
- void Java_com_example_curltest_MainActivity_TestHttpPost(JNIEnv* env,
- jobject obj)
- {
- HttpPostModule post;
- post.SetTimeOut(60);
- post.SetHttpHead("Content-Type:application/json;charset=UTF-8");
- post.SetWriteFunction(PostDispose);
- post.SetURL("http://api.map.baidu.com/place/v2/suggestion?query=tiananmen®ion=131&output=json&ak=fTF5Wt01MNLs7ci9G9G6X76d");
- int nRet = post.SendPostRequest();
- if (nRet == 0)
- LOGI("post success!");
- else
- LOGE("post error code:%d", nRet);
- }
- void Java_com_example_curltest_MainActivity_Init(JNIEnv* env, jobject obj)
- {
- HttpPostModule::Init();
- JavaVM* vm;
- env->GetJavaVM(&vm);
- JNIUtil::Init(env);
- g_objAc = env->NewGlobalRef(obj);
- }
- void Java_com_example_curltest_MainActivity_Cleanup(JNIEnv* env, jobject obj)
- {
- HttpPostModule::Cleanup();
- env->DeleteGlobalRef(g_objAc);
- g_objAc = NULL;
- JNIUtil::CleanUp(env);
- }
- }
里面的JNIUtil工具类在我的另一篇博客有详细说明。
http://blog.csdn.net/csdn49532/article/details/50635338
整个项目工程源码:
http://download.csdn.net/detail/csdn49532/9434453
0 0