尝试对空对象引用调用虚拟方法“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
Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference. Invalid API address Crash
提问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 toast
that 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 doInBackground
catches exception, it will only print the stack trace and then return null
. The null
is then passed to onPostExecute
. The JSONObject
pick the null
and hence the crash. So it'd be better to return empty value than null
.
如果doInBackground
捕获异常,它只会打印堆栈跟踪,然后返回null
。在null
随后被传递给onPostExecute
。该JSONObject
挑null
,因此崩溃。所以返回空值比返回空值更好null
。
In DownloadTask.doInBackground
, change
在DownloadTask.doInBackground
,改变
return null;
to
到
return "";