尝试在空对象引用上调用虚方法'void java.io.BufferedReader.close()'

时间:2015-10-16 20:04:38

标签: java android

尝试在空对象引用上调用虚方法'void java.io.BufferedReader.close()'这个异常被JRE引发请帮助!!

这是班级

package com.example.MovieMania.fragmentTv;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;





import com.example.MovieMania.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.AdapterView.OnItemClickListener;

public class BackgroundTaskTv extends AsyncTask<String, Void, String[]> {

    final String DEF_BASE_URL = "http:api.themoviedb.org/3/tv/popular?[api_key]";

    private final Context context;

    public BackgroundTaskTv(Context context) {
        this.context = context;
    }

    public static String JsonStr;  // so that JSONstring can be used by other activities

    private String[] jsonParse(String movieJsonStr) throws JSONException {

        final String POSTER_PATH = "poster_path"; // JSON STRING PARSING AND
                                                    // RETURN
                                                    // POSTER PATHS

        JSONObject jsonObj = new JSONObject(movieJsonStr);
        JSONArray resultArray = jsonObj.getJSONArray("results");

        int len =resultArray.length();
        String[] posters = new String[len];
        for (int i = 0; i < len; i++) {
            posters[i] = resultArray.getJSONObject(i).getString(POSTER_PATH);
        }

        for (String res : posters)
            Log.v(POSTER_PATH, res);

        return posters;

    }

    @Override
    protected String[] doInBackground(String... params) {



        String movieJsonStr = null;
        InputStream inputStream = null;


        String FINAL_URL=DEF_BASE_URL;
        ImageAdapterTv.poster_paths.clear();

        BufferedReader reader = null;
        HttpURLConnection urlConnection = null; // READ THE INPUTSTREAM AND
                                                // GET THE JSONSTRING
        try {
            URL url = new URL(FINAL_URL);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }

            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it
                // won't affect parsing)
                // But it does make debugging a *lot* easier if you print
                // out the completed
                // buffer for debugging.
                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty. No point in parsing.
                return null;
            }

            movieJsonStr = buffer.toString();
            JsonStr=movieJsonStr;

            Log.v("Tv string: ", movieJsonStr);
        } catch (Throwable e) {
            Log.e("backgroundtask", "EXCEPTION", e);
        } finally {
            urlConnection.disconnect();
            try {
                reader.close();
                inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }
        }

        try {
            return jsonParse(movieJsonStr);
        } catch (JSONException e) {
            Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(String[] result) {
        if (ImageAdapterTv.poster_paths.isEmpty()) {
            for (String s : result) {
                ImageAdapterTv.poster_paths.add(s);
            }
        }

        final Activity activity = (Activity) context;
        activity.runOnUiThread(new Runnable() {
            @Override
            // this code is written so that the grid view is populated after
            // backgroundTask
            public void run() { // produce results so that there is no blank
                                // screen on launch
                GridView grid = (GridView) activity.findViewById(R.id.gridview_tv);
                grid.setAdapter(new ImageAdapterTv(context));

                grid.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        String path=ImageAdapterTv.poster_paths.get(position);
                        Intent intent=new Intent(context,DetailActivityTv.class);
                        intent.putExtra("poster", path);
                        intent.putExtra("POSITION", position);
                        activity.startActivity(intent);
                        }
                });

                }
        });
    }

}

这是一个后台线程,它从api获取json响应 我不知道为什么抛出这个异常。

5 个答案:

答案 0 :(得分:3)

如果在初始化阅读器之前发生异常,则会导致此错误,因为reader.close()位于finally块中。最好在关闭finally

中的资源之前始终检查null
if(reader != null)
    reader.close();
if(inputStream != null)
    inputStream.close();

答案 1 :(得分:1)

你需要检查&#34; Null&#34;在最后。事情正在发生,读者没有创造。

            try {
                if (reader != null) reader.close();
                if (inputStream!= null) inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }

你做return null,但终于完成了。在其中BufferedReader reader = null;。请参阅示例

public static void main(String[] args){
    System.out.println(0);
    Object o = get();
    System.out.println(2);
}

public static Object get(){
    try {
        System.out.println(1);
        return null;
    } catch (Exception e){

    } finally {
        System.out.println("finally");
    }
    return null;
}

<强>输出:

  

0   1   最后   2

答案 2 :(得分:1)

它可能是由于你的urlconnection中的异常或你的输入流为空而引起的。

if (inputStream == null)
return null;

如果抛出异常或从inputstream null检查调用return,则代码将最终运行阻塞。

永远不会创建使用inputstream创建的Reader对象。所以当你尝试close()方法时,它会抛出空指针异常。

在对流和读者,编写者使用close()方法之前,应始终使用空检查。

答案 3 :(得分:1)

从描述中可以看出,当您尝试关闭BufferedReader reader块中的finally对象时,会发生异常,因为此时nulltry。之所以会发生这种情况,是因为在初始化阅读器之前,return块中出现了一些其他异常,或者因为调用了 URL url = new URL(FINAL_URL); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.connect(); // Read the input stream into a String inputStream = urlConnection.getInputStream(); StringBuffer buffer = new StringBuffer(); if (inputStream == null) { // Nothing to do. return null; } 语句,即在这段代码中的某处:

reader

为了避免这种情况,您应该在关闭之前检查inputStreamnull if(reader != null) { reader.close; reader = null; } if(inputStream != null) { inputStream.close; inputStream = null; }

try-catch

除了看看这篇关于捕捉Throwables的帖子: Is it a bad practice to catch Throwable?

无论如何,我认为你应该找出为什么会发生这种情况,因为根据我的理解,这不是你想要的

为什么要将这段代码移到第一个try { return jsonParse(movieJsonStr); } catch (JSONException e) { Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e); } 之外?:

try{}

您可以从一个JSONOblect中捕获多种类型的异常,您只需逐个指定它们即可。 如上所述,当出现问题(并且确实存在)时,您在创建读者之前完成了之前的try-catch块,之后就完成了所有操作。因此,在这个地方你的movieJsonStr也是null,你将它向前传递以从中创建return jsonParse(movieJsonStr);。这是您下一个例外的来源。将default字符串移动到您确定它是您要处理的字符串的位置。

答案 4 :(得分:0)

有时这是问题所在,因为您正在关闭未分配任何值或其值为null的BufferedReader。因此会抛出异常 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'void java.io.BufferedReader.close()' 解决此问题的方法:转到清单文件并授予INTERNET权限