【发布时间】:2020-07-14 12:54:03
【问题描述】:
我在我的第一个活动的 onCreate() 中实例化我的片段。在这种情况下可以看到以下应用流程:
- MainActivity : onCreate()
- Fragment1 : onAttach() : 在那里我得到一个监听器来从 Activity 中获取数据
- Fragment1:onCreateView()
- Fragment2:onAttach()
- Fragment2:onCreateView()
- Fragment3:onAttach()
- Fragment3:onCreateView()
- ...
我的应用程序运行良好,除非我执行以下步骤: 1 - 打开应用程序 2 - 按主页按钮 3 - 使用内置优化器应用程序强制终止应用程序 4 - 再次打开应用程序
在这种情况下,应用程序是:
- Fragment1:onAttach()
- MainActivity : onCreate()
- Fragment1:onCreateView()
- ...
因此,我在 onAttach() 方法中获得的侦听器无效,并在我使用接口时导致 NullPointerException !我不明白我该如何解决它。我试图在 onCreatedActivity() 中获取回调,但这会导致我遇到其他问题。
我该如何解决?
公共类 ForecastFragment 扩展 Fragment 实现 OnNewDataSolcastListener、Animation.AnimationListener、OnFailGetDataSolcast {
private ScaleAnimation mStartingAnimation;
private ViewGroup mBubble;
private Solcast mSolcast;
private TextView mTxtConso;
private TextView mTxtConso2;
private TextView mTxtPresentationConso;
private ImageView mImgErrorSolcast;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Log.e(getClass().getSimpleName(), "onAttach()");
if(getActivity() instanceof Solcast.GetSolcastListener)
mSolcast = ((Solcast.GetSolcastListener) getActivity()).getSolcast();
else
throw new RuntimeException(getClass().getSimpleName() + " have to implement " + Solcast.GetSolcastListener.class.getSimpleName());
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.e(getClass().getSimpleName(), "onCreateView()");
final View rootView = inflater.inflate(R.layout.content_main, container, false);
//init la GUI pour les fonctions qui auront besoin de ces View
mTxtConso = rootView.findViewById(R.id.txtValeurProduction);
mTxtConso2 = rootView.findViewById(R.id.txtValeurProduction2);
mTxtPresentationConso = rootView.findViewById(R.id.txtPresentationProduction);
mBubble = rootView.findViewById(R.id.bubbleMain);
mImgErrorSolcast = rootView.findViewById(R.id.imgErrorSolcast);
mImgErrorSolcast.setVisibility(View.GONE);
//some stuff...
//FAIL HERE : mSolcast null
mSolcast.setSearchDates(start, end);
return rootView;
}
}
感谢您的帮助
编辑 1:
按照 Luis Cardoza Bird 的建议,我将代码放在 onViewCreated() 中。但是我面临另一个问题,我在原帖中很快提到了这个问题。我在 onViewCreated() 的末尾开始了一系列动画。首先,在启动时,会出现一个气泡,然后在后台线程下载 JSON 文件时开始第二个动画(由 mStartingAnimation 表示),在最后一个动画结束时,我想停止onNewDataSolcast() 回调中的 mStartingAnimation。但是我在这个函数中得到了一个 NullPointerException 。我不明白,因为我之前已经开始了,所以我怎么可能得到 NullPointerException ? 正常打开应用没有这个问题。
这是新代码:
public class ForecastFragment extends Fragment implements OnNewDataSolcastListener, Animation.AnimationListener, OnFailGetDataSolcast{
private ScaleAnimation mStartingAnimation;
private ViewGroup mBubble;
private Solcast mSolcast;
private TextView mTxtConso;
private TextView mTxtConso2;
private TextView mTxtPresentationConso;
private ImageView mImgErrorSolcast;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Log.e(getClass().getSimpleName(), "onAttach()");
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.e(getClass().getSimpleName(), "onCreateView()");
return inflater.inflate(R.layout.content_main, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if(getActivity() instanceof Solcast.GetSolcastListener)
mSolcast = ((Solcast.GetSolcastListener) getActivity()).getSolcast();
else
throw new RuntimeException(getClass().getSimpleName() + " have to implement " + Solcast.GetSolcastListener.class.getSimpleName());
View rootView = getView();
assert rootView != null;
//init la GUI pour les fonctions qui auront besoin de ces View
mTxtConso = rootView.findViewById(R.id.txtValeurProduction);
mTxtConso2 = rootView.findViewById(R.id.txtValeurProduction2);
mTxtPresentationConso = rootView.findViewById(R.id.txtPresentationProduction);
mBubble = rootView.findViewById(R.id.bubbleMain);
mImgErrorSolcast = rootView.findViewById(R.id.imgErrorSolcast);
mImgErrorSolcast.setVisibility(View.GONE);
//on prépare la future animation pour la bulle qui respire
mStartingAnimation = new ScaleAnimation(1.05f, 1f, 1.05f, 1f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
mStartingAnimation.setDuration(1200);
mStartingAnimation.setInterpolator(new OvershootInterpolator());
mStartingAnimation.setRepeatCount(Animation.INFINITE);
//some stuff
mSolcast.setSearchDates(start, end);
final ScaleAnimation anim = new ScaleAnimation(0f, 1f, 0, 1f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(500);
anim.setInterpolator(new LinearInterpolator());
anim.setAnimationListener(this);
mBubble.startAnimation(anim);
}
/*
Appelée lorsque les données JSON ont été reçues puis traitées.
Renvoi la liste des énergies @listEnergy associées à leur date dans @listeDate
*/
@Override
public void onNewDataSolcast(ArrayList<Solcast.SolcastData> solcastData) {
//Les données JSON ont été traitées, triées, etc... On renvoi le résultat vers la GUI
Log.e("ForecastFragment:onNewDataSolcast", "New data");
//mStartingAnimation is null : NullPointerException here !
**mStartingAnimation.cancel();**
mBubble.clearAnimation();
}
//animation callbacks
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
//Lorsque la bulle, au démarrage, a fini de grossir on démarre le téléchargement JSON. Cela peut prendre quelques secondes,
//donc on fait l'animation de la bulle qui "respire" en boucle jusqu'à réception des données
//on fait apparaitre le texte "consomation estimée..."
ObjectAnimator anim2 = ObjectAnimator.ofFloat(mTxtPresentationConso, "alpha", 0.0f, 1.0f);
anim2.setInterpolator(new LinearInterpolator());
anim2.setDuration(2000);
anim2.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
//start animation - works well
mBubble.startAnimation(mStartingAnimation);
//will call onNewDataSolcast() callback at the end of the operations
mSolcast.readJSON();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
anim2.start();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
【问题讨论】:
-
也附上你的崩溃报告,它会让你的问题更容易理解。
标签: java android android-fragments android-lifecycle