英文:
Why am I getting NullPointerException error ? trying to pass a value from an edit text
问题
代码中出现了一个错误,导致应用崩溃的原因是在 ManualSearchActivity
类的成员变量中,EnterCityEditText
的值在 onCreate
方法外部被初始化。这会导致 EnterCityEditText
在初始化时为 null
,因此在后续的 doInBackground
方法中使用它时会引发空指针异常。
为了解决这个问题,您应该在 doInBackground
方法内部获取 EnterCityEditText
的值,而不是在类的成员变量中初始化它。以下是修复后的代码:
inner class weatherCall() : AsyncTask<String, Void, String>() {
override fun onPreExecute() {
super.onPreExecute()
findViewById<ProgressBar>(R.id.loader).visibility = View.VISIBLE
findViewById<RelativeLayout>(R.id.mainRelativeContainer).visibility = View.GONE
findViewById<TextView>(R.id.ErrorText).visibility = View.GONE
}
override fun doInBackground(vararg p0: String?): String? {
var response: String?
try {
val EnterCityEditText = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
response = URL("https://api.openweathermap.org/data/2.5/weather?q=$EnterCityEditText&units=metric&APPID=yourapi").readText(Charsets.UTF_8)
} catch (e: Exception) {
response = null
}
return response
}
// ... 省略其余的代码
}
通过在 doInBackground
方法内部获取 EnterCityEditText
的值,您可以解决空指针异常问题,并正确地将城市名称传递到 URL 中,以进行天气查询。感谢David Wasser的提示。
英文:
Manual Search Activity Code:
package com.example.theweathertoday
import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.json.JSONObject
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*
class ManualSearchActivity : AppCompatActivity()
{
val API : String = "your api"
val EnterCityEditText: String = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_manual_search)
val SearchCityButton = findViewById<Button>(R.id.button_search_city)
SearchCityButton.setOnClickListener(View.OnClickListener { weatherCall().execute() })
}
inner class weatherCall() : AsyncTask<String, Void, String>()
{
override fun onPreExecute()
{
super.onPreExecute()
findViewById<ProgressBar>(R.id.loader).visibility = View.VISIBLE
findViewById<RelativeLayout>(R.id.mainRelativeContainer).visibility = View.GONE
findViewById<TextView>(R.id.ErrorText).visibility = View.GONE
}
override fun doInBackground(vararg p0: String?): String?
{
var response:String?
try
{
response = URL( "https://api.openweathermap.org/data/2.5/weather?q=$EnterCityEditText&units=metric&APPID=yourapi").readText(Charsets.UTF_8)
}
catch (e: Exception)
{
response = null
}
return response
}
override fun onPostExecute(result: String?)
{
super.onPostExecute(result)
try
{
//JSON Return Values from the API
val jsonObj = JSONObject(result)
val main = jsonObj.getJSONObject("main")
val sys = jsonObj.getJSONObject("sys")
val wind = jsonObj.getJSONObject("wind")
val weather = jsonObj.getJSONArray("weather").getJSONObject(0)
val updatedAt:Long = jsonObj.getLong("dt")
val updatedAtText = "Updated at: "+ SimpleDateFormat("dd/MM/yyyy hh:mm a", Locale.ENGLISH).format(Date(updatedAt*1000))
val temp = main.getString("temp")+"°C"
val tempMin = "Min Temp: " + main.getString("temp_min")+"°C"
val tempMax = "Max Temp: " + main.getString("temp_max")+"°C"
val pressure = main.getString("pressure")
val humidity = main.getString("humidity")
val sunrise:Long = sys.getLong("sunrise")
val sunset:Long = sys.getLong("sunset")
val windSpeed = wind.getString("speed")
val weatherDescription = weather.getString("description")
val address = jsonObj.getString("name")+", "+sys.getString("country")
/* Populating extracted data into our views */
findViewById<TextView>(R.id.location_xml_id).text = address
findViewById<TextView>(R.id.updated_at_xml_id).text = updatedAtText
findViewById<TextView>(R.id.status_xml_id).text = weatherDescription.capitalize()
findViewById<TextView>(R.id.temperature_xml_id).text = temp
findViewById<TextView>(R.id.min_temp_xml_id).text = tempMin
findViewById<TextView>(R.id.max_temp_xml_id).text = tempMax
findViewById<TextView>(R.id.sunrise).text = SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(Date(sunrise*1000))
findViewById<TextView>(R.id.sunset).text = SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(Date(sunset*1000))
findViewById<TextView>(R.id.wind).text = windSpeed
findViewById<TextView>(R.id.pressure).text = pressure
findViewById<TextView>(R.id.humidity).text = humidity
/* Views populated, Hiding the loader, Showing the main design */
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<RelativeLayout>(R.id.mainRelativeContainer).visibility = View.VISIBLE
} catch (e: Exception) {
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<TextView>(R.id.ErrorText).visibility = View.VISIBLE
}
}
}
}
activity_manual_search.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/gradient_bg"
tools:context=".ManualSearchActivity">
<RelativeLayout
android:id="@+id/mainRelativeContainer"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/locationContainer"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/enter_city_text"
android:text="Enter City Name: "
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/enter_city_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/enter_city_text"
android:maxLines="1"
android:singleLine="true"/>
<Button
android:id="@+id/button_search_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search for City"
android:layout_gravity="center"
android:layout_below="@+id/enter_city_edit_text"
android:layout_centerHorizontal="true"
android:textColor="#ffffff"
android:background="#0048ff"/>
<TextView
android:id="@+id/location_xml_id"
android:textSize="25sp"
android:text="Location"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/updated_at_xml_id"
android:textSize="15sp"
android:text="Updated at"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<LinearLayout
android:id="@+id/overviewContainer"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/status_xml_id"
android:textSize="35sp"
android:layout_gravity="center"
android:text="Clear Sky"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/temperature_xml_id"
android:textSize="70sp"
android:fontFamily="sans-serif-thin"
android:layout_gravity="center"
android:text="Temperature"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<LinearLayout
android:id="@+id/temperature_min_max_xml_id"
android:orientation="horizontal"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/min_temp_xml_id"
android:text="Min Temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<Space
android:layout_width="50dp"
android:layout_height="wrap_content">
</Space>
<TextView
android:id="@+id/max_temp_xml_id"
android:text="Max Temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/detailsContainer"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/sunrise"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Sunrise"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/sunrise"
android:textSize="14sp"
android:text="AM"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/sunset"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Sunset"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/sunset"
android:textSize="14sp"
android:text="PM"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/wind"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Wind"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/wind"
android:textSize="14sp"
android:text="Wind"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="10dp"></Space>
<LinearLayout
android:orientation="horizontal"
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/pressure"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Pressure"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/pressure"
android:textSize="14sp"
android:text="Pressure"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/humidity"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Humidity"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/humidity"
android:textSize="14sp"
android:text="Humidity"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
<LinearLayout
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:padding="9dp"
android:background="#969696"
android:layout_width="0dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/info"
app:tint="#FFF">
</ImageView>
<Space
android:layout_width="wrap_content"
android:layout_height="5dp">
</Space>
<TextView
android:textSize="12sp"
android:text="Weather Forecast"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/info"
android:textSize="14sp"
android:text="Next 10 days"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Space
android:layout_width="10dp"
android:layout_height="wrap_content">
</Space>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<ProgressBar
android:id="@+id/loader"
android:layout_centerInParent="true"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ProgressBar>
<TextView
android:id="@+id/ErrorText"
android:layout_centerInParent="true"
android:text="Error couldn't connect ?"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
Error here:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.theweathertoday, PID: 18698
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.theweathertoday/com.example.theweathertoday.ManualSearchActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3365)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:173)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:174)
at android.content.Context.obtainStyledAttributes(Context.java:744)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:922)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:889)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:691)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:264)
at com.example.theweathertoday.ManualSearchActivity.<init>(ManualSearchActivity.kt:22)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:223) 
at android.app.ActivityThread.main(ActivityThread.java:7656) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
I am trying to pass a value from an edit text to a function, that value is the city name
You can see it inside the URL $EnterCityEditText, I converted the Edit Text entry to String I guess ?
A city name should appear and replace the placeholder value of course
Edit this is the solution, Thanks for David Wasser for hinting
override fun doInBackground(vararg p0: String?): String?
{
var response:String?
try
{
val EnterCityEditText = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
response = URL( "https://api.openweathermap.org/data/2.5/weather?q=$EnterCityEditText&units=metric&APPID=yourapi").readText(Charsets.UTF_8)
}
catch (e: Exception)
{
response = null
}
return response
}
答案1
得分: 0
这是你的问题:
val EnterCityEditText: String = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
你已经将这个变量声明为类的成员变量。当类的实例被创建时,Android 尝试通过调用 findViewById()
来初始化这个变量。这会失败,因为 Activity
还没有完全初始化(onCreate()
尚未被调用),而且你必须等到调用 setContentView()
之后才能继续。
将变量的初始化移到 onCreate()
中,确保在调用 setContentView()
之后进行初始化。
英文:
This is your problem:
val EnterCityEditText: String = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
You've declared this variable as a member variable in your class. When the instance of the class is instantiated, Android attempts to initialize this variable by calling findViewById()
. This fails because the Activity
has not yet been completely initialized (onCreate()
has not yet been called) and you must also wait until after setContentView()
has been called.
Move the initialization of the variable into onCreate()
after you have called setContentView()
.
答案2
得分: 0
将以下部分翻译为中文:
需要将以下代码:
val EnterCityEditText: String = findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
移动到以下代码之后:
setContentView()
在调用setContentView()
之前不能使用findViewById
。
英文:
You need to move this
> val EnterCityEditText: String =
> findViewById<EditText>(R.id.enter_city_edit_text).text.toString()
after
> setContentView()
You can not use findViewById before "setContentView()"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论