Android片段中的Toast显示空指针expn

时间:2018-09-12 07:30:54

标签: java android toast android-toast

在尝试在片段中显示吐司的几种设备上出现错误。这种吐司通常是在翻新响应失败时进行的。吐司代码很简单。请提出建议,找不到在这里和那里搜索的任何原因。

Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();

和我的ST日志在下面。

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
   at android.widget.Toast.(Toast.java:103)
   at android.widget.Toast.makeText(Toast.java:256)

6 个答案:

答案 0 :(得分:4)

根据Fragment.getActivity()的代码和javadoc,您可以返回null

/**
 * Return the {@link FragmentActivity} this fragment is currently associated with.
 * May return {@code null} if the fragment is associated with a {@link Context}
 * instead.
 *
 * @see #requireActivity()
 */
@Nullable
final public FragmentActivity getActivity() {
    return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}

尤其是当您的片段未附加到活动(如herehere)时,可能会发生这种情况。

类似地,getContext()也可以返回null。

在这篇可能相关的文章中,关于何时将其设置为null进行了很好的讨论:


The simple solution has been provided already-在显示Toast之前进行空检查。

但是潜在的问题是体系结构之一-您的代码将API活动耦合到您的UI,并假设有关UI状态的某些事情,即您假设当API调用返回时,用户仍然可以看到屏幕。


更好的解决方案是将Retrofit调用与UI分离-put the API calls in a separate class that does not depend on the UI state

使用事件或pub-sub框架将此API包装器类与需要知道API调用何时返回的所有UI组件进行通信。

EventBusRxJava将是这方面的两种常见解决方案(LocalBroadcastManager将是一种不太常见的方法)。

这将允许任何代码调用您的API,并在API返回时订阅通知。

它还允许您将API响应保存在(例如)本地数据库中,在这种情况下,您可以仅依靠LiveData模式来更新所需的任何UI。

Here's a Medium article giving a brief description of how to use the Android Architecture Components in this manner using the Repository pattern.


鉴于某些项目无法立即重新设计,可能需要解决方法。

上述空检查解决方法很有用,因为该应用程序将不再崩溃。不幸的是,这确实意味着不会向用户通知失败的API调用。

一个替代方法是创建自己的Application子类(许多项目已经完成此操作以初始化公用库),并提供了一种静态访问此应用程序Context的方法。 (A similar suggestion has subsequently been made by Kushal.)

然后,您可以选择使用应用程序Toast来显示Context,而不是片段中的那个。您可能会失去从更特定的上下文中获得的任何特定样式,但是这样做的好处是您的用户仍然可以看到Toast消息。

您的Application暴露为单例已经在这篇文章中进行了很好的描述:

答案 1 :(得分:3)

有时,当片段未与Activity关联时,getActivity()或getContext()可能会产生空指针异常。因此,请使用onAttach方法

public class yourFragment extends Fragment {
   Context context

   @Override
   public void onAttach(Context context) {
        this.context = context;
        super.onAttach(context);
   }
}

答案 2 :(得分:3)

当片段分离时可能会调用getActivity()。试试吧。

if (isAdded()) {
    Toast.makeText(getActivity(), "something", Toast.LENGTH_SHORT).show();
}

答案 3 :(得分:2)

您的活动 std::cout << std::string_view(time + 0, 2) << ':' << std::string_view(time + 2, 2) << ':' << std::string_view(time + 4, 2) << '\n'; 在此行中为空:

context

为避免崩溃,请使用以下命令:

Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();// getActivity() is null

答案 4 :(得分:0)

将您的getActivity()更改为getContext()。请尝试以下给定的代码:

Toast.makeText(getContext(), "Connection Failure", Toast.LENGTH_LONG).show();

答案 5 :(得分:0)

if (isAdded()) {
    Toast.makeText(getActivity(), "something", Toast.LENGTH_SHORT).show();
}

或尝试

if(getActivity() != null)
   Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();

在我的情况下,两种方法都可以正常工作,因为在某些情况下,当片段分离时会调用getActivity()

所以我们也必须照顾它。