2

I have a problem to get my list data. I have an data class.

public class MedicineUsageData {

String companyName;
String productName;
String drugSubstance;
String expireDate;
String barcodeNum;
String serialNum;
String partyNum;
String userName;
int userAge;

public MedicineUsageData() {
}

public MedicineUsageData(String companyName, String productName, String drugSubstance, String expireDate, String barcodeNum, String serialNum, String partyNum, String userName, int userAge) {
    this.companyName = companyName;
    this.productName = productName;
    this.drugSubstance = drugSubstance;
    this.expireDate = expireDate;
    this.barcodeNum = barcodeNum;
    this.serialNum = serialNum;
    this.partyNum = partyNum;
    this.userName = userName;
    this.userAge = userAge;
}

public String getCompanyName() {
    return companyName;
}

public void setCompanyName(String companyName) {
    this.companyName = companyName;
}

public String getProductName() {
    return productName;
}

public void setProductName(String productName) {
    this.productName = productName;
}

public String getdrugSubstance() {
    return drugSubstance;
}

public void setdrugSubstance(String drugSubstance) {
    this.drugSubstance = drugSubstance;
}

public String getExpireDate() {
    return expireDate;
}

public void setExpireDate(String expireDate) {
    this.expireDate = expireDate;
}

public String getBarcodeNum() {
    return barcodeNum;
}

public void setBarcodeNum(String barcodeNum) {
    this.barcodeNum = barcodeNum;
}

public String getSerialNum() {
    return serialNum;
}

public void setSerialNum(String serialNum) {
    this.serialNum = serialNum;
}

public String getPartyNum() {
    return partyNum;
}

public void setPartyNum(String partyNum) {
    this.partyNum = partyNum;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public int getUserAge() {
    return userAge;
}

public void setUserAge(int userAge) {
    this.userAge = userAge;
}
}

I created a list of this object.

List<MedicineUsageData> medicineUsageDataList = new ArrayList<>();

Then in my button listener I create a JSON file to pass this list to another activity.

String medicineUsageJson = gson.toJson(medicineUsageDataList);
Intent recyclerIntent = new Intent(MainScreenActivity.this,RecyclerViewActivity.class);
recyclerIntent.putExtra("medicineList", medicineUsageJson);
startActivity(recyclerIntent);

Then in other activity I get JSON data and convert it to list again.

medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), List.class);

Then I call my Adapter and send medicineList.

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MedicineUsageDataViewHolder> {

public static class MedicineUsageDataViewHolder extends RecyclerView.ViewHolder {

    CardView cv;
    TextView medicineName;
    TextView expireDate;

    MedicineUsageDataViewHolder(View itemView) {
        super(itemView);
        cv = (CardView)itemView.findViewById(R.id.MedicineInfo);
        medicineName = (TextView)itemView.findViewById(R.id.medicine_name);
        expireDate = (TextView)itemView.findViewById(R.id.expire_date);
    }
}

List<MedicineUsageData> medicineList;

RecyclerAdapter(List<MedicineUsageData> medicineList){
    this.medicineList = medicineList;
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

@Override
public RecyclerAdapter.MedicineUsageDataViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.medicine_usage_data, viewGroup, false);
    RecyclerAdapter.MedicineUsageDataViewHolder mvh = new RecyclerAdapter.MedicineUsageDataViewHolder(v);
    return mvh;
}

@Override
public void onBindViewHolder(RecyclerAdapter.MedicineUsageDataViewHolder medicineUsageDataViewHolder, int i) {
    medicineUsageDataViewHolder.medicineName.setText(medicineList.get(i).getproductName);
    medicineUsageDataViewHolder.expireDate.setText(medicineList.get(i).getexpireDate);

    //medicineUsageDataViewHolder.medicineName.setText("bug is");
    //medicineUsageDataViewHolder.expireDate.setText("here");
}

@Override
public int getItemCount() {
    return medicineList.size();
}
}

I try set text of textview with this code.

medicineUsageDataViewHolder.medicineName.setText(medicineList.get(i).getproductName);
medicineUsageDataViewHolder.expireDate.setText(medicineList.get(i).getexpireDate);

But my application crash at this point. If I change this code with this one it works.

//medicineUsageDataViewHolder.medicineName.setText("bug is");
//medicineUsageDataViewHolder.expireDate.setText("here");

So I think my main problem is medicineList.get(i) part. "getproductName" method returns string so it is not a problem. I also try to use toString() method but it didn't fix it either.

I can't see my problem here I tried so many things but I can't see any error. My data comes perfectly , there is no sync problem. I don't know what is the problem is.

Here is my data I checked it in debug mode.

medicineList

I try to convert list data to String and show it and it works. But it isn't my current wanted situation.

medicineUsageDataViewHolder.medicineName.setText(medicineList.toString());

Here is the result of execute of this line. All of the data are correct. But as I say it isn't my wanted situation. I want to access fields like expireDate etc.

[{barcodeNum=8699570090119, companyName=HÜSNÜ ARSAN İLAÇLARI A.Ş., drugSubstance=parasetamol, psödoefedrin hcl, triprolidin hcl, expireDate=12/21, partyNum=19093004A, productName=A-FERIN SINUS 500/30/1.25 MG FİLM KAPLI TABLET, 20 ADET, serialNum=05000023512631, userAge=25.0, userName=admin}, {barcodeNum=8690570010008, companyName=RECKİTT BENCKİSER TEMİZLİK MALZEMELERİ SAN. TİC. A.Ş., drugSubstance=ibuprofen, psödoefedrin hcl, expireDate=09/19, partyNum=CB284, productName=NUROFEN COLD FLU TABLET, 24 ADET, serialNum=80392202232051, userAge=25.0, userName=admin}]

Could you help me please ?

Here is the stack trace record. I checked it but I can't find issue.

            2020-03-12 18:31:01.714 14062-14062/com.track.medicine D/AndroidRuntime: Shutting down VM
2020-03-12 18:31:01.719 14062-14062/com.track.medicine E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.track.medicine, PID: 14062
    java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.track.medicine.MedicineUsageData
        at com.track.medicine.RecyclerAdapter.onBindViewHolder(RecyclerAdapter.java:50)
        at com.track.medicine.RecyclerAdapter.onBindViewHolder(RecyclerAdapter.java:14)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1780)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1546)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:446)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:945)
        at android.view.View.layout(View.java:20854)
        at android.view.ViewGroup.layout(ViewGroup.java:6401)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2956)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2643)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1780)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7827)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
2020-03-12 18:31:01.719 14062-14062/com.track.medicine E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
muratcanyeldan
  • 111
  • 2
  • 14
  • 1
    Pleas post the stack trace – Nghia Do Mar 12 '20 at 14:27
  • firstly: what is the error message? – Vault23 Mar 12 '20 at 14:28
  • @fascynacja I see why you said it was duplicate. But he used an extra class. So I couldn't get answer from that question I thought extra class caused the error. And I didn't notice "TypeToken" part because of extra class as I say. Sorry for asking duplicate but that was the reason I couldn't see answer from that question until people say it to me here. Thanks all. – muratcanyeldan Mar 12 '20 at 15:44

3 Answers3

1

I guess your problem is here:

medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), List.class);

You need to deserealize in the way like this:

List<MedicineUsageData> medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), new TypeToken<List<MedicineUsageData>>() {}.getType());
Vault23
  • 743
  • 1
  • 5
  • 19
1

Issue is in this line

medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), List.class);

Just change it to

medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), 
                     new TypeToken<List<MedicineUsageData>>(){}.getType());

and it will return list of MedicineUsageData.

Massab
  • 1,030
  • 9
  • 22
  • Thank you very much for your answer. This solved my issue. But why I need to do that ? What is the reason for that ? I can parse my JSON to other activities without a problem. Why it caused this ? Is it relative with List ? An example I parse my Map data to JSON and send it to another activity and use it without this "TypeToken" part. – muratcanyeldan Mar 12 '20 at 15:41
  • @muratcangm yes dear, this happens in case of lists. Java doesn't provide a way to represent generic classes so this class does. you can find details here https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/reflect/TypeToken.html – Massab Mar 12 '20 at 16:42
0

I can definitely tell that your problem is here:

medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), List.class);

You are not telling GSON which type it should use. Ok you're telling it to use a List, but a list of What?

Try to pass this instead of List.class

Type type = new TypeToken<List<MedicineUsageData>>(){}.getType();
medicineList = gson.fromJson(getIntent().getStringExtra("medicineList"), type);
Alan Deep
  • 2,037
  • 1
  • 14
  • 22
  • 1
    Thank you very much for information. So if I use GSON with a list I should use TypeToken right ? Thank you I didn't know that. This takes me 4 hours to investigate still I didn't find the answer. Thank you all for answering again. I really appreciate it. – muratcanyeldan Mar 12 '20 at 15:47
  • Exactly. We were all there my friend. This is how we learn :) – Alan Deep Mar 13 '20 at 19:22