Начать действие с параметром


292

Я очень новичок в разработке Android.

Я хочу создать и запустить мероприятие, чтобы показать информацию об игре. Я показываю эту информацию, мне нужен идентификатор игры.

Как я могу передать этот игровой идентификатор на активность? Идентификатор игры абсолютно необходим, поэтому я не хочу создавать или запускать игру, если у нее нет идентификатора.

Это похоже на то, что у действия есть только один конструктор с одним параметром.

Как я могу это сделать?

Спасибо.

Ответы:


506

Поместите 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:

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

42
Возможно, вы захотите убедиться, что b! = Null, прежде чем вы начнете его захватывать
Эндрю

Как «b» может быть нулевым во втором действии в этом коде? Я получаю нулевое значение при создании метода второго действия.
Мурат Чорлу

3
B может быть нулевым, скажем, вы хотите начать это действие из другого места, и вы делаете это стандартным способом, без параметров. Это бросит NPE. Вы должны всегда считать эти параметры необязательными.
Гаспар де Элиас

53
Нет необходимости создавать новый Bundle (и, если вы это делаете, в документации говорится, что вы «должны» использовать имя пакета для префикса ключей). Просто используйте intent.putExtra(String, Int).
Сэм

1
Можно утверждать, что лучше не делать нулевую проверку. en.wikipedia.org/wiki/Fail-fast .
setholopolus

124

Просто добавьте дополнительные данные в намерение, которое вы используете для вызова своей деятельности.

В вызывающей деятельности:

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

Внутри onCreate () действия, которое вы вызываете:

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

1
это нормально, чтобы передать пользовательский тип объекта?
Амит

1
@ Амит Нет, вы должны использовать пакет, как в принятом ответе.
AtlasRider

Посмотрите это @Amyth: stackoverflow.com/questions/14333449/…
Cold

38

Мне нравится делать это статическим методом во втором упражнении:

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

Именно то, что я искал! Спасибо
Маттео

1
В методе onCreate не должно String gameId = intent.getStringExtra(EXTRA_EXTERNAL_ID);бытьString gameId = intent.getStringExtra(EXTRA_GAME_ID);
marcusshep

Наличие статики сделает Ваше тестирование очень трудным.
Джон Трайб

Это утечка памяти? Передача контекста в статический метод кажется мне плохой идеей. Почему бы просто не вернуть намерение, а затем начать действие, используя это намерение из первого класса?
AndroidDev

4

Код Котлина:

Начать SecondActivity:

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

Получить идентификатор в SecondActivity:

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

где gameIdэто String? (может быть пустым)


3

Существующие ответы (данные Intentпередаются в startActivity()) показывают нормальный способ решения этой проблемы. Есть еще одно решение, которое можно использовать в нечетном случае, когда вы создаете действие, которое будет запущено другим приложением (например, одним из действий редактирования в плагине Tasker ), и, следовательно, не управляете тем, Intentкоторое запускает Activity.

Вы можете создать базовый класс Activity, имеющий конструктор с параметром, а затем производный класс, имеющий конструктор по умолчанию, который вызывает конструктор базового класса со значением, как показано ниже:

class BaseActivity extends Activity
{
    public BaseActivity(String param)
    {
        // Do something with param
    }
}

class DerivedActivity extends BaseActivity
{
    public DerivedActivity()
    {
        super("parameter");
    }
}

Если вам нужно сгенерировать параметр для передачи конструктору базового класса, просто замените жестко запрограммированное значение на вызов функции, который возвращает правильное значение для передачи.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.