AndroidでcURLを操作する

なぜそれが必要ですか



C ++でAPIサーバーとの通信を記述し、さまざまなプラットフォームのすべてのアプリケーションで記述されたライブラリを使用します。 もちろん、アンドロイドの下で働きたいです。



Libcurlは、開発者がプロ​​グラムに埋め込むことができる転送APIライブラリです。 cURLは、libcurlライブラリのスタンドアロンラッパーとして機能します。 libcurlは、ファイル(URLでアドレス指定可能)を複数のアプリケーション(オープンおよび商用)に転送する機能を提供するために使用されます。 ( ウィキペディア



iOSの場合、開発者のサイトからcURLを接続して使用する既製の例をダウンロードできます。 また、iOSの場合は簡単です。



Androidでは、Googleスペースで、このクロスプラットフォームライブラリへのアクセスが成功する単一のソースを見つけることができませんでした。 (たぶん私はひどく見ていました)。



そして一般的に言えば、 cURLで Androidを動作させることは、私たちが望むよりも少し複雑であることが判明しました。



必要なもの:




Android用のcURLライブラリの取得



cURL Webサイトにアクセスしてダウンロードを開始すると、デバイスの下からコンソールユーティリティとして実行できるように見えるコンパイル済みのバイナリ(Android 7.31.0バイナリSSL)を見つけることができます。 しかし、アプリケーションからライブラリを操作したい場合は、まったく役に立ちません。

グーグル、ndk * .aに必要なライブラリをビルドする方法についてのチュートリアルを見つけることができます。これは、アプリケーションからすでに操作できます。



Android用およびハブへのcURLの移植について その結果、目的の* .aライブラリファイルを取得します。 私自身はそれを収集しませんでした。 正直にダウンロードしました。



さらに



さらに、結果のライブラリ、プロジェクトを安全に埋め込み、 ndkのすべての機能を使用してアクセスできます。

Javaパーツパーツ


1つのボタンと、情報を受信するサイトのアドレスを入力するフィールドを持つMainActivityを作成します。



activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <EditText android:id="@+id/server_url" android:text="@string/default_url" android:hint="@string/server_url_hint" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true"/> <Button android:id="@+id/button_curl_call" android:layout_below="@+id/server_url" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="@string/button_curl" android:layout_gravity="right" /> <TextView android:id="@+id/text" android:layout_below="@+id/button_curl_call" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>
      
      











MainActivity.java

 package com.ifree.ndkNative; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private static final String INTENT_HTML_DATA = ".html_data"; public static final int HANDLE_CALLBACK = 0; final private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case HANDLE_CALLBACK: String html = msg.getData().getString(INTENT_HTML_DATA); SetHtmlText(html); break; } } }; private void SetHtmlText(String html){ TextView tv = (TextView) findViewById(R.id.text); tv.setText(html); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText serverUrl = (EditText) findViewById(R.id.server_url); Button btnCurl = (Button) findViewById(R.id.button_curl_call); btnCurl.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Native curl = new Native(); curl.addCurlCallbackListener(new ICurlCallbackListener() { @Override public void curlCallBack(String callback) { // ,     gui      TextView,  handler Bundle bundle = new Bundle(); bundle.putString(INTENT_HTML_DATA, callback); Message message = handler.obtainMessage(); message.setData(bundle); handler.sendMessage(message); } }); String response = curl.get_text_from_cpp(String.valueOf(serverUrl.getText()));//    ++  } }); } }
      
      







Native.javaクラスを記述します。 このクラスでは、C ++コードの呼び出しが実行されます。

 package com.ifree.ndkNative; import java.util.HashSet; public class Native { private HashSet<ICurlCallbackListener> callBackListeners = new HashSet<ICurlCallbackListener>(); public void addCurlCallbackListener(ICurlCallbackListener listener){ callBackListeners.add(listener); } public void removeCurlCallbackListener(ICurlCallbackListener listener){ callBackListeners.remove(listener); } static { System.loadLibrary("ndkNative"); } //(  native ,     C++): public native String get_text_from_cpp(String data); private void callback(String data) { for(ICurlCallbackListener listener:callBackListeners){ listener.curlCallBack(data); } } }
      
      







AndroidManifestにインターネット許可を追加することを忘れないでください

 <uses-permission android:name="android.permission.INTERNET"/>
      
      





C ++パーツ


javahユーティリティcom_ifree_ndkNative_Native.hで作成

 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_ifree_ndkNative_Native */ #ifndef _Included_com_ifree_ndkNative_Native #define _Included_com_ifree_ndkNative_Native #ifdef __cplusplus extern "C" { #endif /* * Class: com_ifree_ndkNative_Native * Method: get_text_from_cpp * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_ifree_ndkNative_Native_get_1text_1from_1cpp (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
      
      





ndkNative.cppでサーバー(JNICALL Java_com_ifree_ndkNative_Native_get_1text_1from_1cpp)からデータを受信する機能を定義します

 #include <string.h> #include <stdio.h> #include "stddef.h" #include <jni.h> #include "com_ifree_ndkNative_Native.h" #include "curl/curl.h" #include "curl/easy.h" JNIEnv * gEnv; jobject gObj; void function_callback(jstring str){ jclass cls = gEnv->GetObjectClass(gObj); jmethodID mid = gEnv->GetMethodID(cls, "callback", "(Ljava/lang/String;)V");//   java Native.callback(String data) gEnv->CallVoidMethod(gObj, mid, str); } size_t function_pt(void *ptr, size_t size, size_t nmemb, void *stream){ function_callback(gEnv->NewStringUTF((char *) ptr)); size_t written = fwrite(ptr, size, nmemb, (FILE*)stream); if(written <= 0) return written * size; } JNIEXPORT jstring JNICALL Java_com_ifree_ndkNative_Native_get_1text_1from_1cpp (JNIEnv * env, jobject obj, jstring str) { gEnv = env; gObj = obj; CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, env->GetStringUTFChars(str, 0)); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_pt); res = curl_easy_perform(curl); curl_easy_cleanup(curl); /* Check for errors */ if(res != CURLE_OK) function_callback(gEnv->NewStringUTF(curl_easy_strerror(res))); }else{ function_callback(gEnv->NewStringUTF("error")); } return env->NewStringUTF( "ok" ); }
      
      







Android.mf

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) include $(CLEAR_VARS) LOCAL_MODULE:= libcurl LOCAL_SRC_FILES := libcurl.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := ndkNative LOCAL_SRC_FILES := ndkNative.cpp LOCAL_STATIC_LIBRARIES := libcurl include $(BUILD_SHARED_LIBRARY)
      
      







ソースコード







Ps:実際のアプリケーションで使用するためにプロジェクトを強力に変更する必要があります。特に、 cURLでのすべての作業は、個別のC ++ラッパークラスに移動する必要があります。



Pss:プロジェクトのコード規約は少し不自由です。



All Articles