動作するもの:TUN / TAPサービスを実行するAC実行可能ファイルと、ターミナルで正常に実行される2つのシェルスクリプト(「iproute」と「iptables」を構成するため)があり、すべてrootとして実行されます。
動作しないもの:ボタンが押された後にc実行可能ファイルとシェルスクリプトを実行するAndroidアプリを作成しようとしています。私はもともと、onClickが以下に示すようにprocessBuilderでプロセスを作成するように作成しました。
final Button button1 = ...
...
public void onClick(View v) {
String ip_address = edIPAddress.getText().toString();
Process process;
try {
process = new ProcessBuilder()
.command("/system/bin/su", "-c", "/data/tuntapserv/armeabi/mytunserv " + ip_address)
.redirectErrorStream(true)
.start();
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
pOutput.append("TUN/TAP IS CONFIGURED!\n");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
私の知る限り、これは正常に機能するはずでしたが、実際には、mytunservはランダムな期間の後に機能を停止します。mytunservはTUN/TAPを開始しましたが、数分後に「ip route」を確認すると、tun/tapが停止して消えたことがわかりました。同様に、runtime.execを試しましたが、これはprocessbuilderを使用しているようで、同じ問題がありました。
次に、プロセスの代わりにスレッドを使用するようになりました。これは、シェルスクリプトでは正常に機能するようです。
...
final Button button2 = ...
...
public void onClick(View v) {
sThread = new ScriptThread();
sThread.start();
}
...
private class ScriptThread extends Thread {
@Override
public void run() {
Process process;
try {
process = new ProcessBuilder()
.command("/system/bin/su","-c","/system/bin/sh /data/tuntapserv/armeabi/setup_ip.sh")
.redirectErrorStream(true)
.start();
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
pOutput.append("SCRIPT FINISHED!\n");
while(true) {
Thread.sleep(0);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
これは、少なくとも2つのシェルスクリプトで機能するように見えました。プロセスまたはスレッドがJavaスレッドハンドラーによって強制終了されているに違いないと考えて、mytunservを呼び出すためのこのメソッドを最終的にあきらめました。これは、私の調査からはかなり予測できないようです。代わりに、JNIに移行しました。これは、c実行可能ファイルとシェルスクリプトへのパスをハードコーディングするよりも適切と思われるためです。
ですから、これは私の最新の問題であり、私が助けを求めているものです。
これが私のJNIセットアップです:
#include <jni.h>
...
JNIEXPORT jint JNICALL Java_android_1sp_1api_sample_SetupTunTap_runtun(JNIEnv * env,jobject obj,jstring ip_address)
{
jchar *ip;
jboolean iscopy;
ip=(*env)->GetStringUTFChars(env, ip_address, &iscopy);
...
(*env)->ReleaseStringUTFChars(env, ip_address, ip);
...
}
...
上記のcコードはliblmytunserv.soに変わります。
package android_sp_api.sample;
...
public class SetupTunTap extends AnotherActivity {
static
{
System.loadLibrary("lmytunserv");
}
public native int runtun(String ip_address);
...
final Button button1 = ...
...
public void onClick(View v) {
String ip_address = edIPAddress.getText().toString();
SetupTunTap myTun = new SetupTunTap();
myTun.runtun(ip_address);
pOutput.append("TUN/TAP IS CONFIGURED!\n");
}
...
私の知る限り、cコードは、JNIEXPORTされていないcコード内の他の関数を呼び出すことができるはずです。JNIExportは、私が想像していることから、Javaコードをcコードと相互作用させるための単なる方法です。
とにかく、今私の問題は、ボタン1を押すと、電話でアプリをデバッグまたは実行するときに、アクティビティが閉じてメインメニューアクティビティに戻ることです。デバッグでは「....DalvikVM[localhost:8602]」と表示され、DDMSではデバイスは「オンライン」のままになります。LogCatは、アクティビティが終了/クラッシュしたことを示唆するものを出力しません。そして、SetupTunTapアクティビティに入ると、LogCatは情報を表示して再開しますが、button1が押され、画面が黒く点滅してメインメニューアクティビティに戻ったときに何も出力しません。これは、logCatで、liblmytunservがロードされる部分です。
LogCat出力:
...
07-30 16:30:19.531: D/dalvikvm(4716): Trying to load lib /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20
07-30 16:30:19.531: D/dalvikvm(4716): Added shared lib /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20
07-30 16:30:19.531: D/dalvikvm(4716): No JNI_OnLoad found in /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20, skipping init
さらにデバッグするにはどうすればよいですか?「myTun.runtun(ip_address);」にブレークポイントを設定した場合 次に、Eclipseのデバッグインターフェイスですべての変数を確認できます。その時点を過ぎて進むと、アクティビティが切断され、LogCatに.solibファイルのロードのみが表示されます。私のJNIの設定は間違っているに違いないと思うので、思考プロセスのどこにいてもアドバイスは素晴らしいでしょう。
ハードウェア:Samsung Galaxy Nexus v4.0.4(ルート化)
ファイル:
mytunserv=c実行可能
setup_ip.sh=シェルスクリプト
setup_ip1.sh=シェルスクリプト
SetupTunTap.java
liblmytunserv.so(/ libs / armeabi、/ libs / armeabi-v7a、/ libs / x86に配置)
必要なもの:Cライブラリliblmytunserv.soのネイティブの「runtun」関数は、while(1)無限ループで永久に実行されます。Javaコードが関数を呼び出すとき(button1が押されると)、関数を永久に実行する必要があります。シェルスクリプトsetup_ip.shおよびsetup_ip1.shは、c実行可能ファイルが実行されると実行されます。c実行可能ファイルを永久に実行するにはどうすればよいですか?
さらに情報が必要な場合はお知らせください。お時間をいただきありがとうございます。