[android] Kotlin Android start new Activity

I want to start another activity on Android but I get this error:

Please specify constructor invocation; classifier 'Page2' does not have a companion object

after instantiating the Intent class. What should I do to correct the error? My code:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun buTestUpdateText2 (view: View) {
        val changePage = Intent(this, Page2) 
        // Error: "Please specify constructor invocation; 
        // classifier 'Page2' does not have a companion object"

        startActivity(changePage)
    }

}

This question is related to android kotlin android-intent android-activity

The answer is


Details

  • Android Studio 3.1.4
  • Kotlin version: 1.2.60

Step 1. Application()

Get link to the context of you application

class MY_APPLICATION_NAME: Application() {

    companion object {
        private lateinit var instance: MY_APPLICATION_NAME
        fun getAppContext(): Context = instance.applicationContext
    }

    override fun onCreate() {
        instance = this
        super.onCreate()
    }

}

Step 2. Add Router object

object Router {
    inline fun <reified T: Activity> start() {
         val context =  MY_APPLICATION_NAME.getAppContext()
         val intent = Intent(context, T::class.java)
         context.startActivity(intent)
    }
}

Usage

// You can start activity from any class: form Application, from any activity, from any fragment and other  
Router.start<ANY_ACTIVITY_CLASS>()

How about this to consider encapsulation?

For example:


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_contents)

        val title = intent.getStringExtra(EXTRA_TITLE) ?: EXTRA_TITLE_DEFAULT

        supportFragmentManager.beginTransaction()
            .add(R.id.frame_layout_fragment, ContentsFragment.newInstance())
            .commit()
    }

    // Omit...

    companion object {

        private const val EXTRA_TITLE = "extra_title"
        private const val EXTRA_TITLE_DEFAULT = "No title"

        fun newIntent(context: Context, title: String): Intent {
            val intent = Intent(context, ContentsActivity::class.java)
            intent.putExtra(EXTRA_TITLE, title)
            return intent
        }
    }

This is my main activity where i take the username and password from edit text and setting to the intent

class MainActivity : AppCompatActivity() {
val userName = null
val password = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
    val intent = Intent(this@MainActivity,SecondActivity::class.java);
    var userName = username.text.toString()
    var password = password_field.text.toString()
    intent.putExtra("Username", userName)
    intent.putExtra("Password", password)
    startActivity(intent);
 }
}

This is my second activity where i have to receive values from the main activity

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
var strUser: String = intent.getStringExtra("Username")
var strPassword: String = intent.getStringExtra("Password")
user_name.setText("Seelan")
passwor_print.setText("Seelan")
}

Simply you can start an Activity in KOTLIN by using this simple method,

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", value)
startActivity(intent)

You can use both Kotlin and Java files in your application.

To switch between the two files, make sure you give them unique < action android:name="" in AndroidManifest.xml, like so:

            <activity android:name=".MainActivityKotlin">
                <intent-filter>
                    <action android:name="com.genechuang.basicfirebaseproject.KotlinActivity"/>
                    <category android:name="android.intent.category.DEFAULT" />
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.genechuang.basicfirebaseproject.MainActivityJava"
                android:label="MainActivityJava" >
                <intent-filter>
                    <action android:name="com.genechuang.basicfirebaseproject.JavaActivity" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>

Then in your MainActivity.kt (Kotlin file), to start an Activity written in Java, do this:

       val intent = Intent("com.genechuang.basicfirebaseproject.JavaActivity")
        startActivity(intent)

In your MainActivityJava.java (Java file), to start an Activity written in Kotlin, do this:

       Intent mIntent = new Intent("com.genechuang.basicfirebaseproject.KotlinActivity");
        startActivity(mIntent);

Well, I found these 2 ways to be the simplest of all outcomes:

Way #1:

accoun_btn.setOnClickListener {
            startActivity(Intent(this@MainActivity, SecondActivity::class.java))
        }

Way#2: (In a generic way)

    accoun_btn.setOnClickListener {
        startActivity<SecondActivity>(this)
    }

    private inline fun <reified T> startActivity(context: Context) {
            startActivity(Intent(context, T::class.java))
        }

sample


To start a new Activity ,

startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java)

So change your code to :

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun buTestUpdateText2 (view: View) {
        startActivity(Intent(this@MainActivity,ClassName::class.java))

        // Also like this 

        val intent = Intent(this@MainActivity,ClassName::class.java)
        startActivity(intent)
    }

Remember to add the activity you want to present, to your AndroidManifest.xml too :-) That was the issue for me.


Try this

val intent = Intent(this, Page2::class.java)
startActivity(intent)

You have to give the second argument of class type. You can also have it a little bit more tidy like below.

startActivity(Intent(this, Page2::class.java).apply {
    putExtra("extra_1", value1)
    putExtra("extra_2", value2)
    putExtra("extra_3", value3)
})

I had a similar issue, I started to write my application in Kotlin, after I rewrote one of my activities I wanted to see if there are any issues, the problem was that I was not sure how to send an intent from java file to kotlin file.

In this case I created a static function in kotlin (companion object), this function is getting a context (from the current activity) and returning the new intent while using the current context ("java" context) while using the kotlin class ("::class.java").

Here is my code:

 //this code will be in the kotlin activity - SearchActivity
 companion object {

    fun newIntent(context: Context): Intent {
        return Intent(context, SearchActivity::class.java)
    }
}

    //this is how you call SearchActivity from MainActivity.java
Intent searchIntent = SearchActivity.Companion.newIntent(this);
startActivity(searchIntent);

From activity to activity

val intent = Intent(this, YourActivity::class.java)
startActivity(intent)

From fragment to activity

val intent = Intent(activity, YourActivity::class.java)
startActivity(intent)

This is because your Page2 class doesn't have a companion object which is similar to static in Java so to use your class. To pass your class as an argument to Intent, you will have to do something like this

val changePage = Intent(this, Page2::class.java)

val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
startActivity(intentAct)

You can generally simplify the specification of the parameter BlahActivity::class.java by defining an inline reified generic function.

inline fun <reified T: Activity> Context.createIntent() =
    Intent(this, T::class.java)

Because that lets you do

startActivity(createIntent<Page2>()) 

Or even simpler

inline fun <reified T: Activity> Activity.startActivity() {
    startActivity(createIntent<T>()) 
} 

So it's now

startActivity<Page2>() 

another simple way of navigating to another activity is

Intent(this, CodeActivity::class.java).apply {
                    startActivity(this)
                }

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to kotlin

No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator How to allow all Network connection types HTTP and HTTPS in Android (9) Pie? Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0 Default interface methods are only supported starting with Android N Error : Program type already present: android.support.design.widget.CoordinatorLayout$Behavior Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 startForeground fail after upgrade to Android 8.1 How to get current local date and time in Kotlin How to add an item to an ArrayList in Kotlin? HTTP Request in Kotlin

Examples related to android-intent

Kotlin Android start new Activity Open Facebook Page in Facebook App (if installed) on Android Android - Adding at least one Activity with an ACTION-VIEW intent-filter after Updating SDK version 23 Not an enclosing class error Android Studio Parcelable encountered IOException writing serializable object getactivity() Sending intent to BroadcastReceiver from adb How to pass ArrayList<CustomeObject> from one activity to another? Android Intent Cannot resolve constructor Android Gallery on Android 4.4 (KitKat) returns different URI for Intent.ACTION_GET_CONTENT Android - java.lang.SecurityException: Permission Denial: starting Intent

Examples related to android-activity

Kotlin Android start new Activity The activity must be exported or contain an intent-filter How to define dimens.xml for every different screen size in android? Activity, AppCompatActivity, FragmentActivity, and ActionBarActivity: When to Use Which? Not an enclosing class error Android Studio java.lang.IllegalStateException: Fragment not attached to Activity Soft keyboard open and close listener in an activity in Android android.app.Application cannot be cast to android.app.Activity Android Shared preferences for creating one time activity (example) Android ListView with onClick items