Search code examples
androidandroid-fragmentsandroid-fragmentactivityfragmentmanager

Parent Fragment is alive in Child Fragment but Activity is Null


I have a child fragment in which , parent fragment stays alive but activity context gets null in some random conditions otherwise it works fine, My child fragment code is as follows,

package cl.tt.ui.fragments.child;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.json.JSONObject;

import cl.tt.R;
import cl.tt.controllers.constants.ConstantNumber;
import cl.tt.controllers.constants.Constants;
import cl.tt.controllers.constants.Enums_String;
import cl.tt.controllers.listeners.ProcessedResult;
import cl.tt.controllers.rest_api.RetrofitAdapters;
import cl.tt.modals.JEmployees;
import cl.tt.modals.NotificationStatusClass;
import cl.tt.ui.activities.PaymentDetails;
import cl.tt.ui.activities.base_activity.BaseActivity;
import cl.tt.ui.activities.sub_activity.AddPayment;
import cl.tt.ui.adapter.AFCurrent;
import cl.tt.utility.LogUtil;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class CFCurrent extends Fragment {

int skip = 0, totalSize = -1, lastVist = 0;
private Context context;
private AFCurrent afCurrent;
private List<JEmployees.Job> data;

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context contex, Intent intent) {
        if (Enums_String.LocalReceiver.JOB_ACTIVITY_STATUS_CHANGED.toString().equals(intent.getAction())) {
            String jobId = intent.getExtras().getString(Constants.Other.JOBID);

            JEmployees.Job job= new JEmployees.Job();
            job.setId(jobId);

            if(data==null || data.isEmpty())
                return;

            int position=-1;
            if(data.contains(job))
                position=data.indexOf(job);
            updateRecord(position, jobId, null);
        }
    }
};

private void updateRecord(final int position,final String jobId, final NotificationStatusClass notificationStatusClass)
{
    final StringBuilder matchedPosition= new StringBuilder();
    matchedPosition.append(position);

 //Here the all activity instance gets null in some random conditions.
    try {
        LogUtil.e("current fragment:-", getParentFragment() + "");
        LogUtil.e("current direct activity:-", getActivity() + "");
        LogUtil.e("current activity:-", getParentFragment().getActivity() + "");
    }catch (Exception e)
    {
        LogUtil.e("current error:-", e.getLocalizedMessage()+"");
    }
    try {
        LogUtil.e("1current direct activity:-", getActivity() + "");
        LogUtil.e("1current activity:-", getParentFragment().getActivity() + "");
    }catch (Exception e)
    {
        LogUtil.e("1current error:-", e.getLocalizedMessage()+"");
    }
    try {
        LogUtil.e("11current activity:-", getParentFragment().getActivity() + "");
    }catch (Exception e)
    {
        LogUtil.e("11current error:-", e.getLocalizedMessage()+"");
    }
    String accessToken=((BaseActivity)getParentFragment().getActivity()).accessToken;

}

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

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    View view = inflater.inflate(R.layout.recycler_empty_view, container, false);


    IntentFilter filter = new IntentFilter(Enums_String.LocalReceiver.JOB_ACTIVITY_STATUS_CHANGED.toString());
    LocalBroadcastManager.getInstance(context).registerReceiver(mMessageReceiver, filter);
    return view;
}

}

This is my Fragment from which child fragments(CFcurrent.java) gets invoked as follows,

package cl.tt.ui.fragments;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.util.ArrayList;
import java.util.List;

import cl.tt.R;
import cl.tt.controllers.constants.Enums_String;
import cl.tt.ui.adapter.CFragmentPagerAdapter;
import cl.tt.ui.iBAPViews.SegmentedGroup;
import cl.tt.ui.fragments.child.CFCompleted;
import cl.tt.ui.fragments.child.CFCurrent;
import cl.tt.utility.fonts.FontsManager;

public class Engagements extends 
Fragment implements     RadioGroup.OnCheckedChangeListener,   ViewPager.
OnPageChangeListener {
private Context context;
private ViewPager viewPager;
private SegmentedGroup segmentedGroup;

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

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    final View view = inflater.inflate(R.layout.fragment_engagements, container, false);
    initialize(view);
    return view;
}

private final void initialize(View view) {
    segmentedGroup= (SegmentedGroup)view.findViewById(R.id.frag_engage_rg_completeType);
    segmentedGroup.setOnCheckedChangeListener(this);

    viewPager = (ViewPager) view.findViewById(R.id.frag_engage_vpager);
    viewPager.setPageMargin((int)context.getResources().getDimension(R.dimen._20sdp));
    viewPager.setPageMarginDrawable(android.R.color.transparent);
    viewPager.addOnPageChangeListener(this);

    List<Fragment> fragmentList=new ArrayList<>();
    fragmentList.add(new CFCurrent());
    fragmentList.add(new CFCompleted());
    CFragmentPagerAdapter pagerAdapter=new CFragmentPagerAdapter(getChildFragmentManager(),fragmentList);
    viewPager.setAdapter(pagerAdapter);

    FontsManager.initFormAssets(context, Enums_String.FontsNameLato.MEDIUM.toString());
    FontsManager.changeFonts(view);
}

@Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{
    switch (checkedId)
    {
        case R.id.frag_engage_rb_current:
            viewPager.setCurrentItem(0);
            break;
        case R.id.frag_engage_rb_complete:
            viewPager.setCurrentItem(1);
            break;
    }
}


@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
    switch (position)
    {
        case 0:
            ((RadioButton)segmentedGroup.findViewById(R.id.frag_engage_rb_current)).setChecked(true);
            break;
        case 1:
            ((RadioButton)segmentedGroup.findViewById(R.id.frag_engage_rb_complete)).setChecked(true);
            break;
    }
}

@Override
public void onPageScrollStateChanged(int state) {

}

}

Here is by base activity which broadcast an event and is intercepted by CFcurrent.java and in some random conditions all activity instance gets null. My base activity code is as follows,

package cl.tt.ui.activities.base_activity;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;

import cl.tt.modals.NotificationStatusClass;
import cl.tt.utility.LogUtil;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class BaseActivity extends AppCompatActivity {
public String accessToken = null;

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get extra data included in the Intent
        if (Enums_String.LocalReceiver.PUSH_ARRIVAL.toString().equals(intent.getAction()))
                showPopup(intent.getBundleExtra(Enums_String.LocalReceiver.PUSH_ARRIVAL.toString()));
    }
};

public static NotificationStatusClass getTitle(String string,NotificationStatusClass notificationStatusClass) {
    switch (Enums_String.PushNotificationConstant.valueOf(string)) {
        case CONFIRM_CLOCK_OUT: {
            notificationStatusClass.setStatus(Enums_String.ActivityStatus.CLOCK_OUT_CONFIRMED.name());
            notificationStatusClass.setTitle(Constants.NotificationConstant.CLOCKOUT);
        }break;
        case CONFIRM_AFTER_LUNCH_CLOCK_IN: {
            notificationStatusClass.setStatus(Enums_String.ActivityStatus.AFTER_LUNCH_CONFIRMED.name());
            notificationStatusClass.setTitle(Constants.NotificationConstant.CLOCK_IN_AFTER_LUNCH);
        }break;
        case CONFIRM_CLOCK_IN: {
            notificationStatusClass.setStatus(Enums_String.ActivityStatus.CLOCK_IN_CONFIRMED.name());
            notificationStatusClass.setTitle(Constants.NotificationConstant.CLOCK_IN_CONFIRMATION);
        }break;
    }
    return notificationStatusClass;
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    IntentFilter filter = new IntentFilter(Enums_String.LocalReceiver.PUSH_ARRIVAL.toString());
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter);

    accessToken = GeneralFunctions.getStorageManager(this).getValue(Enums_String.SharedPreferenceConstant.APP_ACCESSTOKEN.toString(), null);
}

private void showPopup(final Bundle bundle) {
    NotificationStatusClass notificationStatusClass= new NotificationStatusClass();

    String desc = bundle.getString("message");
    try {
        JSONObject jsonObject = new JSONObject(bundle.getString(Constants.Other.FLAG));
        notificationStatusClass.setJobId(jsonObject.getString(Constants.Other.JOBID));
        notificationStatusClass=  getTitle(jsonObject.getString(Constants.Other.ACTION), notificationStatusClass);

    } catch (Exception e)
    {
    }
 sendLocalNotification(notificationStatusClass);
}

private void sendLocalNotification(final NotificationStatusClass notificationStatusClass) {
    Intent intent=null;
    Bundle bundle = new Bundle();
    bundle.putString(Constants.Other.JOBID, notificationStatusClass.getJobId());
    if(Constants.NotificationConstant.JOB_CONFIRMED.equals(notificationStatusClass.getTitle())) {
        intent = new Intent(Enums_String.LocalReceiver.JOBDELETE.toString());
        intent.putExtras(bundle);
        LocalBroadcastManager.getInstance(BaseActivity.this).sendBroadcast(intent);
    }

    intent = new Intent(Enums_String.LocalReceiver.JOB_ACTIVITY_STATUS_CHANGED.toString());
    intent.putExtras(bundle);

    LocalBroadcastManager.getInstance(BaseActivity.this).sendBroadcast(intent);
}

}

Please assist me in doing so, as i am unable to understand how an activity gets null if the parent fragment exist.


Solution

  • Create/destroy fragment on the check of Activity. Use activity/fragment override function carefully and on the basis of context of that activity.