การส่งข้อมูลกลับไปที่กิจกรรมหลักใน Android


295

ฉันมีสองกิจกรรม: กิจกรรมหลักและกิจกรรมเด็ก
เมื่อฉันกดปุ่มในกิจกรรมหลักกิจกรรมย่อยจะเริ่มขึ้น

ตอนนี้ฉันต้องการส่งข้อมูลกลับไปที่หน้าจอหลัก ฉันใช้คลาส Bundle แต่มันไม่ทำงาน มันมีข้อยกเว้นรันไทม์บางอย่าง

มีวิธีแก้ไขปัญหานี้หรือไม่?



เคล็ดลับอีกประการหนึ่งกำหนด ArrayList ในกิจกรรมหลักของคุณและทำให้เป็นแบบคงที่เพื่อให้คุณสามารถเข้าถึงได้ในกิจกรรมที่สองจากนั้นเพิ่มข้อมูลในสิ่งที่คุณต้องการส่งไปยังกิจกรรมหลักจากนั้นคุณเข้าถึงกิจกรรมหลัก
Abhishek Yadav

Abhishek Yadav จะเกิดอะไรขึ้นถ้ากิจกรรมหลักของคุณกำลังจะทำลาย (การโทรกลับ) (onDestroy ()) ฉันคิดว่ามันไม่ใช่คำแนะนำที่ดีมาก
Leontsev Anton

คำตอบ:


472

มีสองวิธีในการบรรลุสิ่งที่คุณต้องการขึ้นอยู่กับสถานการณ์

สถานการณ์ที่พบบ่อยที่สุด (ซึ่งเป็นสิ่งที่คุณฟังดูเหมือน) คือเมื่อมีการใช้กิจกรรมลูกเพื่อรับอินพุตผู้ใช้เช่นการเลือกผู้ติดต่อจากรายการหรือการป้อนข้อมูลในกล่องโต้ตอบ ในกรณีนี้คุณควรใช้startActivityForResultเพื่อเปิดกิจกรรมลูกของคุณ

setResultแห่งนี้มีท่อสำหรับส่งข้อมูลกลับไปยังกิจกรรมหลักโดยใช้ เมธอด setResult รับค่าผลลัพธ์ที่เป็น Int และ Intent ที่ส่งกลับไปยังการเรียกกิจกรรม

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ในการเข้าถึงข้อมูลที่ส่งกลับในการลบล้างความเคลื่อนไหวเรียกร้อง requestCode สอดคล้องกับจำนวนเต็มที่ส่งผ่านไปในการstartActivityForResultโทรในขณะที่ resultCode และ Data Intent จะถูกส่งคืนจากกิจกรรมย่อย

@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
เพื่อความสมบูรณ์เราควรพูดถึงว่าสถานที่ที่ดีที่สุดในการโทรออกให้เสร็จสิ้นคืออะไร? มันอาจจะชัดเจนสำหรับผู้เชี่ยวชาญ แต่สำหรับผู้เริ่มต้นจะดีที่จะรู้โดยไม่ต้องอ้างอิงแหล่งข้อมูลเพิ่มเติม
Califf

1
@jelmoodjasser มันเอาฉันบิตที่จะคิดออก แต่โดยทั่วไปเมื่อคุณเริ่มต้นกิจกรรมใหม่ด้วยความตั้งใจที่คุณต้องการที่จะใช้ฟังก์ชั่นแทนเพียงstartActivityForResult startActivityตัวอย่างอาจเป็นstartActivityForResult(myIntent, 2);ที่ 2 คือรหัสผลลัพธ์ซึ่งสามารถแทนที่MY_CHILD_ACTIVITYในคำสั่ง switch ข้างต้น
ปอตไลต์

เมื่อกิจกรรมที่สองเสร็จสิ้นและกลับไปที่กิจกรรมแรกแล้ววิธีการตั้งค่า requestCode เป็นกิจกรรมที่สองก่อนที่จะเสร็จสิ้น .... เพื่อใช้กับ onActivityResult ในกิจกรรมแรก
Ahamadullah Saikat

เจตนาคืออะไร? หากฉันไม่มีสิ่งใดที่จะส่งคืนฉันต้องมีเจตนาที่ว่างเปล่าเพื่อส่งกลับหรือไม่
Bagus Aji Santoso

@BagusAjiSantoso ความตั้งใจเป็นตัวเลือกจำเป็นเฉพาะในกรณีที่คุณมีอะไรที่จะส่งกลับ
Narendra Singh

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 - การกลับมาจากกิจกรรมก่อนหน้านี้จะเรียกใช้ActivityResult :

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

UPDATE: ตอบความคิดเห็นของ 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การให้รหัสผลลัพธ์โดยพลการ
  • 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 requestCode); // suppose requestCode == 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 หรือ onBackPressed ()

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

มันเป็นผลรหัสของคำขอรหัส?
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

ในกิจกรรมครั้งแรก u สามารถส่งเจตนาใช้ แล้วได้รับผลจากการดำเนินกิจกรรมที่สองหลังจากที่เสร็จสิ้นการใช้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.First ของฉัน ActivityA กำลังเรียกใช้ ActivityB จากนั้นภายใน ActivityB ให้ตั้งค่า studentId (ซึ่งเป็นฟิลด์แบบคงที่ใน Utils.class) เช่นนี้ Utils.STUDENT_ID = "1234"; จากนั้นในขณะที่กลับมาที่ ActivityA ให้ใช้ studentId ซึ่งเก็บไว้ใน UtilsSTUDENT_ID

  2. โดยการสร้างวิธี getter และ setter ใน Application Class ของคุณ

แบบนี้:

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
สิ่งนี้จะเหมาะสมกว่าหากกิจกรรมที่สองเป็นการตั้งค่าการเปลี่ยนแปลง / การตั้งค่าถาวรในแอปพลิเคชัน
elimirks

มันจะใช้งานได้หรือไม่ถ้าฉันต้องการแชร์ข้อมูลระหว่างแอพ android ที่แตกต่างกัน 2 อันหนึ่งเรียกว่าไลบรารี่?
joey rohan

21
นี่คือการละเมิด SharedPreferences
Eran Goldin

1
การใช้วิธีนี้เพียงแค่ส่งข้อมูลระหว่างสองกิจกรรม (คำถามดั้งเดิมของ OP) ก็เหมือนกับการใช้งาน SharedPreferences ในทางที่ผิด มันไม่ได้มีไว้สำหรับสิ่งนี้และระบบจะต้องทำงานมากเกินไป (เขียน xml บนที่เก็บและอ่านอีกครั้ง) สำหรับงานง่าย ๆ เช่นการส่งข้อมูลระหว่างสองกิจกรรม
Sudara
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.