无法从片段开始活动,得到 IllegalArgumentException

Posted

技术标签:

【中文标题】无法从片段开始活动,得到 IllegalArgumentException【英文标题】:Can't start activity from fragment, getting IllegalArgumentException 【发布时间】:2020-08-12 00:39:58 【问题描述】:

我尝试从我的片段开始一个活动,但收到此错误:

引起:java.lang.IllegalArgumentException:参数指定为 非空为空:方法 kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull,参数 捆绑

我使用 java 不知道为什么会出现 kotlin 错误

这是我的片段:

public class LoginFragment extends Fragment 

private FragmentLoginBinding binding;
private AuthSharedViewModel sharedViewModel;

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
    sharedViewModel = ((LoginActivity) getActivity()).viewModel;
    binding.setViewmodel(sharedViewModel);
    binding.setLifecycleOwner(this);

    onClickListener();

    return binding.getRoot();


private void onClickListener() 

    binding.loginBtn.setOnClickListener(v -> 
        Intent intent = new Intent(getActivity(), MainActivity.class);
        startActivity(intent);
    );



@Override
public void onDestroyView() 
    super.onDestroyView();
    sharedViewModel.getIsFetchSmsSuccessful().removeObservers(this);
   


代码在片段上出错,但在活动上工作。

任何机构都可以提供帮助??

【问题讨论】:

您在什么时候收到错误消息?当您单击片段中的按钮时?或者当你打开这个片段时? @droidbaza 两人 您的日志错误显示捆绑参数为空。这意味着您可能错误地请求/使用捆绑。例如你不包括检查(如果捆绑!=空)。很难说没有看到你的代码 第一。在你的 destroyView (if (sharedViewModel!=null) sharedViewModel.getIsFetchSmsSuccessful().removeObservers(this);2d 替换此行 "sharedViewModel = ((LoginActivity) getActivity()).viewModel;" - (而不是getActivity - 活动) 【参考方案1】:

您可以在片段中尝试使用此代码代替“getActivity”:

private AppCompatActivity activity;

 @Override
  public void onAttach(@NonNull Context context) 
      super.onAttach(context);
      if (context instanceof AppCompatActivity) 
        activity = (AppCompatActivity) context;
    
  

然后在你的 clickListener 中

 Intent intent = new Intent(activity, MainActivity.class);
 activity.startActivity(intent);
 activity.finish();

【讨论】:

请解释一下为什么这是一个更好的解决方案? @RobAu 谢谢,但不工作,仍然得到同样的错误 @RobAu 如果 getActivity () 返回 null,则片段要么与活动断开连接,要么尚未附加。 (发生待处理的提交事务) @droidbaza getActivity() 不返回 null。它有价值,我在这个片段的其他部分使用了活动,我认为问题不在于活动 我知道。我更新评论更高。只是你用getActivity带了一段sn-p代码【参考方案2】:

尝试不使用第二个getActivity()。 Fragment 类中也有startActivity() 方法。

Intent intent = new Intent(getActivity(), NewActivity.class);
startActivity(intent);

编辑: 在活动可能尚未准备好时调用 onClickListener。 More about the fragment lifecycle. 试试这个:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) 
    super.onActivityCreated(savedInstanceState);
    onClickListener();

@Override public void onViewCreated

【讨论】:

你试过新的 Intent(this, NewActivity.class);也?你有同样的错误吗? 此代码在活动中运行良好,但尝试在片段中使用 getActivity() 时会出错。 我刚试过这段代码,它也在片段中工作。也许您可以发布更多代码,以便我们知道何时调用它。 这是整个片段类 尝试在片段生命周期的不同时间调用 onClickListener()。【参考方案3】:

如果你想从片段中打开活动,你需要使用 片段活动

就这样吧

   binding.loginBtn.setOnClickListener
        activity?.let
            it.startActivity(Intent (it, MainActivity::class.java))
            it.finish()
        
    

 binding.loginBtn.setOnClickListener
        requireActivity().startActivity(Intent(requireActivity(),MainActivity::class.java))
        requireActivity().finish()
    

activity?.letrequireActivity() 都是 FragmentActivity

我从您的错误消息中注意到的一件事是

指定为非空的参数为空:方法 kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull,参数 捆绑

所以我会在 Bundle savedInstanceState 中添加 @Nullable

@Nullable
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,@Nullable Bundle savedInstanceState) 
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
    sharedViewModel = ((LoginActivity) getActivity()).viewModel;
    binding.setViewmodel(sharedViewModel);
    binding.setLifecycleOwner(this);

    onClickListener();

    return binding.getRoot();

还有一件事 你需要像这样切换你的代码

@Override
public void onDestroyView() 
    sharedViewModel.getIsFetchSmsSuccessful().removeObservers(this);
    super.onDestroyView();


因为你想在销毁视图之前移除观察者

这就是它在 kotlin 中的样子

class LoginFragment : Fragment() 
    private var binding: FragmentLoginBinding? = null
    private var sharedViewModel: AuthSharedViewModel? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)
        sharedViewModel = (activity as LoginActivity).viewModel
        binding.setViewmodel(sharedViewModel)
        binding.setLifecycleOwner(this)       
        return binding.getRoot()
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        onClickListener()
    


    private fun onClickListener() 
        binding.loginBtn.setOnClickListener
            activity?.startActivity(Intent(activity, MainActivity::class.java))
            activity?.finish()
        
    

    override fun onDestroyView() 
        sharedViewModel.getIsFetchSmsSuccessful().removeObservers(this)
        super.onDestroyView()
    

这是Java

public class LoginFragment extends Fragment 
    private FragmentLoginBinding binding;
    private AuthSharedViewModel sharedViewModel;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
        sharedViewModel = ((LoginActivity) getActivity()).viewModel;
        binding.setViewmodel(sharedViewModel);
        binding.setLifecycleOwner(this);
        return binding.getRoot();
    

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) 
        onClickListener();
    

    private void onClickListener() 
        binding.loginBtn.setOnClickListener(v -> 
            Intent intent = new Intent(getActivity(), MainActivity.class);
            startActivity(intent);
        );
    


    @Override
    public void onDestroyView() 
        sharedViewModel.getIsFetchSmsSuccessful().removeObservers(this);
        super.onDestroyView();

    


【讨论】:

@AbbasTorabi 我编辑了我的代码,请再次检查 将 onClickListerner() 从 onCreateView 移动到 onViewCreated 正是我 2 小时前写的。 @einUserName 是的,我看到你的帖子,我只是重新排列它,但我认为这不是主要问题,问题应该是参数 bundle 为 Null,这就是为什么他应该添加 @Nullable Bundle首先保存实例状态。在 onCreateView() 我的意思是【参考方案4】:

我终于找到了我该死的解决方案。问题是我使用 KeyboardVisibilityEvent 库来控制键盘的隐藏和可见性。

我用这段代码来控制:

KeyboardVisibilityEvent.setEventListener(getActivity(), this::updateKeyboardStatusText); 

但我必须通过方法中的活动来处理生命周期

KeyboardVisibilityEvent.setEventListener(getActivity(), getActivity(), this::updateKeyboardStatusText);

希望能帮助别人。 谢谢大家

【讨论】:

很高兴您找到了解决方案。下次请发布更多代码以及完整的错误消息,包括引发异常的行号。

以上是关于无法从片段开始活动,得到 IllegalArgumentException的主要内容,如果未能解决你的问题,请参考以下文章

从意图活动访问片段方法

我无法从 ListFragment 内的 onListItemClick 开始新活动

从一个活动开始一个片段

从片段开始活动

如何在选项卡式活动中设置片段从右到左开始

如何通过单击片段内的线性布局从片段类开始新活动?下面是我的代码,但这不起作用