【问题标题】:Kotlin Android start new ActivityKotlin Android 启动新 Activity
【发布时间】:2018-01-13 01:28:37
【问题描述】:

我想在 Android 上开始另一个活动,但出现此错误:

请指定构造函数调用;分类器“Page2”没有伴随对象

在实例化 Intent 类之后。我应该怎么做才能纠正错误?我的代码:

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)
    }

}

【问题讨论】:

  • @BakaWaii 该页面已不存在。
  • 在将 Java 应用程序转换为 Kotlin 时出现同样的错误。必须添加依赖项。 IDE实际上是在警告我。但我也在这里找到了答案stackoverflow.com/questions/34144392/…

标签: android kotlin android-intent android-activity


【解决方案1】:

要在java中启动Activity,我们编写了Intent(this, Page2.class),基本上你必须在第一个参数中定义Context,在第二个参数中定义目标类。根据源码中的Intent方法——

 public Intent(Context packageContext, Class<?> cls)

如您所见,我们必须在第二个参数中传递Class&lt;?&gt; 类型。

通过写Intent(this, Page2),我们从未指定我们将通过类,我们试图通过class 类型,这是不可接受的。

在 kotlin 中使用 ::class.java 替代 .class。使用以下代码启动您的Activity

Intent(this, Page2::class.java)

例子-

val intent = Intent(this, NextActivity::class.java)
// To pass any data to next activity
intent.putExtra("keyIdentifier", value)
// start your next activity
startActivity(intent)

【讨论】:

  • 知道为什么他们将其更改为 ::class.java 而不是 .class 吗?与 Java 相比,Kotlin 方法异常复杂。
  • @Mr-IDE class 返回 Kotlin KClass,但 Android 需要 Java Class&lt;...&gt;,因此需要 .java 属性。
【解决方案2】:

只需使用这个简单的方法,您就可以在KOTLIN 中启动一个Activity

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

【讨论】:

  • 你不需要使用 putExtra 方法来开始新的活动。
  • @ShadeToD 是的!无需使用putExtra 方法。我刚刚添加它是为了在开始新的Activity 时传递值
【解决方案3】:

要开始一个新的活动,

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

所以把你的代码改成:

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)
    }

【讨论】:

  • this@Activity 等于 Java 的 Activity.this :)
  • 您忘记在 startActivity(Intent(this@CurrentClassName,RequiredClassName::class.java) 中添加结尾 ')'
【解决方案4】:

您通常可以通过定义内联具体化的泛型函数来简化参数BlahActivity::class.java 的规范。

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

因为这样可以让你做

startActivity(createIntent<Page2>()) 

甚至更简单

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

现在是这样

startActivity<Page2>() 

【讨论】:

  • 作为 kotlin 的新手,您将如何使用它植入可变数量(或没有)的 putExtra()?
  • 你可以设置inline fun &lt;reified T: Activity&gt; Context.createIntent(vararg extras: Pair&lt;String, Any?&gt;) = Intent(this, T::class.java).apply { putExtras(bundleOf(*extras)) }而不是我说的,它会起作用(假设你有来自android-ktx或anko的bundleOf
【解决方案5】:

你必须给出类类型的第二个参数。你也可以让它更整洁一点,如下所示。

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

【讨论】:

  • 干净多了?我现在正在改变我所有的意图以匹配这种格式
【解决方案6】:

试试这个

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

【讨论】:

    【解决方案7】:

    嗯,我发现这两种方法是所有结果中最简单的:

    方式#1:

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

    方式#2:(通用方式)

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

    【讨论】:

      【解决方案8】:

      这是我的主要活动,我从编辑文本中获取用户名和密码并设置为意图

      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);
       }
      }
      

      这是我的第二个活动,我必须从主要活动中接收值

      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")
      }
      

      【讨论】:

        【解决方案9】:

        这是因为您的 Page2 类没有类似于 Java 中的 static 的伴随对象,因此要使用您的类。要将你的类作为参数传递给Intent,你必须做这样的事情

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

        【讨论】:

          【解决方案10】:

          从活动到活动

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

          从片段到活动

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

          【讨论】:

            【解决方案11】:

            另一种导航到另一个活动的简单方法是

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

            【讨论】:

            • 请考虑解释您的代码以及它将如何提供帮助,以便其他人可以从中受益。
            【解决方案12】:
            fun Context.launchActivity(
                cls: Class<*>,
                flags: Int = 0,
                intentTransformer: Intent.() -> Unit = {}
            ) {
                val intent = Intent(this, cls).apply {
                    addFlags(flags)
                    intentTransformer()
                }
                this.startActivity(intent)
            }
            

            【讨论】:

            • 没有任何解释的代码转储很少有帮助。 Stack Overflow 是关于学习的,而不是提供 sn-ps 来盲目复制和粘贴。请edit您的问题并解释它如何比 OP 提供的更好。见How to Answer
            • 对我来说它就像手套一样,让我试着解释一下。在创建这样的函数时,您使用的是先进且有益的 kotlin 技术,这种技术的名称是扩展函数。下面我举个例子:
            【解决方案13】:
            val intentAct: Intent = Intent(this@YourCurrentActivity, TagentActivity::class.java)
            startActivity(intentAct)
            

            【讨论】:

              【解决方案14】:

              我有一个类似的问题,我开始在 Kotlin 中编写我的应用程序,在我重写了我的一个活动之后,我想看看是否有任何问题,问题是我不确定如何从 java 发送意图文件到 kotlin 文件。

              在这种情况下,我在 kotlin(伴随对象)中创建了一个静态函数,该函数在使用 kotlin 的同时使用当前上下文(“java”上下文)获取上下文(从当前活动)并返回新意图类(“::class.java”)。

              这是我的代码:

               //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);
              

              【讨论】:

              • 如果您将@JvmStatic 添加到您的newIntent 方法中,您可以在没有Companion 部分的情况下从java 调用它。
              【解决方案15】:

              这样考虑封装怎么样?

              例如:

              
                  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
                      }
                  }
              

              【讨论】:

                【解决方案16】:

                详情

                • Android Studio 3.1.4
                • Kotlin 版本:1.2.60

                步骤 1.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()
                    }
                
                }
                

                步骤 2. 添加路由器对象

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

                用法

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

                【讨论】:

                  【解决方案17】:

                  记得将你想要展示的活动添加到你的AndroidManifest.xml :-) 这对我来说是个问题。

                  【讨论】:

                    【解决方案18】:

                    您可以在应用程序中同时使用 Kotlin 和 Java 文件。

                    要在两个文件之间切换,请确保在 AndroidManifest.xml 中为它们提供唯一的

                                <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>
                    

                    然后在您的 MainActivity.kt(Kotlin 文件)中,要启动一个用 Java 编写的 Activity,请执行以下操作:

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

                    在您的 MainActivityJava.java(Java 文件)中,要启动一个用 Kotlin 编写的 Activity,请执行以下操作:

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

                    【讨论】:

                      【解决方案19】:

                      扩展功能

                      fun Activity.showToast(message: String, toastLength: Int){
                          //LENGTH_SHORT = 0;
                          //LENGTH_LONG = 1;
                          Toast.makeText(this, message, toastLength).show()
                      }
                      
                      fun Fragment.showToast(message: String, toastLength: Int){
                          //LENGTH_SHORT = 0;
                          //LENGTH_LONG = 1;
                          Toast.makeText(requireContext(), message, toastLength).show()
                      }
                      
                      fun Context.launchActivity(
                          cls: Class<*>,
                          flags: Int = 0,
                          intentTransformer: Intent.() -> Unit = {}
                      ) {
                          val intent = Intent(this, cls).apply {
                              addFlags(flags)
                              intentTransformer()
                          }
                          this.startActivity(intent)
                      }
                      

                      在活动调用中

                      showToast("message to be shown", 1)
                      

                      在片段调用中

                      showToast("message to be shown", 1)
                      

                      从任何地方开始活动

                       launchActivity(MainActivity::class.java, Intent.FLAG_ACTIVITY_NEW_TASK)
                      

                      Kotlin Extension function

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-07-28
                        • 2012-09-06
                        • 2013-06-15
                        • 1970-01-01
                        相关资源
                        最近更新 更多