Naveed Abbas
Naveed Abbas

Reputation: 1187

Java to Kotlin access class specific variables in different methods

I'm from Objective-C background. I have to create objects programmatically, so trying to explore it in Java and in Kotlin.

In Objective-C We used to declare the instance variables in .h files and access them anywhere in the .m files, is there something similar interface where we declare the variables and object types somewhere and then access them in our kotlin class?

I'm trying to declare a variable that I can access in different methods inside of a class (e.g MainActivity). In Java, it works fine however in Kotlin, I guess I'm having trouble to declare it without initializing it. Need help.

//Here is the Java Code that works fine.
public class MainActivity extends AppCompatActivity {

    **LinearLayout box;**

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        **box = new LinearLayout(this);**

    }

    private void SampleMethod () {
        **box.setBackgroundColor(Color.RED);**
     }
   }

If I try to achieve this in Kotlin, it stops the app with the ERROR provided in stacktrace.

//Here is Kotlin code that is stopping the app. 
class MainActivity : AppCompatActivity() {

   **val sample = TextView(this)** // I need to declare variable here.

   override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    **sample.setText("Hello!")**
    MainContainer.addView(sample)
   }

 fun Test() {
    **sample.setBackgroundColor(Color.RED)**
 }
}

Here is the Stacktrace

07-04 13:16:14.690 12663-12663/? I/zygote: Not late-enabling -Xcheck:jni (already on)
07-04 13:16:15.230 12663-12663/? W/zygote: Unexpected CPU variant for X86 using defaults: x86
07-04 13:16:16.639 12663-12663/com.example.sample.kotlinproject I/InstantRun: starting instant run server: is main process
07-04 13:16:16.938 12663-12663/com.example.sample.kotlinproject D/AndroidRuntime: Shutting down VM
07-04 13:16:16.940 12663-12663/com.example.sample.kotlinproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sample.kotlinproject, PID: 12663
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.sample.kotlinproject/com.example.sample.kotlinproject.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2679)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
    at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
    at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:127)
    at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:121)
    at android.support.v7.app.AppCompatActivity.getResources(AppCompatActivity.java:542)
    at android.view.View.<init>(View.java:4563)
    at android.view.View.<init>(View.java:4706)
    at android.view.ViewGroup.<init>(ViewGroup.java:597)
    at android.widget.LinearLayout.<init>(LinearLayout.java:234)
    at android.widget.LinearLayout.<init>(LinearLayout.java:230)
    at android.widget.LinearLayout.<init>(LinearLayout.java:226)
    at android.widget.LinearLayout.<init>(LinearLayout.java:222)
    at com.example.sample.kotlinproject.MainActivity.<init>(MainActivity.kt:18)
    at java.lang.Class.newInstance(Native Method)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

Upvotes: 2

Views: 1200

Answers (1)

David Rawson
David Rawson

Reputation: 21407

class MainActivity : AppCompatActivity() {


   val sample = TextView(this)

This won't work - and your Android book or tutorial should cover the reason why. It's not enough to instantiate the AppCompatActivity using the constructor to get a fully-fledged instance of the Activity.

In general, it's probably better to wait until onCreate before trying to programatically instantiate a view.

class MainActivity : AppCompatActivity() {

    lateinit var myTextView: TextView

    override fun onCreate(savedInstanceState: Bundle) {
        //instantiate myTextView here if you must 
    }
}

Upvotes: 3

Related Questions