3

免責事項

コメントで説明したように、問題は修正されました。答えがなく、他の人を混乱させたくなかったので削除することを考えていましたが、私の修正は必ずしも問題を対象としているわけではありませんが、それを回避します. だから、いつか誰かが答えを見つけてくれることを期待して、私はそれを保持します.

元の質問

Android ndk を使用していくつかのファイルから読み取っていますが、出力にいくつか問題があります。問題は、ほとんどの場合は機能していますが、時々間違った入力をすることです。以下は私のコードの設定方法です (これは完全なコードではないことに注意してください。ただし、さらに情報が必要な場合は追加します。単純にしたいだけです)。正確な問題は、以下のコードです。

  1. NDK C++ ファイルでは、fstream を使用してファイルから読み取ります。ファイルは電話機の内部メモリに保存されているため、正常に動作しています。2 つのファイルがあります。

1.1 : file1.cpp

JNIExport jdoubleArray class_path_nativeMethod 
                (JNIEnv* env, jclass thiz, jint index, jint size){
    jdouble dubArray[6];
    jdoubleArray result;
    result = env->NewDoubleArray(size);

    string s = "/sdcard/" + construct_fileName(index);

    ifstream is;
    if(is.fail()){
       return NULL; 
    }
    is.open(s.c_str());

    // read something from the files 
    // save it into dubArray
    // assign dubArray to result

    return result;
}

1.2 : file2.cpp

string construct_fileName(int index){
    string s;

    switch(index){
    case 0:
        s = "file1.ext";
        break;
    case 1:
        s = "file2.ext";
        break;
    case 2:
        s = "file3.ext";
        break;
    default:
        // something
    }

    return s;
}

2 これでメインのアクティビティ MainActivity.java

private TextView output;
private TextView output2;
private RadioGroup radioGroup;
private Button calculateButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.output = (TextView) findViewById(R.id.textView2);
    this.output2 = (TextView) findViewById(R.id.textView3);
    this.radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);
    this.calculateButton = (Button) findViewById(R.id.button1);
}

public void calculate(View v){
    int index;
    switch (v.getId()){
    case(R.id.button1){
        switch(radioGroup.getCheckedRadioButtonId()){
        case R.id.radio0:
            index = 0;
            break;
        case R.id.radio1:
            index = 1;
            break;
        case R.id.radio2:
            index = 2;
            break;
        }
    }

    double arr[] = CppMethods.nativeCalculations(index, 2);
    Double i, j;
    i = Double.valueOf(arr[0]);
    j = Double.valueOf(arr[1]);
    this.output.setText(i.toString().subSequence(0, i.toString().length()));
    this.output2.setText(j.toString().subSequence(0, j.toString().length()));
    }
}

問題は、テキストビューの値がほとんどの場合正しいことです。しかし、radio0ボタンを選択してbuttonオブジェクトを 50 回押すと、テキスト ビューで 5 回または 6 回は正しくない出力が得られ、それ以外の場合は正しい出力が得られるとします。

役立つ情報:

  • 出力が正しくない場合、2.72364283467E17 のような法外な数値が得られますが、期待している出力は、ファイルに保存されている 20 未満の double 値です。
  • 出力が正しくない場合、両方のテキストビューに上記のばかげた数が表示されます
  • ほとんどの場合、出力は正しいため、コードは確かに正しいです。

長い質問で申し訳ありませんが、

ありがとう、

ナックス

4

1 に答える 1

0

それはあなたの問題を解決しないかもしれませんが、私が気づいた次の点はあなたを助けるかもしれません:

  1. あなたのfile1.cppでは、のエラー処理env->NewDoubleArray()が見落とされています(または、投稿のために意図的に見落としていましたか?)

  2. doubleにsを割り当てる方法はわかりませんが、 GooglejdoubleArrayからのいくつかのベストプラクティスの提案があります(実際、他のJNI環境にも適用できます)。

  3. synchronizedスレッドの問題1:ネイティブコードがマルチスレッド用に準備されていない場合は、追加する方が良いと思いますCppMethods.nativeCalculations()fstreamそうしないと、別の呼び出しが来たときにまだ開いている可能性があるため):

    public class CppMethods {
        public static native synchronized double[] nativeCalculations(int index, int size);
    }
    
  4. runOnUiThreadスレッドの問題2:呼び出しをラップするようなものが必要になる場合がありsetText()ます。その上、なぜあなたがsetText()そんなに複雑な電話をかけたのだろうか、私はこれで十分だと思います(ちなみに、aStringはaですCharSequence):

    final double[] arr = CppMethods.nativeCalculations(index, 2);
    this.runOnUiThread(new Runnable() {
        public void run() {
            this.output.setText(String.valueOf(arr[0]));
            this.output2.setText(String.valueOf(arr[1]));
        }
    });
    
于 2013-03-16T17:06:28.543 に答える