ObjectInputStream 在 Android 中的 AsyncTask 中给出 NullPointerException 错误

ObjectInputStream is giving NullPointerException error inside the AsyncTask in Android

我的目的是 反序列化 AsyncTask 中的二进制文件,因为这是一个冻结我 Android 的繁重进程界面。

Web 服务序列化 Weka 分类器 class。然后,我通过 Web 服务获取一个二进制文件,我将反序列化该二进制文件,以便我可以继续处理其他 Weka 计算。

我已经在我的 Android 应用程序中接收序列化的二进制文件并反序列化。然后,我意识到反序列化和读取过程需要时间。因此,我决定使用 AsyncTask 向用户显示进度对话框。

而且,问题来了。当我在 doInBackground 方法中实现反序列化过程时,出现 NullPointerException 错误。

Android代码:

public class MatlabMainWindow extends AppCompatActivity {

private Button treeButton;
private Button positionButton;
private TextView textViewTree;
private PositionDetector positionDetector;
private String treeHolder;
private Classifier j48ClassifierHolder;

File sdcardFile = Environment.getExternalStorageDirectory();

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

    treeButton = (Button) findViewById(R.id.button_tree);
    positionButton = (Button) findViewById(R.id.button_position);
    textViewTree = (TextView) findViewById(R.id.textView_tree);


treeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            BackgroundTask task = new BackgroundTask(MatlabMainWindow.this);
            task.execute();

        }
    });

    positionButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                String positionString = positionDetector.calculateThePosition();

                AlertDialog.Builder alert = new AlertDialog.Builder(MatlabMainWindow.this);
                alert.setTitle("Position Prediction");
                alert.setMessage(positionString);
                alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub

                    }
                });
                alert.show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}

private class BackgroundTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;

    public BackgroundTask(MatlabMainWindow activity) {
        dialog = new ProgressDialog(activity);
    }

    @Override
    protected void onPreExecute() {
        dialog.setMessage("Doing something, please wait.");
        dialog.show();

    // getting the binary file through web service
    ...
    ...

        Volley.newRequestQueue(MatlabMainWindow.this).add(binaryHttpRequest);
    }

    @Override
    protected void onPostExecute(Void result) {
        textViewTree.setMovementMethod(new ScrollingMovementMethod());
        textViewTree.setText(treeHolder);
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            // deserialize model
            ObjectInputStream ois = new ObjectInputStream(
                    new FileInputStream(sdcardFile.getAbsolutePath() + "/Weka/dataset_RFKON/j48.model"));

                j48ClassifierHolder = (Classifier) ois.readObject();
                ois.close();
        }
        catch (Exception ex){
            ex.printStackTrace();
        }

        //try {
        //
        //        treeHolder = j48ClassifierHolder.toString();
        //    } catch (Exception e) {
        //        e.printStackTrace();
        //    }


        return null;
    }
  }
}

错误:

W/System.err:     at inovasyonwebservice.com.gezkonwebservice.Matlab.MatlabMainWindow$BackgroundTask.doInBackground(MatlabMainWindow.java:250)
W/System.err:     at inovasyonwebservice.com.gezkonwebservice.Matlab.MatlabMainWindow$BackgroundTask.doInBackground(MatlabMainWindow.java:155)
W/System.err:     at android.os.AsyncTask.call(AsyncTask.java:292)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
W/System.err:     at inovasyonwebservice.com.gezkonwebservice.Matlab.MatlabMainWindow$BackgroundTask.doInBackground(MatlabMainWindow.java:264)
W/System.err:     at inovasyonwebservice.com.gezkonwebservice.Matlab.MatlabMainWindow$BackgroundTask.doInBackground(MatlabMainWindow.java:155)
W/System.err:     at android.os.AsyncTask.call(AsyncTask.java:292)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worke

注意:因为运行在MatlabMainWindowclass,反序列化过程,文件位置,文件权限都没有问题完美

编辑 1: 我刚刚评论了 toString() 部分以进一步阅读投资部分,我实际上遇到的主要错误是这个:

W/System.err: java.io.EOFException
W/System.err:     at libcore.io.Streams.readFully(Streams.java:83)
W/System.err:     at java.io.DataInputStream.readLong(DataInputStream.java:147)

提前致谢各位!

我认为你必须检查这部分代码:

        ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(sdcardFile.getAbsolutePath() + "/Weka/dataset_RFKON/j48.model"));

            j48ClassifierHolder = (Classifier) ois.readObject();
            ois.close();

我认为 j48ClassifierHolder 字段由于异常而状态为 null,这导致 j48ClassifierHolder.toString() 抛出 NullPointerException。 事实上,你 try/catch 这部分,你必须检查你的 logcat 在 NullPointerException.

之前的异常

好的伙计们,我已经弄清楚出了什么问题。在我的 doInBackground() 方法中主要有 3 个部分,它们是通过 Web 服务获取二进制文件、读取和反序列化二进制文件以及将我的对象转换为字符串。

我发现获取二进制文件并将反序列化对象转换为字符串会以某种方式混淆 readObject() 方法。因此,我通过将 Web 服务部分放入 onCreate() 并将字符串转换部分放入 onPostExecute() 来隔离这两个过程。

这是最终代码:

public class MatlabMainWindow extends AppCompatActivity {

private Button treeButton;
private Button positionButton;
private TextView textViewTree;
private PositionDetector positionDetector;
private String treeHolder;
private Classifier j48ClassifierHolder;

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

    treeButton = (Button) findViewById(R.id.button_tree);
    positionButton = (Button) findViewById(R.id.button_position);
    textViewTree = (TextView) findViewById(R.id.textView_tree);

    BinaryHttpRequest binaryHttpRequest = new BinaryHttpRequest(....)

    Volley.newRequestQueue(MatlabMainWindow.this).add(binaryHttpRequest);

    treeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            BackgroundTask task = new BackgroundTask(MatlabMainWindow.this);
            task.execute();
        }
    });

    positionButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                String positionString = positionDetector.calculateThePosition();

                AlertDialog.Builder alert = new AlertDialog.Builder(MatlabMainWindow.this);
                alert.setTitle("Position Prediction");
                alert.setMessage(positionString);
                alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub

                    }
                });
                alert.show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}

private class BackgroundTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;

    public BackgroundTask(MatlabMainWindow activity) {
        dialog = new ProgressDialog(activity);
    }

    @Override
    protected void onPreExecute() {
        dialog.setMessage("Doing something, please wait.");
        dialog.show();
    }

    @Override
    protected void onPostExecute(Void result) {
        try {
            treeHolder = positionDetector.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        textViewTree.setMovementMethod(new ScrollingMovementMethod());
        textViewTree.setText(treeHolder);
        if (dialog.isShowing()) {
            dialog.dismiss();
        }


    }

    @Override
    protected Void doInBackground(Void... params) {

        positionDetector = new PositionDetector();
            try {
        // reading the binary file here 
                positionDetector.getTrainData();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
    }
}
}