可传递自定义对象在故​​意传递时丢失实例值 [英] Parcelable custom object losing instance values when passed with intent

查看:56
本文介绍了可传递自定义对象在故​​意传递时丢失实例值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,使我完全陷入了难以置信的境地.通过意图将其发送到新活动后,我的自定义对象似乎正在丢失值.为什么一个对象只有在故意传递后才丢失其实例变量的值?

Ive come in to a problem that has me completely stumped beyond belief. My custom object seems to be losing the values after it is sent via intent to a new activity. Why would an object lose values of its instance variables only after being passed with intent?

我有一个实现Parcelable的自定义对象,用于存储特定数据.

I have custom object that implements Parcelable, for storing specific data.

public class Vehicle implements Parcelable, Serializable{
private static final String TAG = "vehicleObject";
public String vehicleType;
public String refID;
public String title;

public HashMap<String, String> reservedSpecs;
public HashMap<String, String> generalSpecs;
public HashMap<String, String> engineSpecs;
public HashMap<String, String> powerTrainSpecs;
public HashMap<String, String> otherSpecs;

public Vehicle(String vehicleType, String year, String make, String model){
    this.refID = UUID.randomUUID().toString();
    this.title = year + " " + make + " " + model;
    this.vehicleType = vehicleType;
    this.reservedSpecs = new HashMap<>();
    this.reservedSpecs.put("year", year);
    this.reservedSpecs.put("make", make);
    this.reservedSpecs.put("model", model);
}

public Vehicle(Parcel source){
    Bundle bundle = source.readBundle(getClass().getClassLoader());
    vehicleType = bundle.getString("vehicleType");
    refID = bundle.getString("refID");
    title = bundle.getString("title");

    reservedSpecs = (HashMap) bundle.getSerializable("reserved");
    generalSpecs = (HashMap) bundle.getSerializable("general");
    engineSpecs = (HashMap) bundle.getSerializable("engine");
    powerTrainSpecs = (HashMap) bundle.getSerializable("power");
    otherSpecs = (HashMap) bundle.getSerializable("other");
}

@Override
public void writeToParcel(Parcel dest, int flags){
    Bundle bundle = new Bundle();
    bundle.putString("vehicleType", vehicleType);
    bundle.putString("refID", refID);
    bundle.putString("title", title);
    bundle.putSerializable("reserved", reservedSpecs);
    bundle.putSerializable("general", generalSpecs);
    bundle.putSerializable("engine", engineSpecs);
    bundle.putSerializable("power", powerTrainSpecs);
    bundle.putSerializable("other", otherSpecs);

    dest.writeBundle(bundle);
}

@Override
public int describeContents(){
    return 0;
}

/**
  *Generic getters/Setters for all instance variables 
**/

/**
 * Creator required for class implementing the parcelable interface.
 */
public static final Parcelable.Creator<Vehicle> CREATOR = new Creator<Vehicle>() {

    @Override
    public Vehicle createFromParcel(Parcel source) {
        return new Vehicle(source);
    }

    @Override
    public Vehicle[] newArray(int size) {
        return new Vehicle[size];
    }
};

}

然后,在我的主要活动中,使用侦听器传递对象(车辆).该对象位于ArrayList中

I then, in my main activity, pass the object(Vehicle) using a listener. The object lives in ArrayList

public class fragment_overview extends Fragment implements UpdateUI{
    private static final String TAG = "frg_ovrvw";

    private final String SHARED_PREF = "com.kd8bny.maintenanceman_preferences";

    private Toolbar toolbar;
    private Context context;
    private SharedPreferences sharedPreferences;
    private RecyclerView cardList;
    private RecyclerView.LayoutManager cardMan;
    private RecyclerView.Adapter cardListAdapter;

    private ArrayList<Vehicle> roster;
    private String mUnit;

    public fragment_overview() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        context = getActivity().getApplicationContext();
        roster = new ArrayList<>(new SaveLoadHelper(context).load());
    }

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

        sharedPreferences = context.getSharedPreferences(SHARED_PREF, 0);

        //Toolbar
        toolbar = (Toolbar) view.findViewById(R.id.tool_bar);
        ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
        ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        ((AppCompatActivity)getActivity()).getSupportActionBar().setHomeButtonEnabled(true);

        //cards
        mUnit = sharedPreferences.getString("prefUnitDist", "");

        cardList = (RecyclerView) view.findViewById(R.id.overview_cardList);
        cardMan = new LinearLayoutManager(getActivity());
        cardList.setLayoutManager(cardMan);
        cardList.addOnItemTouchListener(new RecyclerViewOnItemClickListener(context, cardList, new RecyclerViewOnItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int pos) {
                if (!roster.isEmpty()) { //THIS INTENT HERE
                    Intent viewIntent = new Intent(getActivity(), test.class);
                    Bundle bundle = new Bundle();
                    bundle.putParcelable("vehicle", roster.get(pos));
                    bundle.putInt("pos", pos);
                    viewIntent.putExtra("bundle", bundle);
                    view.getContext().startActivity(viewIntent);
                } else {
                    Intent addIntent = new Intent(getActivity(), activity_add_fleetRoster.class);
                    addIntent.putParcelableArrayListExtra("roster", roster);
                    view.getContext().startActivity(addIntent);
                }
            }

            @Override
            public void onItemLongClick(View view, int pos) {}}));

      return view;

一旦发送了意图,我就会在新活动中收到它.

Once the intent is sent I receive it in my new activity.

public class test extends AppCompatActivity {
private ArrayList<Vehicle> roster;
private Vehicle vehicle;
RecyclerView cardList;
RecyclerView.LayoutManager cardMan;
RecyclerView.Adapter cardListAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    Bundle bundle = getIntent().getBundleExtra("bundle");
    vehicle = bundle.getParcelable("vehicle");
    int vehiclePos = bundle.getInt("pos", -1);

    //Set recycler view
    cardList = (RecyclerView) findViewById(R.id.info_cardList);
    cardMan = new LinearLayoutManager(this);
    cardList.setLayoutManager(cardMan);

    }

@Override
public void onResume(){
    super.onResume();

    cardListAdapter = new adapter_info(vehicle);
    cardList.setAdapter(cardListAdapter);
 }

}

适配器然后获取车辆对象并使用吸气剂生成卡

The adapter then takes the vehicle object and uses getters to generate cards

public adapter_info(Vehicle vehicle) {
    ArrayList<HashMap> temp = new ArrayList<>();
    temp.add(vehicle.getGeneralSpecs());
    temp.add(vehicle.getEngineSpecs());
    temp.add(vehicle.getPowerTrainSpecs());
    temp.add(vehicle.getOtherSpecs());       
}
/**
*Adapter stuff such as onCreateViewHodler and bind
**/

现在,所有这些都可以正常工作,并且在第一个遍历中非常出色.当我尝试通过其他意图发送该对象,恢复活动之后尝试执行任何操作时,在我的对象上使用getter和setter进行的任何操作. 我对象中的哈希图丢失了值 以下是当您按最新记录"并返回到应用程序时会发生的情况的gif图像.该应用程序永远不会失去焦点.

Now this all works fine and dandy the first run-through. When I Try to do anything after including sending this object through another intent, resuming the activity, anything using getters and setters on my object. The Hashmaps in my object lose their values Below is a gif of what happens when you press recents and return to the app. The app never loses focus.

这是显示发生情况的日志

Here is a log showing what happens

 01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman D/TEST!!!: create{G=G}{E=E}{P=P}{Po=Oo}   //All 4 hashmaps with values
01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman A/getGeneralSpecs: get{G=G} //A log of each hashmap in the object's getter method
01-09 20:27:19.850 2359-2359/com.kd8bny.maintenanceman A/getEngineSpecs: get{E=E}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman A/getPowerTrainSpecs: get{P=P}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman A/getOtherSpecs: get{Po=Oo}
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{G=G}, {E=E}, {P=P}, {Po=Oo}] //Finally what the adapter sees using the getter method
01-09 20:27:19.851 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{G=G}, {E=E}, {P=P}, {Po=Oo}]

在此之后,再次调用该对象

After this ran here is the object called again

    01-09 20:28:13.382 2359-2359/com.kd8bny.maintenanceman A/getGeneralSpecs: get{} //Empty hashmap that had G=G
01-09 20:28:13.382 2359-2359/com.kd8bny.maintenanceman A/getEngineSpecs: get{}  //Empty hashmap that had E=E
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman A/getPowerTrainSpecs: get{}  //Empty hashmap that had P=P
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman A/getOtherSpecs: get{Po=Oo}   //hashmap that retains its value
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{Po=Oo}] //And what the adapter sees as it calls on the object again
01-09 20:28:13.383 2359-2359/com.kd8bny.maintenanceman E/adptr_inf: [{Po=Oo}]

为什么这些价值消失了?我可以通过其他方式解决此问题吗?我已经尝试过使用singeton并通过可序列化的结果相同. 预先感谢!

Why are these value disappearing? Can I do this differently to fix the problem. I have tried using a singeton and passing serializable with the same results. Thanks in advance!

推荐答案

我终于弄清楚了这个问题的根源.

I finally figured out what the issue was in this problem.

JAVA通过值传递

每当我创建一个新对象时,我的自定义对象都会传递哈希图的值.然后,我将编辑该对象或对其进行调用,哈希图将返回其最后一个键/值对.我通过使用Gson序列化哈希图并在以后将其返回为其形式来解决了这个问题.

My custom object would pass value of the hashmap whenever I created a new object. I would then edit the object or call on it and the hashmap would return its last key/value pair. I solved the issue by using Gson to serialize the hashmap and return it to its form later.

这篇关于可传递自定义对象在故​​意传递时丢失实例值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆