2016-01-10 50 views
1

我遇到了一个让我完全无法相信的问题。我的自定义对象似乎在通过意图发送到新活动后丢失了值。为什么一个对象只有在被意图传递后才会丢失它的实例变量的值?可传递自定义对象,当意图传递时丢失实例值

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

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中

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; 

一旦意图被发送,我会在我的新活动中收到它。

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

}

适配器然后采取车辆对象,并使用getter方法来生成卡

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在我的对象上。 我的对象中的哈希表丢失了它们的值 下面是当您按最近值并返回到应用程序时发生的情况。该应用程序永远不会失去焦点。 Pressing Recents

下面是一个日志显示会发生什么

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

在这之后跑到这里又被称为对象

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并传递可串行化的结果。 在此先感谢!

+0

我没有看到问题,但你可以尝试切换到Parceler,看看是否修复它。 https://github.com/johncarl81/parceler – nasch

+0

有趣的项目。我给了一个镜头 – kd8bny

+0

所以我缩小了这个问题一点。转出循环器视图是奇怪的,因为我将setAdapter放在onStart方法中。 但是,将对象发送给其他活动时仍存在问题。变成parcelable可以正常工作,但是我的对象实例在onResume方法运行后发生了变化。即丢失数据。 – kd8bny

回答

0

我终于弄清楚这个问题是什么问题。

JAVA是按值传递

我的自定义对象将通过HashMap中的值,每当我创建了一个新的对象。然后编辑对象或调用它,并且hashmap将返回其最后一个键/值对。我通过使用Gson序列化hashmap并稍后将其返回给它的表单来解决问题。