Reputation: 143
I'm a beginner with Android Studio and Kotlin. I get the following error when trying to change the text of a TextView using Synthetic Binding from within my class.
Unable to start activity ComponentInfo{com.oppenheimer.myapplication/com.oppenheimer.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
The code up to "Some other text" works but when I try with "Very new phrase" from within the class it crashes. It seems to be a common error but I'm not finding other posts that match my issue.
Here is my code
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/MyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val myClass = MyClass()
myClass.MyFunction()
}
}
MyClass.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MyClass : AppCompatActivity() {
fun MyFunction () {
MyText.text = "Very new phrase"
}
}
Full Error
2020-05-02 13:13:50.784 3632-3632/com.oppenheimer.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.oppenheimer.myapplication, PID: 3632
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.oppenheimer.myapplication/com.oppenheimer.myapplication.MainActivity}: 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:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
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:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
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:163)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:174)
at android.content.Context.obtainStyledAttributes(Context.java:738)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:692)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:479)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214)
at com.oppenheimer.myapplication.MyClass._$_findCachedViewById(Unknown Source:25)
at com.oppenheimer.myapplication.MyClass.MyFunction(MyClass.kt:10)
at com.oppenheimer.myapplication.MainActivity.onCreate(MainActivity.kt:18)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
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:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
How do I change the layout from within a class? What is the "right" way to do this? Should I Pass the TextView into the class?
Thanks
Upvotes: 1
Views: 774
Reputation: 373
If you really need to, you could access MyText and alter its value by passing a reference of it to MyClass and to MyFunction() as a parameter.
MainActivity.kt
package com.oppenheimer.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val textView = findViewById<TextView>(R.id.MyText)
val myClass = MyClass(textView)
myClass.MyFunction(textView)
}
}
MyClass.kt
package com.oppenheimer.myapplication
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MyClass(textView: TextView) : AppCompatActivity() {
fun MyFunction (textView: TextView) {
textView.text = "Very new phrase"
}
}
Please note also that following naming conventions is good software practice and therefore all function names should start with a small letter, myFunction().
Upvotes: 1
Reputation: 373
Generally speaking, you should not be trying to access a layout item from within another class, which is why you get an error.
Move it to the MainActivty's onCreate() function:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyText.text = "Some other text"
val myClass = MyClass()
myClass.MyFunction()
MyText.text = "Very new phrase"
}
}
MyClass.kt
class MyClass : AppCompatActivity() {
fun MyFunction () {
}
}
Upvotes: 1