Android Java接口回调onPostExecute空指针异常。

3

I have the following classes:

Main.java

package com.example.webapp;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;

public class Main extends Activity {


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.settings:
                showSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    final Handler handler = new Handler()
    {
        public void handleMessage(Message msg) 
        {

            try {
                final String result = msg.toString();
                JSONObject jObject  = new JSONObject(result.toString());
                mainView(jObject);
              }
              catch(JSONException e) {
                e.getCause();
              }


        };
    };

    public void mainView(JSONObject result){

    }

    public void showSettings(){
        setContentView(R.layout.settings);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Oncreate","1");
        String url = "http://xxx.xxx.xxx/webapp/server.php?method=getPageIndexLiveValues";
        Log.d("Oncreate","2");
        JSONhandler parser = new JSONhandler(this);
        parser.execute(url);

        Log.d("Oncreate","3");



    }


        public void onRequestCompleted(JSONObject result) {
            setContentView(R.layout.main);
           Log.d("onRequestComplete","complete");
            try {
                TextView test1 = (TextView) findViewById(R.id.textView1);
                test1.setText(result.getString("GP").toString()+"W");
                TextView test2 = (TextView) findViewById(R.id.textView2);
                test2.setText(result.getString("IP").toString()+"W");
                TextView test3 = (TextView) findViewById(R.id.textView3);
                test3.setText(result.getString("EFF").toString()+"%");

                Time today = new Time(Time.getCurrentTimezone());
                today.setToNow();


                TextView textViewDay = (TextView) findViewById(R.id.textDateTime);

                textViewDay.setText(today.monthDay+"-"+(today.month+1)+"-"+today.year+" "+today.format("%k:%M:%S"));             // Day of the month (0-31)

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }



}

JSONhandler.java 包 com.example.webapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

public class JSONhandler extends AsyncTask<String, Void, JSONObject> {

    //private static final JSONObject JSONObject = null;
    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    public JSONhandler(Main main){

    }

    public interface MyCallbackInterface {
        public void onRequestCompleted(JSONObject json);
    }

    private MyCallbackInterface mCallback;

    public void JSONParser(MyCallbackInterface callback) {
        mCallback = callback;
    }

    public JSONObject getJSONFromUrl(String url) { 
        Log.d("getJSONFromUrl","1");        
        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;


    }

    @Override
    protected JSONObject doInBackground(String... params) {
        Log.d("doInBackground","1");
        String url = params[0];
        Log.d("doInBackground",url);
        Log.d("doInBackground","2");
        return getJSONFromUrl(url);
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        Log.d("onPostExecute",result.toString());

        //In here, call back to Activity or other listener that things are done
        try{
            JSONObject json = result.getJSONObject("sumIn");
            Log.d("onPostE Sum",json.toString());
            mCallback.onRequestCompleted(json); //<<<<<< See bel
        }catch(JSONException e){
            Log.d("onPostE Sum",json.toString());
        }
    }
}

!!!!ERROR MESSAGE!!!!
E/AndroidRuntime(2237): FATAL EXCEPTION: main
E/AndroidRuntime(2237): java.lang.NullPointerException
E/AndroidRuntime(2237):     at com.example.webapp.JSONhandler.onPostExecute(JSONhandler.java:107)
E/AndroidRuntime(2237):     at com.example.webapp.JSONhandler.onPostExecute(JSONhandler.java:1)
and a lot more.....

我对Java / Android非常陌生,无法理解这里发生了什么。 希望有人能帮我。

更新的代码: 我更新了代码,但仍然在第107行(//<<<<请参见下文)出现错误。 当json正确初始化时,代码会在mCallback错误中运行。 当json为空时,TryCatch捕获错误并记录“empty”。

Main的新代码并按照Sam的建议更改了代码。

package com.example.webapp;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;

import com.example.webapp.JSONhandler.MyCallbackInterface;

    public class Main extends Activity implements MyCallbackInterface  {


        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle item selection
        switch (item.getItemId()) {
            case R.id.settings:
                showSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    final Handler handler = new Handler()
    {
        public void handleMessage(Message msg) 
        {

            try {
                final String result = msg.toString();
                JSONObject jObject  = new JSONObject(result.toString());
                mainView(jObject);
              }
              catch(JSONException e) {
                e.getCause();
              }


        };
    };

    public void mainView(JSONObject result){

    }

    public void showSettings(){
        setContentView(R.layout.settings);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Oncreate","1");
        String url = "http://xxx.xxx.xxx";
        Log.d("Oncreate","2");
        JSONhandler parser = new JSONhandler(this);
        parser.execute(url);

        Log.d("Oncreate","3");



    }

    @Override
    public void onRequestCompleted(JSONObject result) {
        setContentView(R.layout.main);
        Log.d("onRequestComplete","complete");
            try {
                TextView test1 = (TextView) findViewById(R.id.textView1);
                test1.setText(result.getString("GP").toString()+"W");
                TextView test2 = (TextView) findViewById(R.id.textView2);
                test2.setText(result.getString("IP").toString()+"W");
                TextView test3 = (TextView) findViewById(R.id.textView3);
                test3.setText(result.getString("EFF").toString()+"%");

                Time today = new Time(Time.getCurrentTimezone());
                today.setToNow();


                TextView textViewDay = (TextView) findViewById(R.id.textDateTime);

                textViewDay.setText(today.monthDay+"-"+(today.month+1)+"-"+today.year+" "+today.format("%k:%M:%S"));             // Day of the month (0-31)

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }



}

新的JSONhandler代码,并根据Sam的建议更改了代码。
package com.example.webapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

public class JSONhandler extends AsyncTask<String, Void, JSONObject> {

    //private static final JSONObject JSONObject = null;
    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    public JSONhandler(Main main){

    }

    public interface MyCallbackInterface {
        public void onRequestCompleted(JSONObject json);
    }

    private MyCallbackInterface mCallback;

    public JSONhandler(MyCallbackInterface callback) {
        mCallback = callback;
    }

    public JSONObject getJSONFromUrl(String url) { 
        Log.d("getJSONFromUrl","1");        
        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;


    }

    @Override
    protected JSONObject doInBackground(String... params) {
        Log.d("doInBackground","1");
        String url = params[0];
        Log.d("doInBackground",url);
        Log.d("doInBackground","2");
        return getJSONFromUrl(url);
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        Log.d("onPostExecute",result.toString());

        //In here, call back to Activity or other listener that things are done
        try{
            JSONObject json = result.getJSONObject("sumInvrters");
            Log.d("onPostE Sum",json.toString());
            mCallback.onRequestCompleted(json); //<<<< see below 
        }catch(JSONException e){
            Log.d("onPostE Sum","empty");
        }
    }
}

只有一个问题:你是新手程序员吗?如果是这样,我建议你搜索一下什么是NullPointerException,了解它之所以会出现是因为变量/对象/某些东西在其值为null时被使用,并进行调试以查明为什么是null。只有在尝试解决此问题并没有得到解决方案后,再来这里向人们寻求提示。 - Luiggi Mendoza
哪一行代码引起了异常? - Code-Apprentice
@LuiggiMendoza:我是Java的新手,但我试图理解发生了什么(看看我的log.d,我这样做是希望看到出了什么问题)。我明白 //<<<< see bel(ow) 这行出了问题,但由于JSONObject json记录的是预期的值,我就没看出来。 - marco
2个回答

2

通过LogCat和您的笔记:

mCallback.onRequestCompleted(json); //<<<<<< See bel

看起来mCallback是空的,因为你忘记定义它了。让我们稍微改变一下:

  1. Have your Activity implement your callback:

    public class Main extends Activity implements MyCallbackInterface {
    

    And add @Override to onRequestCompleted() if necessary.

  2. Remove the JSONhandler constructor that expects an Activity and replace it with one that expects your interface.


    So remove this code:

    public JSONhandler(Main main){
    
    }
    
    public void JSONParser(MyCallbackInterface callback) {
        mCallback = callback;
    }
    


    Use this constructor instead:

    public JSONhandler(MyCallbackInterface callback) {
        mCallback = callback;
    }
    
现在这段代码应该可以正常工作:
JSONhandler parser = new JSONhandler(this);
parser.execute(url);

谢谢您的回复!您提到的那一行确实是导致异常的那一行。我已经更改了代码,但仍然遇到了NullPointerException。当JSONObject json为空时,代码可以正常运行,但(我认为)这是因为Try捕获了json的null值。但是当JSONObject json被填充时,代码在mCallback.onRequestCompleted(json)行遇到了NullPointerException。很快会发布更新后的代码,希望您能继续帮助我。 - marco
1
你还有一个带有Main参数的构造函数,请从你的代码中移除它:public JSONhandler(Main main){} - Sam

0
第107行的一个值为空。假设您已经在注释“见下文”的那一行,那么很可能是mCallback为空。这是因为JSONParse从未被调用。请注意,这是一个函数而不是构造函数 - 它是否应该是一个构造函数?

它被设计为一个构造函数,Sam在他的代码示例中也提到了它。谢谢你的输入。 - marco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接