父片段在子片段中是活动的,但活动为空。

4

我有一个子片段,其中父片段保持活动状态,但在某些随机情况下,活动上下文会变为空,否则它可以正常工作。 我的子片段代码如下:

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;
}

这是我的Fragment,从中调用子Fragment(CFcurrent.java)的方式如下:

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) {

}

这里是我的基础活动,它广播一个事件,并被CFcurrent.java拦截,在某些随机条件下,所有活动实例都会变成null。 我的基础活动代码如下:

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);
}

请帮我翻译以下内容,因为我不理解如果父片段存在,活动如何变为空值:

}

请协助我完成此操作,因为我无法理解如果父片段存在,活动如何变为空值。


“一些随机条件”是什么? - suku
@suku,没有任何随机条件,因为每当它收到通知时,updateRecord()都会被触发并且正常工作,但是在某些情况下activity会变成null,我不知道那些是什么随机情况。 - Abhinandan Chada
BroadcastReceiver 是由系统异步调用的,与您的 Fragment/Activity 生命周期不一定同步。如果它获取到 NULL,则这是片段和接收器之间的竞争条件。您应该仅在注册时创建接收器,然后在构造函数中传递 Activity,以确保它不为 NULL。您还应该只在与活动/片段生命周期同步的情况下注册/取消注册接收器,而不是作为初始化字段。 - escape-llc
1个回答

1

在检查Activity时创建/销毁片段。 谨慎使用activity/fragment重写函数,并基于该活动的上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接