5

動作するもの: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実行可能ファイルを永久に実行するにはどうすればよいですか?

さらに情報が必要な場合はお知らせください。お時間をいただきありがとうございます。

4

1 に答える 1

2

JNIで

JNIEXPORT jint JNICALL Java_android_1sp_1api_sample_SetupTunTap_runtun(JNIEnv * env,jobject obj,jstring ip_address)

活動中

package android_sp_api.sample;

これらは一致する必要があります;)

編集:5回のうち4回はこれだけです。また、Java側も投稿しますが、次のようになっているといいのですが

class SetupTunTap
{
   public native int runtun(String ip_address);

///}

したがって、SetupTunTapクラスも投稿してください\

edit2:おっと、編集は不要でした。ただのパッケージ名です。

于 2012-07-30T21:26:53.550 に答える