如何在 Fragment 中使用 onNewIntent(Intent intent) 方法?

Posted

技术标签:

【中文标题】如何在 Fragment 中使用 onNewIntent(Intent intent) 方法?【英文标题】:How to use method onNewIntent(Intent intent) inside a Fragment? 【发布时间】:2015-07-14 14:49:30 【问题描述】:

我正在尝试通过我的设备使用 NFC 硬件。但是,问题是当我注册 Activity 以接收 Intent 时:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

我在 Activity 而不是 Fragment 中收到结果。有没有办法在 Fragment 中处理这个结果?

提前致谢!

【问题讨论】:

【参考方案1】:

onNewIntent 属于 Activity,因此您不能在片段中使用它。您可以做的是在数据到达onNewIntent 时将数据传递给您的片段,前提是您有对片段的引用。

Fragment fragment;  
@Override
protected void onNewIntent(Intent intent) 
    super.onNewIntent(intent);

    // Check if the fragment is an instance of the right fragment
    if (fragment instanceof MyNFCFragment) 
        MyNFCFragment my = (MyNFCFragment) fragment;
        // Pass intent or its data to the fragment's method
        my.processNFC(intent.getStringExtra());
    


【讨论】:

Fragment 中onNewIntent 的生命周期是多少? @IgorGanapolsky Fragments 没有启动模式,除此之外,它们不是由 Intent 而不是 Activity 启动的,因此没有等效项。【参考方案2】:

我通过以下方式解决了我的问题:

在 MyActivity.java 中

@Override
protected void onNewIntent(Intent intent) 
    super.onNewIntent(intent);
    setIntent(intent);

在 MyFragment.java 中

@Override
public void onStart() 
    super.onStart();
    if (getActivity() != null && getActivity().getIntent().hasExtra(...)) 
        // do whatever needed
    

【讨论】:

【参考方案3】:

使用LiveData

存储库:

class IntentRepo  
    private val _intent = MutableLiveData<Intent>()

    val get: LiveData<Intent> = Transformations.map(_intent)  it!! 

    fun set(intent: Intent)  _intent.value = intent 

活动视图模型:

class MainViewModel(intentRepo: IntentRepo) : ViewModel() 
    val intent = intentRepo

活动

override fun onNewIntent(intent: Intent?) 
    super.onNewIntent(intent)
    viewModel.intent.set(intent)

片段

viewModel.intent.get.observe(viewLifecycleOwner, 
    // Your intent: $it
)

【讨论】:

【参考方案4】:

我们以更动态的方式处理调用以支持任何片段,方法是在 Activity 中添加类似:

// ...

public class ActivityMain extends AppCompatActivity 

    // ...

    @Override
    protected void onNewIntent(Intent intent) 
        super.onNewIntent(intent);
        Fragment fragment = getFragment();
        if (fragment != null) 
            try 
                Method method = fragment.getClass().getMethod("onNewIntent", Intent.class);
                method.invoke(fragment, intent);
             catch (NoSuchMethodException ignored) 
             catch (IllegalAccessException | InvocationTargetException e) 
                Log.e(TAG, "Failed to call onNewIntent method for class: " + fragment.getClass().getSimpleName());
            
        
    

    public Fragment getFragment() 
        // For NAVIGATION-DRAWER only
        // (replace below logic, if you use View-Pager).

        FragmentManager manager = this.getSupportFragmentManager();
        manager.executePendingTransactions();
        return manager.findFragmentById(R.id.my_main_content);
    

然后在每个根Fragment 简单地听:

  @SuppressWarnings("unused")
  public void onNewIntent(Intent intent) 
    Log.i("MyTag", "onNewIntent: " + intent);
  

【讨论】:

以上是关于如何在 Fragment 中使用 onNewIntent(Intent intent) 方法?的主要内容,如果未能解决你的问题,请参考以下文章

onNewIntent使用-Android

为什么要在onNewIntent的时候要显示的去调用setIntent

切换选项卡 onNewIntent 导致 IllegalStateException

onNewIntent() 生命周期和注册的监听器

onNewIntent()

onNewIntent(intent) 不能正常工作