3

免责声明

正如我在评论中描述的那样,问题已得到解决。我正在考虑删除它,因为没有答案并且我不想混淆其他人,但我的修复不一定针对问题,而是解决它。所以,我只是保留它,希望有一天有人会找到答案。

原始问题

我正在使用 android ndk 从一些文件中读取数据,但输出存在一些问题。问题是,它大部分时间都在工作,但偶尔会给出错误的输入。下面是我的代码是如何设置的(请注意,这不是完整的代码,但如果需要更多信息,我会添加它。我只是想保持简单)。确切的问题是下面的代码。

  1. 在 NDK C++ 文件中,我使用 fstream 从文件中读取。这些文件存储在手机的内存中,因此可以正常工作。有2个文件:

1.1:文件1.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:文件2.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 的双精度值。
  • 当输出不正确时,两个文本视图都有上面显示的荒谬数字
  • 代码肯定是正确的,因为大多数时候输出是正确的。

对不起,很长的问题,

谢谢,

纳克斯

4

1 回答 1

0

它可能无法解决您的问题,但我注意到的以下几点可能会对您有所帮助:

  1. 在您的file1.cpp, 错误处理中env->NewDoubleArray()遗漏了(或者您是否故意错过了发布?)

  2. 我不知道您如何将doubles分配给jdoubleArray,但这里有一些来自Google的最佳实践建议(实际上它也适用于其他 JNI 环境):

  3. 线程问题1:如果您的本机代码没有为多线程做好准备,我认为最好添加synchronizedCppMethods.nativeCalculations()因为fstream如果不这样做,当另一个调用来临时可能仍然打开):

    public class CppMethods {
        public static native synchronized double[] nativeCalculations(int index, int size);
    }
    
  4. 线程问题 2:您可能需要runOnUiThread包装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 回答