Я создаю свои фрагменты в onCreate () моего первого действия. В этом случае in может видеть следующий поток приложения:
- 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 () , но это приводит меня к другой проблеме.
Как я могу это исправить?
publi c class 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;
}
}
Спасибо за вашу помощь
EDIT 1 :
Как подсказал Луис Кардоза Берд, я поместил свой код в onViewCreated (). Но я столкнулся с другой проблемой, о которой я быстро упомянул в оригинальном сообщении. Я начинаю цепочку анимаций в конце onViewCreated (). Сначала при запуске растет пузырь, затем запускается вторая анимация (представленная mStartingAnimation ), когда фоновый поток загружает файл JSON, и в конце последней анимации я хочу остановить mStartingAnimation в обратном вызове onNewDataSolcast () . Но я получаю исключение 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) {
}
}