【问题标题】:Start an Activity with a parameter带参数启动 Activity
【发布时间】:2011-04-24 05:42:07
【问题描述】:

我是 Android 开发的新手。

我想创建并启动一项活动以显示有关游戏的信息。我表明我需要一个 gameId 的信息。

如何将此游戏 ID 传递给活动?游戏 ID 是绝对必要的,所以如果没有 ID,我不想创建或启动活动。

就像活动只有一个参数的一个构造函数。

我该怎么做?

谢谢。

【问题讨论】:

    标签: android android-activity oncreate


    【解决方案1】:

    将您的 ID int 放入新的 Intent

    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    Bundle b = new Bundle();
    b.putInt("key", 1); //Your id
    intent.putExtras(b); //Put your id to your next Intent
    startActivity(intent);
    finish();
    

    然后在你的新Activity 中获取 id:

    Bundle b = getIntent().getExtras();
    int value = -1; // or other values
    if(b != null)
        value = b.getInt("key");
    

    【讨论】:

    • 在开始抓取之前,您可能需要确保 b != null
    • 如何在此代码的第二个活动中“b”为空?我在第二个活动的创建方法上得到 b 为空。
    • B 可以为空,假设您想从另一个地方开始此活动,并且您以标准方式进行,没有参数。它会抛出一个 NPE。您应该始终认为此参数是可选的。
    • 没有必要创建一个新的 Bundle(如果你这样做,the documentation 说你“必须”使用包名作为密钥的前缀。)只需使用 intent.putExtra(String, Int)
    • 有人可能会争辩说最好不要进行空检查。 en.wikipedia.org/wiki/Fail-fast.
    【解决方案2】:

    只需向用于调用活动的 Intent 添加额外数据即可。

    在调用者活动中:

    Intent i = new Intent(this, TheNextActivity.class);
    i.putExtra("id", id);
    startActivity(i);
    

    在您调用的活动的 onCreate() 内部:

    Bundle b = getIntent().getExtras();
    int id = b.getInt("id");
    

    【讨论】:

    • 可以传入自定义对象类型吗?
    • @Amyth 不,您必须使用已接受答案中的捆绑包。
    • 这个答案应该是被接受的。整个 Bundle 的废话是不必要的。
    • @Amyth 查看 API 的签名,看起来任何自定义类型都需要可打包或可序列化。大概是因为 andriod 活动 API 是在假设新活动可能在不同的进程中设计的。
    【解决方案3】:

    我喜欢在第二个活动中使用静态方法:

    private static final String EXTRA_GAME_ID = "your.package.gameId";
    
    public static void start(Context context, String gameId) {
        Intent intent = new Intent(context, SecondActivity.class);
        intent.putExtra(EXTRA_GAME_ID, gameId);
        context.startActivity(intent);
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ... 
        Intent intent = this.getIntent();
        String gameId = intent.getStringExtra(EXTRA_GAME_ID);
    }
    

    然后从您的第一个活动(以及其他任何地方)开始,您只需:

    SecondActivity.start(this, "the.game.id");
    

    【讨论】:

    • 正是我想要的!谢谢
    • 在onCreate方法中String gameId = intent.getStringExtra(EXTRA_EXTERNAL_ID);不应该是String gameId = intent.getStringExtra(EXTRA_GAME_ID);
    • 拥有静态数据会使您的测试非常困难。
    • 这是内存泄漏吗?将上下文传递给静态方法对我来说似乎是个坏主意。为什么不直接返回意图,然后使用第一类的意图开始活动?
    【解决方案4】:

    Kotlin 代码:

    启动SecondActivity:

    startActivity(Intent(context, SecondActivity::class.java)
        .putExtra(SecondActivity.PARAM_GAME_ID, gameId))
    

    获取SecondActivity中的Id:

    class CaptureActivity : AppCompatActivity() {
    
        companion object {
            const val PARAM_GAME_ID = "PARAM_GAME_ID"
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val gameId = intent.getStringExtra(PARAM_GAME_ID)
            // TODO use gameId
        }
    }
    

    其中gameIdString? (可以为空)

    【讨论】:

      【解决方案5】:

      现有答案(将Intent 中的数据传递给startActivity())显示了解决此问题的正常方法。还有另一种解决方案可以在您创建一个将由另一个应用程序启动的活动(例如,Tasker 插件中的一个编辑活动)的奇怪情况下使用,因此不控制@987654324 @ 启动 Activity

      你可以创建一个基类Activity,它有一个带参数的构造函数,然后是一个派生类,它有一个默认构造函数,它用一个值调用基类构造函数,如下所示:

      class BaseActivity extends Activity
      {
          public BaseActivity(String param)
          {
              // Do something with param
          }
      }
      
      class DerivedActivity extends BaseActivity
      {
          public DerivedActivity()
          {
              super("parameter");
          }
      }
      

      如果您需要生成要传递给基类构造函数的参数,只需将硬编码的值替换为返回正确值的函数调用即可传递。

      【讨论】:

        猜你喜欢
        • 2018-08-29
        • 1970-01-01
        • 2013-07-18
        • 1970-01-01
        • 2011-07-07
        • 2012-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多