Android从文件读取,偶尔读取不正确的值

时间:2013-03-10 02:34:11

标签: java android c++ android-ndk file-io

声明

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

原始问题

我正在使用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()));
        }
    }
    

    所以问题是,textviews中的值在大多数情况下都是正确的。但是,假设我选择了radio0按钮,并按下button对象50次,我将在文本视图中输出不正确的输出5或6次,并在其他时间输出正确的输出。

    一些可能有用的信息:

    • 当输出不正确时,我得到一些令人发指的数字,如2.72364283467E17,而我期望的输出是小于20的双倍值,存储在文件中。
    • 当输出不正确时,两个文本视图都有上面显示的荒谬数字
    • 代码是正确的,因为输出在大多数情况下都是正确的。

    很抱歉这个很长的问题,

    谢谢,

    NAX

1 个答案:

答案 0 :(得分:0)

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

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

  2. 我不知道您如何将double分配给jdoubleArray,但以下是 Google 的一些最佳做法建议(实际上它适用)对于其他JNI环境也是如此):

  3. 线程问题1:如果您的本机代码没有为多线程做好准备,我认为最好将synchronized添加到CppMethods.nativeCalculations()(因为fstream可能仍然存在如果没有这样做,则打开另一个电话时):

    public class CppMethods {
        public static native synchronized double[] nativeCalculations(int index, int size);
    }
    
  4. 线程问题2:您可能需要runOnUiThread之类的内容来包含setText()次来电。此外,我想知道为什么你打电话给setText()如此复杂,我认为这已经足够了(顺便说一下,StringCharSequence):

    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]));
        }
    });