You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Activity间传递数据及通过startActivityForResult更新数据与界面

嘿,我来帮你搞定这两个Android开发的问题,结合你给的代码片段详细拆解~

问题一:如何从通过getIntent()接收数据的Activity中发送数据?

其实不管这个Activity是不是通过getIntent()接收数据的,发送数据的逻辑和普通Activity完全一致,分两种场景:

  • 如果是要把数据返回给上一个启动它的Activity:用setResult()配合finish()就行,就像你在AddNewContact里做的那样。比如当前Activity是接收了数据的ViewContact,现在要回传数据给Activity A,代码可以这么写:
    // 准备返回的Intent和数据
    Intent resultIntent = new Intent();
    resultIntent.putExtra("KEY_UPDATED_CONTACT_ID", contactId);
    // 设置结果码和数据
    setResult(RESULT_OK, resultIntent);
    finish(); // 关闭当前Activity,回到上一个
    
  • 如果是要启动新的Activity并传递数据:直接用startActivity()就行,和普通场景没区别,比如从ViewContact启动另一个Activity:
    Intent intent = new Intent(this, OtherActivity.class);
    intent.putExtra("KEY_CONTACT_INFO", contact);
    startActivity(intent);
    

简单说:接收Intent数据的身份,不会限制你发送Intent的能力~

问题二:能否在Activity B中用startActivityForResult(),在Activity C修改数据后更新B的数据库与布局?

当然可以!你的思路完全没问题,代码里的更新没生效,大概率是数据库更新是异步操作,但你没在更新完成后触发UI刷新,不一定非要用LiveData,但LiveData会让这个过程更省心。

先分析你的现有代码问题

你在ViewContact的onActivityResult里拿到了编辑后的联系人数据,调用了contactRepository.update(contact),但UI没变化:

  • 如果你的Repository的update方法是异步的(比如用Room的suspend方法、Coroutine或者AsyncTask),数据库确实会更新,但ViewContact的UI没有收到“数据已更新”的通知,所以不会自动刷新。
  • 另外,注意startActivityForResult()已经被AndroidX废弃了,推荐用registerForActivityResult(),后面会给你示例。

解决方案:两种方式实现UI更新

方式一:手动刷新UI(简单直接,适合小场景)

在数据库更新完成后,重新查询该联系人的最新数据,然后手动更新ViewContact的所有控件:

// 修改onActivityResult里的更新逻辑
if (requestCode == EDIT_CONTACT_REQUEST && resultCode == RESULT_OK) {
    // ... 前面获取name、phone等数据的代码
    Contact contact = new Contact(
            name, surname, company, phoneNumber, phoneType,
            email, emailType, address, postcode);
    contact.setId(id);

    // 用Coroutine在后台更新数据库,避免阻塞主线程
    CoroutineScope(Dispatchers.IO).launch {
        contactRepository.update(contact);
        // 后台查询最新的联系人数据
        Contact updatedContact = contactRepository.getContactByIdSync(id);
        // 切回主线程更新UI
        withContext(Dispatchers.Main) {
            // 手动更新所有显示控件
            tvName.setText(updatedContact.getName());
            tvSurname.setText(updatedContact.getSurname());
            tvPhone.setText(updatedContact.getPhoneNumber());
            // 其他控件同理更新
        }
    }
    Toast.makeText(this, "联系人已更新", Toast.LENGTH_SHORT).show();
}

这里假设你的Repository有一个同步查询的getContactByIdSync方法,如果用Room的话,这个方法要放在后台线程调用。

方式二:用LiveData自动监听数据库变化(推荐,符合MVVM规范)

如果你的ViewContact一开始就是通过LiveData来观察联系人数据的,那么当数据库更新时,LiveData会自动通知UI刷新,完全不用手动触发:

  1. 首先确保你的Room DAO和Repository提供返回LiveData的查询方法:
    // DAO层
    @Dao
    interface ContactDao {
        @Update
        suspend fun update(contact: Contact);
        
        @Query("SELECT * FROM contacts WHERE id = :id")
        fun getContactById(id: Int): LiveData<Contact>;
    }
    
    // Repository层
    class ContactRepository(application: Application) {
        private val contactDao: ContactDao;
        
        init {
            ContactDatabase db = ContactDatabase.getDatabase(application);
            contactDao = db.contactDao();
        }
    
        suspend fun update(contact: Contact) {
            contactDao.update(contact);
        }
    
        fun getContactById(id: Int): LiveData<Contact> {
            return contactDao.getContactById(id);
        }
    }
    
  2. 在ViewContact的onCreate里观察这个LiveData,初始化UI并自动监听变化:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_contact);
        
        // 获取要查看的联系人ID
        int contactId = getIntent().getIntExtra(EXTRA_ID, -1);
        ContactRepository contactRepository = new ContactRepository(getApplication());
        
        // 观察LiveData,数据变化时自动更新UI
        contactRepository.getContactById(contactId).observe(this, contact -> {
            if (contact != null) {
                tvName.setText(contact.getName());
                tvSurname.setText(contact.getSurname());
                tvPhone.setText(contact.getPhoneNumber());
                // 其他控件初始化/更新
            }
        });
    }
    
  3. 然后在onActivityResult里只需要异步更新数据库即可,LiveData会自动触发UI刷新:
    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == EDIT_CONTACT_REQUEST && resultCode == RESULT_OK) {
            // ... 前面获取数据的代码
            Contact contact = new Contact(
                    name, surname, company, phoneNumber, phoneType,
                    email, emailType, address, postcode);
            contact.setId(id);
            
            // 异步更新数据库
            CoroutineScope(Dispatchers.IO).launch {
                contactRepository.update(contact);
            }
            Toast.makeText(this, "联系人已更新", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "联系人未更新", Toast.LENGTH_SHORT).show();
        }
    }
    

补充:替换废弃的startActivityForResult()

从AndroidX Activity 1.2.0开始,startActivityForResult()被废弃,推荐用registerForActivityResult(),代码示例如下:

// 在ViewContact里定义ActivityResultLauncher
private ActivityResultLauncher<Intent> editContactLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == RESULT_OK) {
                Intent data = result.getData();
                if (data != null) {
                    int id = data.getIntExtra(EXTRA_ID, -1);
                    if (id == -1) {
                        Toast.makeText(this, "联系人未更新", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    // 这里处理返回的数据,和原来的onActivityResult逻辑一致
                    String name = data.getStringExtra(EXTRA_NAME);
                    // ... 其他数据获取和更新逻辑
                }
            } else {
                Toast.makeText(this, "联系人未更新", Toast.LENGTH_SHORT).show();
            }
        });

// 启动编辑页面Activity C时调用
Intent intent = new Intent(this, AddNewContact.class);
intent.putExtra(EXTRA_ID, contactId); // 传递要编辑的联系人ID
editContactLauncher.launch(intent);

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:11:18