尝试对空对象引用调用虚拟方法“int java.lang.String.length()”。无效的 API 地址崩溃

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47950334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:44:06  来源:igfitidea点击:

Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference. Invalid API address Crash

javaandroid

提问by Aiden

I'm still kinda new to Android programming and I've been trying to make a simple weather app, for practice. This code works fine when I enter a valid city name, however I want to use a toastthat shows an error to the user when the name is not valid. But this results in a crash, I tried removing the toast, but my app still crashes.

我对 Android 编程还是有点陌生​​,我一直在尝试制作一个简单的天气应用程序,以供练习。当我输入有效的城市名称时,此代码可以正常工作,但是我想使用toast在名称无效时向用户显示错误的 。但这导致崩溃,我尝试删除toast,但我的应用程序仍然崩溃。

Here's the code:

这是代码

public class MainActivity extends AppCompatActivity {

EditText cityName;
TextView resultTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    cityName = (EditText) findViewById(R.id.cityName);
    resultTextView = (TextView) findViewById(R.id.resultTextView);

}


public void findWeather(View view)
{
    Log.i("Button", "pressed");


    InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    mgr.hideSoftInputFromWindow(cityName.getWindowToken(), 0);



    try {

        String encodedCityName = URLEncoder.encode(cityName.getText().toString(), "UTF-8");
        DownloadTask task = new DownloadTask();
        task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + encodedCityName +"&appid=***");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        Toast.makeText(getApplicationContext(), "Could not find city", Toast.LENGTH_LONG);

    }

}


public class DownloadTask extends AsyncTask<String, Void, String>
{

    @Override
    protected String doInBackground(String... strings) {

        String result = "";
        URL url;
        HttpURLConnection urlConnection;

        try {
            url = new URL(strings[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            InputStream in = urlConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);

            int data = reader.read();
            while(data != -1)
            {
                char current = (char) data;
                result += current;
                data = reader.read();
            }
            return  result;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        try{
            String message = "";
            JSONObject jsonObject = new JSONObject(s);
            String weatherInfo = jsonObject.getString("weather");
            Log.i("weather", weatherInfo);

            JSONArray arr = new JSONArray(weatherInfo);

            for(int i = 0; i < arr.length(); i++)
            {
                JSONObject jsonPart = arr.getJSONObject(i);

                String main = "";
                String description = "";

                main = jsonPart.getString("main");
                description = jsonPart.getString("description");

                if (!main.isEmpty() && !description.isEmpty())
                {
                    message += main + ": " + description + "\r\n";

                }
            }

            if(!message.isEmpty())
            {
                resultTextView.setText(message);

            }
            else
            {
                Toast.makeText(getApplicationContext(), "Could not find city", Toast.LENGTH_LONG);
            }

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


    }
}

and the error mesage:

错误信息

12-22 22:11:51.204 4858-4858/com.example.aiden.whatstheweather E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.aiden.whatstheweather, PID: 4858

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116) at org.json.JSONTokener.nextValue(JSONTokener.java:94) at org.json.JSONObject.(JSONObject.java:159) at org.json.JSONObject.(JSONObject.java:176) at com.example.aiden.whatstheweather.MainActivity$DownloadTask.onPostExecute(MainActivity.java:102) at com.example.aiden.whatstheweather.MainActivity$DownloadTask.onPostExecute(MainActivity.java:65) at android.os.AsyncTask.finish(AsyncTask.java:695) at android.os.AsyncTask.-wrap1(Unknown Source:0) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

12-22 22:11:51.204 4858-4858/com.example.aiden.whatstheweather E/AndroidRuntime:致命异常:主进程:com.example.aiden.whatstheweather,PID:4858

java.lang.NullPointerException:尝试在 org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116) 处 org.json.JSONTokener 处的空对象引用上调用虚拟方法“int java.lang.String.length()”。 nextValue(JSONTokener.java:94) at org.json.JSONObject.(JSONObject.java:159) at org.json.JSONObject.(JSONObject.java:176) at com.example.aiden.whatstheweather.MainActivity$DownloadTask。onPostExecute(MainActivity.java:102) at com.example.aiden.whatstheweather.MainActivity$DownloadTask.onPostExecute(MainActivity.java:65) at android.os.AsyncTask.finish(AsyncTask.java:695) at android.os.AsyncTask .-wrap1(Unknown Source:0) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712) at android.os.Handler.dispatchMessage(Handler.java:105) 在 android.os.Looper.loop(Looper.java:164) 在 android.app.ActivityThread.main(ActivityThread.java:6541) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android .internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)164) 在 android.app.ActivityThread.main(ActivityThread.java:6541) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java: 240) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)164) 在 android.app.ActivityThread.main(ActivityThread.java:6541) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java: 240) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

采纳答案by ADM

If any exception occur in doInBackground()its going to return null. Handle it as below.

如果在doInBackground()其返回过程中发生任何异常null。如下处理。

  @Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
   if(s!=null){
    // Do you work here on success
  }else{
     // null response or Exception occur 
    }
}

回答by ThomasEdwin

If doInBackgroundcatches exception, it will only print the stack trace and then return null. The nullis then passed to onPostExecute. The JSONObjectpick the nulland hence the crash. So it'd be better to return empty value than null.

如果doInBackground捕获异常,它只会打印堆栈跟踪,然后返回null。在null随后被传递给onPostExecute。该JSONObjectnull,因此崩溃。所以返回空值比返回空值更好null

In DownloadTask.doInBackground, change

DownloadTask.doInBackground,改变

return null;

to

return "";