Android NDK C++ 通信時にバックグラウンド移行すると通信が止まることがある

67 views
Skip to first unread message

App Bikaba

unread,
Aug 4, 2020, 9:03:21 AM8/4/20
to 日本Androidの会
はじめまして。

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
Reply all
Reply to author
Forward
0 new messages