Відправлення даних назад до Основної діяльності в Android


295

У мене два види діяльності: основна діяльність та дитяча діяльність.
Коли я натискаю кнопку в основній діяльності, активність дитини починається.

Тепер я хочу повернути деякі дані назад на головний екран. Я використовував клас Bundle, але він не працює. Це кидає деякі винятки з виконання.

Чи є для цього рішення?



Ще один трюк визначте ArrayList у вашій основній діяльності та зробіть його статичним, щоб ви могли отримати доступ до нього під час другої діяльності, а потім додайте в нього дані, які ви хочете надіслати до основної діяльності, тоді ви отримаєте доступ до нього в основній діяльності
Abhishek Yadav

Абхішек Ядав, що робити, якщо ваша основна діяльність збирається знищити (onDestroy () зворотний виклик). Я думаю, що це не дуже гарна порада.
Леонцев Антон

Відповіді:


472

Є кілька способів досягти того, що ви хочете, залежно від обставин.

Найпоширеніший сценарій (як це звучить у вашому варіанті) - це те, коли дочірня діяльність використовується для отримання вводу користувача - наприклад, вибір контакту зі списку або введення даних у діалоговому вікні. У цьому випадку вам слід скористатисяstartActivityForResult для запуску Діяльність дитини.

Це забезпечує конвеєр для відправки даних назад до основної діяльності за допомогою setResult . Метод setResult приймає значення результату int та Намір, які передаються назад до виклику Activity.

Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("some_key", "String data"); 
setResult(Activity.RESULT_OK, resultIntent);
finish();

Щоб отримати доступ до повернених даних у вимкненій активності виклику onActivityResult. Код запиту відповідає цілому числу, переданому у startActivityForResultвиклику, в той час як результатКод результатів і Намір даних повертаються з дочірньої діяльності.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  switch(requestCode) {
    case (MY_CHILD_ACTIVITY) : {
      if (resultCode == Activity.RESULT_OK) {
        // TODO Extract the data returned from the child Activity.
        String returnValue = data.getStringExtra("some_key");
      }
      break;
    } 
  }
}

4
для повноти варто згадати, яке найкраще місце для виклику для завершення ()? Це може бути зрозуміло експертам, але для початківців було б добре знати, не посилаючись на додаткові джерела.
Каліфорнія

1
@jelmoodjasser Це знадобилось мені трохи, щоб розібратися, але в основному, коли ви починаєте нову діяльність з Intent, вам потрібно використовувати startActivityForResultфункцію, а не просто startActivity. Прикладом може бути startActivityForResult(myIntent, 2);2, де результат - код результату, який може зайняти місце MY_CHILD_ACTIVITYв операторі перемикача вище.
Прожектор

коли друга активність закінчена і повертається до першої діяльності, то як встановити requestCode у другу активність, перш ніж закінчити її .... для використання її для onActivityResult у FirstActivity
Ahamadullah Saikat

Чи є умисел обов'язковим? Якщо я не маю нічого надсилати назад, чи потрібен мені порожній намір відправити назад?
Багус Аджі Сантосо

Намір @BagusAjiSantoso необов’язковий, потрібен лише у випадку, якщо вам є що надіслати назад.
Нарендра Сінгх

186

Діяльність 1 використовує startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

Діяльність 2 запускається, і ви можете виконати операцію, щоб закрити Діяльність, зробіть це:

Intent output = new Intent();
output.putExtra(ActivityOne.Number1Code, num1);
output.putExtra(ActivityOne.Number2Code, num2);
setResult(RESULT_OK, output);
finish();

Діяльність 1 - повернення з попередньої діяльності викликає onActivityResult :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ActivityTwoRequestCode && resultCode == RESULT_OK && data != null) {
        num1 = data.getIntExtra(Number1Code);
        num2 = data.getIntExtra(Number2Code);
    }
}

ОНОВЛЕННЯ: Відповідь на коментар Seenu69, У другому заході,

int result = Integer.parse(EditText1.getText().toString()) 
           + Integer.parse(EditText2.getText().toString());
output.putExtra(ActivityOne.KEY_RESULT, result);

Тоді в одній діяльності,

int result = data.getExtra(KEY_RESULT);

Привіт, я вдячний, що ти відповів на моє запитання. Цей код мені недостатньо. Я хочу, щоб доповнення виконувались у самій другій діяльності, і результат слід повернути до MainActivity методом onActivityResult. Наприклад, у головній діяльності є лише кнопка, яка при натисканні на неї вводить другий вигляд, там два числа вводяться через віджет editText, логіка додавання виконується в самій другій діяльності, і нарешті результат повертається в MainActivity. Зрозумів?
Seenu69

2
У такому випадку у другому виді ви виконуєте обчислення та зберігаєте результат у намірі за допомогою putExtra (). Я редагував свою відповідь вище
jimmithy

68

Відправка назад

Це допомагає мені бачити речі в контексті. Ось повний простий проект для повернення даних назад. Замість того, щоб надати файли макета xml, ось зображення.

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

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

  • Почніть Другу діяльність startActivityForResult, надавши їй довільний код результату.
  • Override onActivityResult. Це називається, коли закінчується Друга діяльність. Ви можете переконатися, що це насправді Друга активність, перевіривши код запиту. (Це корисно, коли ви починаєте кілька різних видів діяльності з однієї і тієї ж основної діяльності.)
  • Витягніть отримані дані з повернення Intent. Дані витягуються за допомогою пари ключ-значення.

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

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

Друга діяльність

  • Помістіть дані, які ви хочете повернути до попередньої діяльності, у Intent. Дані зберігаються у Intentвикористанні пари ключ-значення.
  • Встановіть результат на 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("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

Інші примітки

  • Якщо ви знаходитесь у фрагменті, він не знатиме значення RESULT_OK. Просто використовуйте повне ім'я: Activity.RESULT_OK.

Дивись також


Це дуже добре написане явне пояснення. Молодці!
Kingsley Ijike

29

FirstActivity використовує startActivityForResult:

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent, int resultCode); // suppose resultCode == 2

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2)
    {
        String message=data.getStringExtra("MESSAGE");
    }
}

На події виклику SecondActivity setResult () onClick або onBackPress ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);

Чи це результатCode requestCode?
Engr Syed Rowshan Ali

15

Виклик наміру активності дитини за допомогою виклику методу startActivityForResult ()

Приклад цього є тут: http://developer.android.com/training/notepad/notepad-ex2.html

і в "Повернення результату з екрана" цього: http://developer.android.com/guide/faq/commontasks.html#opennewscreen


Так, я погоджуюся з cbrulak, посилання на документи було набагато кориснішим, ніж відповідь.
george_h

Зараз посилання показують деякі загальні речі. Вміст може бути змінений. Будь ласка, оновіть його або видаліть відповідь для спільноти
Manoranjan,

7

Я створив простий демо-клас для вашої кращої роботи.

FirstActivity.java

 public class FirstActivity extends AppCompatActivity {

    private static final String TAG = FirstActivity.class.getSimpleName();
    private static final int REQUEST_CODE = 101;
    private Button btnMoveToNextScreen;

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

        btnMoveToNextScreen = (Button) findViewById(R.id.btnMoveToNext);
        btnMoveToNextScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivityForResult(mIntent, REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            if(requestCode == REQUEST_CODE && data !=null) {
                String strMessage = data.getStringExtra("keyName");
                Log.i(TAG, "onActivityResult: message >>" + strMessage);
            }
        }

    }
}

І ось SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = SecondActivity.class.getSimpleName();
    private Button btnMoveToPrevious;
    private EditText editText;

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

        editText = (EditText) findViewById(R.id.editText);

        btnMoveToPrevious = (Button) findViewById(R.id.btnMoveToPrevious);
        btnMoveToPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = editText.getEditableText().toString();

                Intent mIntent = new Intent();
                mIntent.putExtra("keyName", message);
                setResult(RESULT_OK, mIntent);
                finish();

            }
        });

    }
}

3
добре пояснено!
Radhey

5

У першій діяльності ви можете надіслати намір за допомогою, startActivityForResult()а потім отримати результат від другої діяльності після її закінчення setResult.

MainActivity.class

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_RESULT_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);
        // send intent for result 
        startActivityForResult(intent, SECOND_ACTIVITY_RESULT_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_RESULT_CODE) {
            if (resultCode == RESULT_OK) {

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

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

SecondActivity.class

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("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

1

Всі ці відповіді пояснюють сценарій вашої другої діяльності, яку слід закінчити після надсилання даних.

Але якщо ви не хочете закінчити другу діяльність і хочете повернути дані спочатку, тоді для цього ви можете використовувати BroadCastReceiver.

У другій діяльності -

Intent intent = new Intent("data");
intent.putExtra("some_data", true);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

У першій діяльності-

private BroadcastReceiver tempReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do some action
    }
};

Зареєструйте приймач у onCreate () -

 LocalBroadcastManager.getInstance(this).registerReceiver(tempReceiver,new IntentFilter("data"));

Скасувати реєстрацію в onDestroy ()


0

Ще одним способом досягнення бажаного результату, який може бути кращим залежно від вашої ситуації, є створення інтерфейсу для слухачів.

Змушуючи батьківську активність прослуховувати інтерфейс, який спрацьовує дочірньою діяльністю при передачі необхідних даних у якості параметра, можна створити аналогічний набір обставин


-1

Є кілька способів зробити це. 1. за допомогою startActivityForResult (), що дуже добре пояснено у наведених вище відповідях.

  1. створивши статичні змінні у вашому класі "Utils" або будь-якому іншому власному класі. Наприклад, я хочу передати StudentId з ActivityB в ActivityA. Спочатку моя ActivityA викликає ActivityB. Потім всередині ActivityB встановіть studentId (що є статичним полем у Utils.class). Як цей Utils.STUDENT_ID = "1234"; тоді під час повернення до ActivityA використовуйте StudentId, який зберігається в Utils.STUDENT_ID.

  2. створивши метод геттера та сетера у вашому Класі додатків.

подобається це:

public class MyApplication extends Application {

    private static MyApplication instance = null;
    private String studentId="";

    public static MyApplication getInstance() {
        return instance;
    }

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

    public void setStudentId(String studentID){
        this.studentId=studentID;
    }

    public String getStudentId(){
        return this.studentId;
    }
}

значить, ви зробили. просто встановіть дані всередині, коли ви перебуваєте в ActivityB, і після повернення в ActivityA отримайте дані.


-1

Лише невелика деталь, яка, на мою думку, відсутня у наведених вище відповідях.

Якщо ваша дитяча діяльність може бути відкрита з кількох батьківських дій, ви можете перевірити, чи потрібно це робити setResultчи ні, виходячи з того, чи була ваша діяльність відкрита startActivityабо startActivityForResult. Ви можете досягти цього, використовуючи getCallingActivity(). Більше інформації тут .


-2

Використовуйте sharedPreferences та зберігайте свої дані та отримуйте доступ до них з будь-якої точки програми

зберегти дату, як ця

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, value);
    editor.commit();

І отримуйте такі дані

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);

6
Це було б більш доречно, якби другий вид діяльності встановлював постійну зміну / налаштування в додатку.
ліквідує

Чи спрацює це, якщо я хочу поділитися даними між двома різними додатками для Android?
joey rohan

21
Це зловживання SharedPreferences.
Еран Голдін

1
Використовувати цей метод просто для передачі даних між двома видами діяльності (оригінальне запитання ОП) - це як зловживання SharedPreferences. Це не призначено для цього, і системі доводиться робити занадто багато роботи (писати XML на сховище і читати його знову) для простого завдання, наприклад передачі даних між двома видами діяльності.
Судара
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.