Как передать данные между действиями в приложении Android?

1349

У меня есть сценарий, когда после входа в систему через страницу входа, будет выход buttonна каждом activity.

При нажатии sign-outя передам session idзарегистрированного пользователя для выхода. Кто-нибудь может подсказать мне, как оставаться session idдоступным для всех activities?

Любая альтернатива этому делу

UMAR
источник
14
я использовал sharedpreference, это полезно также для хранения данных для входа на функцию
запоминания
Это работает для меня. stackoverflow.com/a/7325248/2125322 Спасибо
Darshan
stackoverflow.com/a/37774966/6456129 может быть полезным
Йесси
в таких случаях попробуйте создать класс commomUtils с методом sharedprefereces ... это сохранит код в чистоте и связанные с ним данные. И вы легко сможете очистить определенный набор данных с помощью всего лишь одного метода очистки этого конкретного файла prefferencesFile, без очистки каких-либо данных приложения по умолчанию ...
Муахмад Тайиб

Ответы:

1268

Самый простой способ сделать это - передать идентификатор сеанса в действие выхода из системы, которое Intentвы используете для запуска действия:

Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("EXTRA_SESSION_ID", sessionId);
startActivity(intent);

Получите доступ к этому намерению в следующем упражнении:

String sessionId = getIntent().getStringExtra("EXTRA_SESSION_ID");

В документах для намерений имеют больше информации (загляните в разделе под названием «Extras»).

Эрих Дуглас
источник
хорошо, если я передам идентификатор сеанса для активности выхода при успешном входе в систему, и будет ли он работать на любой странице активности для выхода или вручную, мне придется присвоить ему значение для каждого действия ??? используя вышеописанную процедуру
UMAR
5
Да, вам нужно будет сделать идентификатор сеанса доступным для каждого действия, в котором вы хотите разрешить пользователю выходить из системы. В качестве альтернативы вы можете сохранить его в объекте Application, но тогда вам придется управлять состоянием сеанса (проверить, является ли он действительным, перед использованием и т. Д.).
Эрих Дуглас
1
Помните, что в документации указано следующее: Добавьте расширенные данные к цели. Имя должно включать префикс пакета, например, приложение com.android.contacts будет использовать такие имена, как «com.android.contacts.ShowAll».
Сергей Федоров
1
И для чтения данных из другого использования ActivityLong session_ids=getIntent().getExtras().getLong("EXTRA_SESSION_IDS");
Фарид
1
Как мы можем передавать данные с помощью setDataи в чем разница между этими двумя подходами? Какой лучше?
Хосейн Агаджани
1402

В вашей текущей деятельности создайте новый Intent:

String value="Hello world";
Intent i = new Intent(CurrentActivity.this, NewActivity.class);    
i.putExtra("key",value);
startActivity(i);

Затем в новом действии извлеките эти значения:

Bundle extras = getIntent().getExtras();
if (extras != null) {
    String value = extras.getString("key");
    //The key argument here must match that used in the other activity
}

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

user914425
источник
58
Просто информация для тех, кто такой слепой, как я: если вы ставите целое число в своей текущей деятельности, вы должны получить его через новую extras.getInt("new_variable_name"). Если вы попытаетесь получить его через getString()Android, посмотрите, что int был задан и возвращает ноль!
Биш
4
Что делать, если действие уже запущено, нужно ли это делать startActivity(i);? Я имею в виду, могу ли я выполнить операцию A, вызывать операцию B , и это возвращает данные в операцию A ? я в замешательстве?
Франциско Корралес Моралес
Я предпочитаю строковую переменную. Вы всегда можете преобразовать строку в целое или позже с плавающей точкой.
user914425
140

Прохождение Intent - хороший подход, как отметил Эрих.

Однако объект Application - это еще один способ, и иногда он проще при работе с одним и тем же состоянием в нескольких действиях (в отличие от необходимости получать / помещать его везде) или объектами, более сложными, чем примитивы и строки.

Вы можете расширить Application, а затем установить / получить все, что хотите, и получить к нему доступ из любого Activity (в том же приложении) с помощью getApplication () .

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

Чарли Коллинз
источник
8
+1 за проблему статики. Вероятно, очистка может быть решена путем объединения одного объекта с помощью метода onCreate / onTerminate класса Application.
Сид
10
Эй, я знаю, что эта тема была довольно давно, но предоставленная ссылка теперь тупиковая. Где-нибудь я могу найти пример?
JuiCe
Как добиться этого с помощью приложения? @CharlieCollins
Banee Ishaque K
Вот обновленный пример этого здесь, из очень старой книги :) github.com/charlieCollins/android-in-practice/blob/master/ch07/…
Чарли Коллинз
@JuiCe Сообщение в блоге разработчиков Android о утечках памяти больше не является недействительным.
Эдрик
94

Исходный класс:

Intent myIntent = new Intent(this, NewActivity.class);
myIntent.putExtra("firstName", "Your First Name Here");
myIntent.putExtra("lastName", "Your Last Name Here");
startActivity(myIntent)

Класс назначения (класс NewActivity):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);

    Intent intent = getIntent();

    String fName = intent.getStringExtra("firstName");
    String lName = intent.getStringExtra("lastName");
}
Мадам Рахман
источник
3
Может ли намерение быть нулевым? Должны ли мы проверить, что это не нуль?
Микро
85

Вам просто нужно прислать дополнительные услуги, пока вы говорите о своем намерении.

Нравится:

Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
intent.putExtra("Variable name", "Value you want to pass");
startActivity(intent);

Теперь по OnCreateвашему методу SecondActivityвы можете получить такие дополнения.

Если отправленное вами значение было вlong :

long value = getIntent().getLongExtra("Variable name which you sent as an extra", defaultValue(you can give it anything));

Если отправленное вами значение былоString :

String value = getIntent().getStringExtra("Variable name which you sent as an extra");

Если отправленное вами значение былоBoolean :

Boolean value = getIntent().getBooleanExtra("Variable name which you sent as an extra", defaultValue);
Mayank Saini
источник
3
Помните, что в документации указано следующее: Добавьте расширенные данные к цели. Имя должно включать префикс пакета, например, приложение com.android.contacts будет использовать такие имена, как «com.android.contacts.ShowAll».
Сергей Федоров
Это копия самого популярного ответа, который был там за 2 года до этого ответа, и ответа Сахила Махаджана Мджа, который был на 1 год старше. Единственная разница: примеры для booleanи longполучателей, которые заслуживают комментария ИМО, а не ответа.
Мурмель
48

Это помогает мне видеть вещи в контексте. Вот два примера.

Передача данных вперед

введите описание изображения здесь

Основная деятельность

  • Поместите данные, которые вы хотите отправить, в Intent с парой ключ-значение. Посмотрите этот ответ для соглашений об именовании для ключа.
  • Начните второе действие с startActivity.

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // get the text to pass
        EditText editText = (EditText) findViewById(R.id.editText);
        String textToPass = editText.getText().toString();

        // start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra(Intent.EXTRA_TEXT, textToPass);
        startActivity(intent);
    }
}

Вторая деятельность

  • Вы используете, getIntent()чтобы получить, Intentчто началось второе действие. Затем вы можете извлечь данные getExtras()и ключ, который вы определили в первом упражнении. Поскольку наши данные являются строкой, мы будем просто использовать getStringExtraздесь.

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

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

        // get the text from MainActivity
        Intent intent = getIntent();
        String text = intent.getStringExtra(Intent.EXTRA_TEXT);

        // use the text in a TextView
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(text);
    }
}

Передача данных назад

введите описание изображения здесь

Основная деятельность

  • Начните второе действие с startActivityForResult, предоставив ему произвольный код результата.
  • Override onActivityResult. Это называется, когда заканчивается второе задание. Вы можете убедиться, что это фактически Второе действие, проверив код результата. (Это полезно, когда вы запускаете несколько разных действий из одного и того же основного действия.)
  • Извлеките данные, которые вы получили от возврата Intent. Данные извлекаются с использованием пары ключ-значение. Я мог бы использовать любую строку для ключа, но я буду использовать предопределенный, Intent.EXTRA_TEXTтак как я отправляю текст.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // get String data from Intent
                String returnString = data.getStringExtra(Intent.EXTRA_TEXT);

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

Вторая деятельность

  • Поместите данные, которые вы хотите отправить обратно в предыдущее действие, в Intent. Данные хранятся в Intentпаре ключ-значение. Я решил использовать Intent.EXTRA_TEXTдля моего ключа.
  • Установите результат RESULT_OKи добавьте намерение, содержащее ваши данные.
  • Позвоните, finish()чтобы закрыть Второе занятие.

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

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

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_TEXT, stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}
Suragch
источник
3
Вау, спасибо! Это было именно то, что я искал. При использовании камеры или других внешних устройств вполне понятно, что я ожидаю результатов, но я не думал использовать их внутри. Вы первый, кто выразил это так открыто.
user3195231
45

Обновлено примечание, что я упомянул использование SharedPreference . Он имеет простой API и доступен во всех приложениях. Но это неуклюжее решение и представляет угрозу безопасности, если вы передаете конфиденциальные данные. Лучше всего использовать намерения. Он содержит обширный список перегруженных методов, которые можно использовать для лучшей передачи разных типов данных между действиями. Посмотрите на intent.putExtra . Эта ссылка довольно хорошо описывает использование putExtra.

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

public class MyActivity extends Activity {
    public static final String ARG_PARAM1 = "arg_param1";
...
public static getIntent(Activity from, String param1, Long param2...) {
    Intent intent = new Intent(from, MyActivity.class);
        intent.putExtra(ARG_PARAM1, param1);
        intent.putExtra(ARG_PARAM2, param2);
        return intent;
}

....
// Use it like this.
startActivity(MyActvitiy.getIntent(FromActivity.this, varA, varB, ...));
...

Затем вы можете создать намерение для планируемой деятельности и убедиться, что у вас есть все параметры. Вы можете адаптировать для фрагментов. Простой пример выше, но вы поняли идею.

angryITguy
источник
2
Мне больше нравится ваш ответ ... Передача его через намерение означает, что почти везде, где я начинаю занятие, вы должны помнить, что нужно включить sessionId. Поместив его в SharedPreferences, вы можете получить его в любое время из любой деятельности. : 0)
bytebender
@bytebender Я знаю, что ответ немного опоздал, я ценю, что вам нравится мой оригинальный ответ за его простоту, но я бы постарался сохранить идентификатор сессии в общих настройках. Если вы должны хранить его на жестком диске, используйте шифрование. Если вы можете использовать инфраструктуры аутентификации, использующие JWT, она будет включать refreshTokens, более безопасные для долговременного хранения, а затем сохранить текущий токен сеанса как открытое свойство пользовательского объекта Application для простого доступа к токенам аутентификации и снизить накладные расходы на активность. намеренные подписи.
angryITguy
38

Попробуйте сделать следующее:

Создайте простой «вспомогательный» класс (фабрика для ваших намерений), например так:

import android.content.Intent;

public class IntentHelper {
    public static final Intent createYourSpecialIntent(Intent src) {
          return new Intent("YourSpecialIntent").addCategory("YourSpecialCategory").putExtras(src);
    }
}

Это будет фабрика для всех ваших намерений. Каждый раз, когда вам нужен новый Intent, создайте статический метод фабрики в IntentHelper. Чтобы создать новое намерение, вы должны просто сказать это так:

IntentHelper.createYourSpecialIntent(getIntent());

В вашей деятельности. Если вы хотите «сохранить» некоторые данные в «сеансе», просто используйте следующее:

IntentHelper.createYourSpecialIntent(getIntent()).putExtra("YOUR_FIELD_NAME", fieldValueToSave);

И отправьте это намерение. В целевой деятельности ваше поле будет доступно как:

getIntent().getStringExtra("YOUR_FIELD_NAME");

Так что теперь мы можем использовать Intent как тот же старый сеанс (как в сервлетах или JSP ).

Понькин
источник
28

Вы также можете передать объекты пользовательского класса, создав класс, который можно передать . Лучший способ сделать его пригодным для продажи - написать свой класс, а затем просто вставить его на сайт, например http://www.parcelabler.com/ . Нажмите на сборку, и вы получите новый код. Скопируйте все это и замените оригинальное содержание класса. Затем-

Intent intent = new Intent(getBaseContext(), NextActivity.class);
Foo foo = new Foo();
intent.putExtra("foo", foo);
startActivity(intent);

и получить результат в NextActivity

Foo foo = getIntent().getExtras().getParcelable("foo");

Теперь вы можете просто использовать объект foo, как если бы вы использовали.

Вайбхав Шарма
источник
23

Другой способ - использовать открытое статическое поле, в котором вы храните данные, а именно:

public class MyActivity extends Activity {

  public static String SharedString;
  public static SomeObject SharedObject;

//...
ComputerSaysNo
источник
5
Мне действительно интересно, почему ваше предложение не получило голосов, оно проще и практичнее.
Поризм
7
хм ... разве это не нарушает принципы ОО?
Кристиан Вильма
2
@ChristianVielma ну, это больше похоже на серую область ... вы можете сделать это многими способами, для меня это кажется чистым "уходом", так что ... вам (разработчику) решать, принимать ли это работает хорошо для вас или нет, мне нравится этот способ, потому что за ним легче следовать, но он может очень сильно испачкаться ...
ComputerSaysNo
2
почему вы говорите, что это пачкается? Разве iOS не делает это для передачи данных между viewcontrollers путем установки «свойств», которые похожи на это? Это намного проще, чем использовать намерения
Терри Бу
2
Да, вы передаете данные между контроллерами представления, но не со статическими свойствами. Проблема в том, что это не свойство нужного экземпляра действия. То, как Android запускает действия с помощью startActivity (), не мгновенно создает экземпляр объекта и позволяет разработчику установить переменную экземпляра. Это довольно раздражает ...
Шон,
20

Наиболее удобный способ передачи данных между действиями - передача намерений. В первом упражнении, из которого вы хотите отправить данные, вы должны добавить код,

String str = "My Data"; //Data you want to send
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("name",str); //Here you will add the data into intent to pass bw activites
v.getContext().startActivity(intent);

Вы также должны импортировать

import android.content.Intent;

Затем в следующем Acitvity (SecondActivity) вы должны извлечь данные из намерения, используя следующий код.

String name = this.getIntent().getStringExtra("name");
Сахил Махаджан МДж
источник
2
Это дубликат самого популярного ответа, который был там еще 1 год.
Мурмель
19

Вы можете использовать SharedPreferences...

  1. Логирование. ID сеанса хранения времени вSharedPreferences

    SharedPreferences preferences = getSharedPreferences("session",getApplicationContext().MODE_PRIVATE);
    Editor editor = preferences.edit();
    editor.putString("sessionId", sessionId);
    editor.commit();
  2. Выход. Время получения идентификатора сеанса в общих настройках

    SharedPreferences preferences = getSharedPreferences("session", getApplicationContext().MODE_PRIVATE);
    String sessionId = preferences.getString("sessionId", null);

Если у вас нет требуемого идентификатора сеанса, удалите sharedpreferences:

SharedPreferences settings = context.getSharedPreferences("session", Context.MODE_PRIVATE);
settings.edit().clear().commit();

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

Рави Парсания
источник
17

Стандартный подход.

Intent i = new Intent(this, ActivityTwo.class);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
String getrec=textView.getText().toString();
Bundle bundle = new Bundle();
bundle.putString(“stuff”, getrec);
i.putExtras(bundle);
startActivity(i);

Теперь во втором упражнении извлеките данные из пакета:

Получить пакет

Bundle bundle = getIntent().getExtras();

Извлечь данные ...

String stuff = bundle.getString(“stuff”); 
Аджай Венугопал
источник
1
Дубликат, как уже было предложено ПРАБИШ РК в 2012 году. И может быть сокращен до i.putExtras()/, getIntent().getString()который предлагается 6 других ответов ...
Мурмель
17

Из деятельности

 int n= 10;
 Intent in = new Intent(From_Activity.this,To_Activity.class);
 Bundle b1 = new Bundle();
 b1.putInt("integerNumber",n);
 in.putExtras(b1);
 startActivity(in);

К деятельности

 Bundle b2 = getIntent().getExtras();
 int m = 0;
 if(b2 != null)
  {
     m = b2.getInt("integerNumber");
  }
Гавин Джойс
источник
1
Дубликат: Bundleоснованный подход уже был предложен PRABEESH РК в 2012 году и Аджаем Венугопалом , Кришна . И может быть сведен к i.putExtras()/, getIntent().getString()который предлагается 8 других ответов ...
Murmel
11

Вы можете отправлять данные между действиями, используя объект намерения. Рассмотрим у вас есть два вида деятельности , а именно FirstActivityи SecondActivity.

Внутри FirstActivity:

Используя Намерение:

i = new Intent(FirstActivity.this,SecondActivity.class);
i.putExtra("key", value);
startActivity(i)

Inside SecondActivity

Bundle bundle= getIntent().getExtras();

Теперь вы можете использовать разные методы класса комплекта для получения значений, переданных из FirstActivity по ключу.

Например bundle.getString("key"), bundle.getDouble("key")и bundle.getInt("key")т. Д.

Кришна
источник
1
Дубликат: BundleОснованный подход уже был предложен PRABEESH РК в 2012 году и Ajay Venugopal . И может быть сведен к i.putExtras()/, getIntent().getString()который предлагается 7 других ответов ...
Murmel
11

Если вы хотите перенести растровое изображение между Активами / Фрагментами


Деятельность

Чтобы передать растровое изображение между Activites

Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);

И в классе деятельности

Bitmap bitmap = getIntent().getParcelableExtra("bitmap");

Фрагмент

Чтобы передать растровое изображение между фрагментами

SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);

Получить внутри SecondFragment

Bitmap bitmap = getArguments().getParcelable("bitmap");

Передача больших растровых изображений

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

Таким образом, в этом случае вы должны сжать растровое изображение как массив байтов, а затем распаковать его в другой деятельности , как это

В первую очередь

Intent intent = new Intent(this, SecondActivity.class);

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray(); 
intent.putExtra("bitmapbytes",bytes);

А во Второй деятельности

byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
capt.swag
источник
9
Intent intent = new Intent(YourCurrentActivity.this, YourActivityName.class);
intent.putExtra("NAme","John");
intent.putExtra("Id",1);
startActivity(intent);

Вы можете получить его в другой деятельности. Два пути:

int id = getIntent.getIntExtra("id", /* defaltvalue */ 2);

Второй способ:

Intent i = getIntent();
String name = i.getStringExtra("name");
Дилавар Малек
источник
8

Вот моя лучшая практика, и она очень помогает, когда проект огромен и сложен.

Предположим, что у меня есть 2 вида деятельности, LoginActivityи HomeActivity. Я хочу передать 2 параметра (имя пользователя и пароль) из LoginActivityв HomeActivity.

Во-первых, я создаю свой HomeIntent

public class HomeIntent extends Intent {

    private static final String ACTION_LOGIN = "action_login";
    private static final String ACTION_LOGOUT = "action_logout";

    private static final String ARG_USERNAME = "arg_username";
    private static final String ARG_PASSWORD = "arg_password";


    public HomeIntent(Context ctx, boolean isLogIn) {
        this(ctx);
        //set action type
        setAction(isLogIn ? ACTION_LOGIN : ACTION_LOGOUT);
    }

    public HomeIntent(Context ctx) {
        super(ctx, HomeActivity.class);
    }

    //This will be needed for receiving data
    public HomeIntent(Intent intent) {
        super(intent);
    }

    public void setData(String userName, String password) {
        putExtra(ARG_USERNAME, userName);
        putExtra(ARG_PASSWORD, password);
    }

    public String getUsername() {
        return getStringExtra(ARG_USERNAME);
    }

    public String getPassword() {
        return getStringExtra(ARG_PASSWORD);
    }

    //To separate the params is for which action, we should create action
    public boolean isActionLogIn() {
        return getAction().equals(ACTION_LOGIN);
    }

    public boolean isActionLogOut() {
        return getAction().equals(ACTION_LOGOUT);
    }
}

Вот как я передаю данные в моей LoginActivity

public class LoginActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        String username = "phearum";
        String password = "pwd1133";
        final boolean isActionLogin = true;
        //Passing data to HomeActivity
        final HomeIntent homeIntent = new HomeIntent(this, isActionLogin);
        homeIntent.setData(username, password);
        startActivity(homeIntent);

    }
}

Последний шаг, вот как я получаю данные в HomeActivity

public class HomeActivity extends AppCompatActivity {

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

        //This is how we receive the data from LoginActivity
        //Make sure you pass getIntent() to the HomeIntent constructor
        final HomeIntent homeIntent = new HomeIntent(getIntent());
        Log.d("HomeActivity", "Is action login?  " + homeIntent.isActionLogIn());
        Log.d("HomeActivity", "username: " + homeIntent.getUsername());
        Log.d("HomeActivity", "password: " + homeIntent.getPassword());
    }
}

Выполнено! Круто :) Я просто хочу поделиться своим опытом. Если вы работаете над небольшим проектом, это не должно быть большой проблемой. Но когда вы работаете над большим проектом, вам действительно больно, когда вы хотите провести рефакторинг или исправление ошибок.

THANN Phearum
источник
7

Дополнительный ответ: Соглашения об именах для ключевой строки

На фактический процесс передачи данных уже дан ответ, однако в большинстве ответов используются жестко закодированные строки для имени ключа в Intent. Это обычно хорошо, когда используется только в вашем приложении. Однако в документации рекомендуется использовать EXTRA_*константы для стандартизированных типов данных.

Пример 1. Использование Intent.EXTRA_*ключей

Первое занятие

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, "my text");
startActivity(intent);

Второе занятие:

Intent intent = getIntent();
String myText = intent.getExtras().getString(Intent.EXTRA_TEXT);

Пример 2. Определение собственного static finalключа

Если одна из Intent.EXTRA_*Строк не соответствует вашим потребностям, вы можете определить свою собственную в начале первого упражнения.

static final String EXTRA_STUFF = "com.myPackageName.EXTRA_STUFF";

Включение имени пакета - это просто соглашение, если вы используете ключ только в своем приложении. Но необходимо избегать конфликтов имен, если вы создаете какой-то сервис, который другие приложения могут вызывать с намерением.

Первое занятие:

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(EXTRA_STUFF, "my text");
startActivity(intent);

Второе занятие:

Intent intent = getIntent();
String myText = intent.getExtras().getString(FirstActivity.EXTRA_STUFF);

Пример 3: Использование ключа ресурса String

Хотя это и не упомянуто в документации, этот ответ рекомендует использовать ресурс String, чтобы избежать зависимости между действиями.

strings.xml

 <string name="EXTRA_STUFF">com.myPackageName.MY_NAME</string>

Первое занятие

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(getString(R.string.EXTRA_STUFF), "my text");
startActivity(intent);

Второе занятие

Intent intent = getIntent();
String myText = intent.getExtras().getString(getString(R.string.EXTRA_STUFF));
Suragch
источник
7

Ты можешь использовать Intent

Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
mIntent.putExtra("data", data);
startActivity(mIntent);

Другой способ может также использовать шаблон синглтона :

public class DataHolder {

 private static DataHolder dataHolder;
 private List<Model> dataList;

 public void setDataList(List<Model>dataList) {
    this.dataList = dataList;
 }

 public List<Model> getDataList() {
    return dataList;
 }

 public synchronized static DataHolder getInstance() {
    if (dataHolder == null) {
       dataHolder = new DataHolder();
    }
    return dataHolder;
 }
}

От вашей первой активности

private List<Model> dataList = new ArrayList<>();
DataHolder.getInstance().setDataList(dataList);

На SecondActivity

private List<Model> dataList = DataHolder.getInstance().getDataList();
Сэчин
источник
Дубликат: Намерение подход уже предложен верхней наиболее голосовавшие ответ и ответ Сахил Mahajan MJ в и ответ Mayank SAINI в и ответ Md Рахмана. , Ответ Dilavar M в , ответ для Android разработчика , sahulab . Синглтон: Родион Альтшулер ответ
Мурмель
6

Передача данных между действиями происходит главным образом посредством намеренного объекта.

Сначала вы должны прикрепить данные к объекту намерения с использованием Bundleкласса. Затем вызовите деятельность , используя либо startActivity()илиstartActivityForResult() методов.

Вы можете найти больше информации об этом, например, из сообщения в блоге. Передача данных в действие .

ПРАБИШ РК
источник
Это более или менее аналогично непосредственному использованию предоставленных Intent методов ( Intent#putExtra()). Но добавляет другое Bundleи усложняет ситуацию.
Мурмель
6

Вы можете попробовать Shared Preference, это может быть хорошей альтернативой для обмена данными между действиями

Сохранить идентификатор сессии -

SharedPreferences pref = myContexy.getSharedPreferences("Session 
Data",MODE_PRIVATE);
SharedPreferences.Editor edit = pref.edit();
edit.putInt("Session ID", session_id);
edit.commit();

Чтобы получить их -

SharedPreferences pref = myContexy.getSharedPreferences("Session Data", MODE_PRIVATE);
session_id = pref.getInt("Session ID", 0);
Рохит Гурджар
источник
Дубликат: этот подход уже был предложен Рави Парсания в 2014 году
Мурмель
5

Запустите другое действие с помощью параметров передачи этого действия через Bundle Object

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

Получить другой вид деятельности (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

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

Здесь у нас есть модель сотрудника

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Вы можете использовать Gson lib, предоставленный Google, для сериализации сложных данных, подобных этой

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);
DroidNinja
источник
5

Котлин

Проход от первого занятия

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

Получить во второй деятельности

val value = getIntent().getStringExtra("key")

Предложение

Всегда помещайте ключи в постоянный файл для более управляемого пути.

companion object {
    val KEY = "key"
}
Khemraj
источник
4
/*
 * If you are from transferring data from one class that doesn't
 * extend Activity, then you need to do something like this.
 */ 

public class abc {
    Context context;

    public abc(Context context) {
        this.context = context;
    }

    public void something() {
        context.startactivity(new Intent(context, anyone.class).putextra("key", value));
    }
}
Дип Похрел
источник
4

Чарли Коллинз дал мне идеальный ответ, используя Application.class. Я не знал, что мы могли бы подкласс это так легко. Вот упрощенный пример использования пользовательского класса приложения.

AndroidManifest.xml

Присвойте android:nameатрибуту собственный класс приложения.

...
<application android:name="MyApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
....

MyApplication.java

Используйте это как глобальный держатель ссылки. Он отлично работает в том же процессе.

public class MyApplication extends Application {
    private MainActivity mainActivity;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public void setMainActivity(MainActivity activity) { this.mainActivity=activity; }
    public MainActivity getMainActivity() { return mainActivity; }
}

MainActivity.java

Установите глобальную ссылку «singleton» на экземпляр приложения.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((MyApplication)getApplication()).setMainActivity(this);
    }
    ...

}

MyPreferences.java

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

public class MyPreferences extends PreferenceActivity
            implements SharedPreferences.OnSharedPreferenceChangeListener {
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (!key.equals("autostart")) {
            ((MyApplication)getApplication()).getMainActivity().refreshUI();
        }
    }
}
Whome
источник
4

Недавно я выпустил Vapor API , фреймворк Android со вкусом jQuery, который упрощает все виды задач, подобных этой. Как уже упоминалось, SharedPreferencesэто один из способов, которым вы могли бы сделать это.

VaporSharedPreferencesреализован как Singleton, так что это один из вариантов, и в Vapor API он имеет сильно перегруженный .put(...)метод, поэтому вам не нужно явно беспокоиться о типе данных, который вы фиксируете - при условии, что он поддерживается. Это также свободно, так что вы можете звонить по цепочке:

$.prefs(...).put("val1", 123).put("val2", "Hello World!").put("something", 3.34);

Он также может автоматически сохранять изменения и унифицировать процесс чтения и записи, поэтому вам не нужно явно извлекать редактор, как в стандартном Android.

В качестве альтернативы вы можете использовать Intent. В Vapor API вы также можете использовать цепной перегруженный .put(...)метод для VaporIntent:

$.Intent().put("data", "myData").put("more", 568)...

И передайте это как дополнительное, как упомянуто в других ответах. Вы можете получить дополнительные данные от вашего Activity, и, более того, если вы используете VaporActivityэто, это делается для вас автоматически, поэтому вы можете использовать:

this.extras()

Чтобы получить их на другом конце в Activityвы переключитесь на.

Надеюсь, что это представляет интерес для некоторых :)

Darius
источник
@BaneeIshaqueK да извините, я не поддерживал это в течение некоторого времени. Обновите ссылку, чтобы указать прямо на Github для проекта на случай, если это поможет. пс. Не уверен, что я думал об этой лицензии ... извинения
Дариус
4

Первое занятие:

Intent intent = new Intent(getApplicationContext(), ClassName.class);
intent.putExtra("Variable name", "Value you want to pass");
startActivity(intent);

Второе занятие:

String str= getIntent().getStringExtra("Variable name which you sent as an extra");
Суреш Мадапарти
источник
4

Вы можете передавать данные между действиями в приложении тремя способами

  1. умысел
  2. SharedPreferences
  3. заявка

Передача данных в намерениях имеет некоторые ограничения. Для большого объема данных вы можете использовать общий доступ к данным на уровне приложения, и, сохраняя его в SharedPreference, размер вашего приложения увеличивается

Лаванья Велусамы
источник
3

Используйте глобальный класс:

public class GlobalClass extends Application
{
    private float vitamin_a;


    public float getVitaminA() {
        return vitamin_a;
    }

    public void setVitaminA(float vitamin_a) {
        this.vitamin_a = vitamin_a;
    }
}

Вы можете вызывать установщики и получатели этого класса из всех других классов. Для этого вам нужно создать объект GlobalClass в каждом акте:

GlobalClass gc = (GlobalClass) getApplication();

Тогда вы можете позвонить, например:

gc.getVitaminA()
Патриция Хеймфарт
источник
Главное приложение - это дубликат ответа
Whome