はじめまして。
Android NDKにおいてC++からlibcurlを使って通信処理を実装しています。そこで致命的ではないですが、1つの問題に遭遇しています。
まず app.cpp を作成し、そこにC++の以下コードを作成しました。
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <jni.h>
size_t curl_write(void *contents, size_t size, size_t nmemb, std::string *s)
{
size_t newLength = size*nmemb;
s->append((char*)contents, newLength);
return newLength;
}
extern "C" jstring Java_com_example_com_MainActivity_test(){
CURLcode ret;
CURL *hnd;
/// セッションを維持したまま連続的に通信
for(int i = 0; i < 100; ++i){
hnd = curl_easy_init();
std::string url = "https://hoge.com/hoge";
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "");
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, curl_write);
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, &resp);
curl_easy_setopt(hnd, CURLOPT_COOKIEFILE, "cookie.txt");
curl_easy_setopt(hnd, CURLOPT_COOKIEJAR, "cookie.txt");
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
ret = curl_easy_perform(hnd);
}
curl_easy_cleanup(hnd);
hnd = NULL;
/// 省略...
}
細かなコードミスについてはご指摘不要です。そして上記コードは実際のコードとも異なります。そのコードで行っている、連続的にセッション維持したまま通信を行うコードを疑似再現しました。
そしてJava側から以下のように呼び出しています。
public class MainActivity extends AppCompatActivity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/// ネイティブメソッドを実行
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable(){
@Override
public synchronizedvoid run(){
test();
}
})
}
/** ネイティブメソッド **/
public synchronized native String test();
static {
System.loadLibrary("app");
}
}
そして実行時にある問題が発生しました。
アプリで test() が実行されるまではいいのですが、実機端末とWifiとの距離(≒通信環境の良さ)によって次の2パターンの動作になってしまいました。
ケースA : Wifiと端末が近い場合
=> 距離にして1~5メートルほどと推測。アプリがバックグラウンド/履歴画面に移行した場合、 test() 内の通信処理は止まらない。
ケースB :Wifiと端末が遠い場合。
=> 距離にして5メートル以上離れた場合と推測。アプリがバックグラウンド/履歴画面に移行した場合、curl_easy_perform の実行がなぜか止まってします。それ以外の通信に関係のないコードは動き続ける
この現象に悩まされています。
間違いなくこういった規則性があると確認しました。
もし同じような問題に遭遇した方、あるいはAndroid NDKでの通信処理に詳しい方がいらっしゃれば、原因を一緒に考えていただくとありがたいです。実機のAndroidバージョンは7.0です。よろしくお願いいたします。m(__)m