在尝试在片段中显示吐司的几种设备上出现错误。这种吐司通常是在翻新响应失败时进行的。吐司代码很简单。请提出建议,找不到在这里和那里搜索的任何原因。
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)
答案 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();
}
尤其是当您的片段未附加到活动(如here和here)时,可能会发生这种情况。
类似地,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组件进行通信。
EventBus
或RxJava
将是这方面的两种常见解决方案(LocalBroadcastManager
将是一种不太常见的方法)。
这将允许任何代码调用您的API,并在API返回时订阅通知。
它还允许您将API响应保存在(例如)本地数据库中,在这种情况下,您可以仅依靠LiveData
模式来更新所需的任何UI。
鉴于某些项目无法立即重新设计,可能需要解决方法。
上述空检查解决方法很有用,因为该应用程序将不再崩溃。不幸的是,这确实意味着不会向用户通知失败的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()
。
所以我们也必须照顾它。