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

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

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

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

Solutions Collecting From Web of "Как передавать данные между действиями в приложении Android?"

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

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

Доступ к этому намерению при следующей деятельности

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

Документы для намерений содержат дополнительную информацию (смотрите раздел «Дополнительно»).

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

 Intent i = new Intent(getApplicationContext(), 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 } 

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

Передача Intent extras – хороший подход, как отметил Эрих.

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

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

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

Класс источника:

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

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

Как это:

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

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

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

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

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

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

 IntentHelper.createYourSpecialIntent(getIntent()); 

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

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

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

 getIntent().getStringExtra("YOUR_FIELD_NAME"); 

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

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

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

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

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

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

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

 public class MyActivity extends Activity { public static String SharedString; public static SomeObject SharedObject; //... 

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

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

Самый удобный способ передачи данных между действиями – это передача намерений. В первом действии, откуда вы хотите отправить данные, вы должны добавить код,

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

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

  1. Логирование. Идентификатор сеанса хранилища времени в SharedPreferences

     SharedPreferences preferences = getSharedPreferences("session",getApplicationContext().MODE_PRIVATE); Editor editor = preferences.edit(); editor.putString("sessionId", sessionId); editor.commit(); 
  2. Выход. Идентификатор сеанса времени в sharedpreferences

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

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

Из активности

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

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

Внутри FirstActivity:

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

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

Внутри SecondActivity

 Bundle bundle= getIntent().getExtras(); 

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

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

Если вы хотите транслировать растровое изображение между Activites / Fragments


Мероприятия

Передача растрового изображения между Activites

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

И в классе Activity

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

Фрагмент

Передача растрового изображения между фрагментами

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

Чтобы получить внутри второго фрагмента

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

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

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

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

В FirstActivity

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

И в SecondActivity

 byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes"); Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
 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"); 

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

Чтобы сохранить идентификатор сеанса –

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

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

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

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

Попробуй это:

CurrentActivity.java

 Intent intent = new Intent(currentActivity.this, TargetActivity.class); intent.putExtra("booktype", "favourate"); startActivity(intent); 

TargetActivity.java

 Bundle b = getIntent().getExtras(); String typesofbook = b.getString("booktype"); 

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

Предположим, что у меня есть 2 действия, SplashActivity и HomeActivity . Я хочу передать 2 параметра (имя пользователя и пароль) из SplashActivity в 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); } } 

Вот как я передаю данные в своем SplashActivity

 public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); 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 SplashActivity //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()); } } 

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

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

Я использую статические поля в классе и получаю / устанавливаю их:

Подобно:

 public class Info { public static int ID = 0; public static String NAME = "TEST"; } 

Для получения значения используйте это в Управлении:

 Info.ID Info.NAME 

Для установки значения:

 Info.ID = 5; Info.NAME = "USER!"; 

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

Фактический процесс передачи данных уже был дан ответ, однако большинство ответов использует жестко закодированные строки для имени ключа в 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 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)); 

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

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

Другой способ использования шаблона singleton:

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

}

С вашей FirstActivity

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

По второстепенности

 private List<Model> dataList = DataHolder.getInstance().getDataList(); 

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

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

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

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

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

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

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

 this.extras() 

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

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

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

 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 в каждом Actitity:

 GlobalClass gc = (GlobalClass) getApplication(); 

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

 gc.getVitaminA() 

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

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

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

  • Сделайте только одно поле или как можно меньше и повторите их использование, сделайте их объектом типа и передайте его желаемому типу в принимающей активности.
  • Всякий раз, когда какой-либо из них больше не будет полезен, установите его явно null, которое будет собираться сборщиком мусора, перед следующим назначением.

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

Для большинства случаев достаточно Intent.putExtras.

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

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

 //Serializable class public class YourClass implements Serializable { public long session_id = 0; }