首页 > 解决方案 > 使用 SharedPreferences 保存抽象类的子类的 ArrayList

问题描述

大家下午好,我是一名大学生,我决定制作一个有趣的点击游戏,直到现在它进展顺利,因为我遇到了一个我无法理解的“错误”:

我有一个名为“UpgradesClick”的抽象类,其中包含所有点击升级,如下所示:抽象类树

我的抽象类“UpgradesClick”实现 Parcelable(我尝试通过 Intent.PutExtra 传递它,但它不起作用)抽象类

然后我认为 SharedPreferences 会救我,因为我已经听说过它们,并且我希望我的升级点击商店活动执行 save() onPause()方法调用,以保存所有对象的值,Level 和 Price 所以我决定制作一个抽象类 UpgradeClick 的 ArrayList,并将它们全部放在里面。将对象添加到 ArrayList

然后我编写了典型的 SharedPreferences 调用 Save() 和 Load(),每当我从 MainActivity 移动到 Store 时,它​​都会显示数据已加载 (1)* 但是当我移回 MainActivity 时游戏崩溃,并将我的所有值设置回 0(2)* --- *见这里

这是我的问题,我的 onSave() 方法出现一个我无法理解的错误,因为它没有强调任何内容。Save() 和 Load() 方法

它在“json = gson.toJson(todosUpgradesClick);”上给了我一个错误 我假设它是我将 ArrayList 转换为 Json 文件的地方。

真的很伤心,“将对象发送到其他活动”这件事不允许我继续我的游戏,因为大部分游戏代码只是在我的 onClick 方法上添加每个 Class 的值并乘以其他值。
也很抱歉没有在帖子上发布任何代码,但它太大了,我认为没有人会费心阅读。非常感谢您的时间,亲爱的堆栈溢出者 ;)


PS:如果您想知道“列表”,我首先将它作为一个 ArrayList,但它不起作用,所以截图部分显示“ List”也被尝试作为一个 ArrayList。
再一次,

编辑 - 添加代码和错误日志

代码:

> 
import android.app.Activity;
import android.os.Parcel;
import android.os.Parcelable;
import android.widget.TextView;

public abstract class UpgradesClick extends MainActivity implements Parcelable {
    private int nivel;
    private int preco;
    private int precoBase;
    private int valorGanhoPorClick;
    Activity act;

    //private TextView tvQtdPClick;
    private TextView tvnivel;
    private TextView tvpreco;

    protected UpgradesClick(Activity act, int nivel, int precoBase){
        //setTvQtdPClick( (TextView) act.findViewById(R.id.qtdcuspopc) );
        this.nivel = nivel;
        this.precoBase = precoBase;
        this.act = act;
    }
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(nivel);
        out.writeInt(preco);
    }
    protected UpgradesClick(Parcel in) {
        nivel = in.readInt();
        preco = in.readInt();
    }
    public void comprarUpgrade(){
        setNivel( getNivel() + 1 );
        setPreco( getNivel() * 5 );
        setValorGanhoPorClick( getNivel() );
    }
    public float getValorGanhoPorClick() {
        return valorGanhoPorClick;
    }
    public void setValorGanhoPorClick(int valorGanhoPorClick) {
        this.valorGanhoPorClick = valorGanhoPorClick;
    }
    public int getPrecoBase() {
        return precoBase;
    }
    public void setPrecoBase(int precoBase) {
        this.precoBase = precoBase;
    }
    public void setPreco(int preco) {
        this.preco = preco;
    }
    public int getPreco(){
        if (getNivel() == 0){
            return precoBase;
        }else {
            return preco;
        }
    }
    public int getNivel() {
        return nivel;
    }
    public void setNivel(int nivel) {
        this.nivel = nivel;
    }
    public void setTvnivel(TextView tvnivel) {
        this.tvnivel = tvnivel;
    }
    public TextView getTvnivel() {
        return tvnivel;
    }
    public void setTvpreco(TextView tvpreco) {
        this.tvpreco = tvpreco;
    }
    public TextView getTvpreco() {
        return tvpreco;
    }
}
class UpgradeClick_Gosma extends UpgradesClick{

    public UpgradeClick_Gosma(Activity act, int nivel, int precoBase) {

        super(act, nivel, precoBase);
        setValorGanhoPorClick(getNivel());
        setPreco(getPrecoBase() * getNivel());
    }

    public static final Parcelable.Creator<UpgradeClick_Gosma> CREATOR = new Parcelable.Creator<UpgradeClick_Gosma>() {
        public UpgradeClick_Gosma createFromParcel(Parcel in) {
            return new UpgradeClick_Gosma(in);
        }

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

    public UpgradeClick_Gosma(Parcel in) {
        super(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
class UpgradeClick_Dedeta extends UpgradesClick{

    public UpgradeClick_Dedeta(Activity act, int nivel, int precoBase) {

        super(act, nivel, precoBase);
        setValorGanhoPorClick(getNivel());
        setPreco(getPrecoBase() * getNivel());
    }

    public static final Parcelable.Creator<UpgradeClick_Dedeta> CREATOR = new Parcelable.Creator<UpgradeClick_Dedeta>() {
        public UpgradeClick_Dedeta createFromParcel(Parcel in) {
            return new UpgradeClick_Dedeta(in);
        }

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

    public UpgradeClick_Dedeta(Parcel in) {
        super(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
class UpgradeClick_Sorte extends UpgradesClick{

    public UpgradeClick_Sorte(Activity act, int nivel, int precoBase) {

        super(act, nivel, precoBase);
        setValorGanhoPorClick(getNivel());
        setPreco(getPrecoBase() * getNivel());
    }

    public static final Parcelable.Creator<UpgradeClick_Sorte> CREATOR = new Parcelable.Creator<UpgradeClick_Sorte>() {
        public UpgradeClick_Sorte createFromParcel(Parcel in) {
            return new UpgradeClick_Sorte(in);
        }

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

    public UpgradeClick_Sorte(Parcel in) {
        super(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
class UpgradeClick_Douro extends UpgradesClick{

    public UpgradeClick_Douro(Activity act, int nivel, int precoBase) {

        super(act, nivel, precoBase);
        setValorGanhoPorClick(getNivel());
        setPreco(getPrecoBase() * getNivel());
    }

    public static final Parcelable.Creator<UpgradeClick_Douro> CREATOR = new Parcelable.Creator<UpgradeClick_Douro>() {
        public UpgradeClick_Douro createFromParcel(Parcel in) {
            return new UpgradeClick_Douro(in);
        }

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

    public UpgradeClick_Douro(Parcel in) {
        super(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
class UpgradeClick_Agua extends UpgradesClick{

    public UpgradeClick_Agua(Activity act, int nivel, int precoBase) {

        super(act, nivel, precoBase);
        setValorGanhoPorClick(getNivel());
        setPreco(getPrecoBase() * getNivel());
    }

    public static final Parcelable.Creator<UpgradeClick_Agua> CREATOR = new Parcelable.Creator<UpgradeClick_Agua>() {
        public UpgradeClick_Agua createFromParcel(Parcel in) {
            return new UpgradeClick_Agua(in);
        }

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

    public UpgradeClick_Agua(Parcel in) {
        super(in);
    }

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

-- 购物活动代码

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;

public class UpgradeClickActvity extends AppCompatActivity {
    //UpgradesClick.UpgradeClick1 upgrade;

    Intent intent;

    int[] IMAGEM = {R.drawable.upgradespit1, R.drawable.upgradespit2, R.drawable.upgradespit3, R.drawable.upgradespit4, R.drawable.upgradespit5};
    int[] NOME = {R.string.UpgradeClick1Titulo, R.string.UpgradeClick2Titulo, R.string.UpgradeClick3Titulo, R.string.UpgradeClick4Titulo, R.string.UpgradeClick5Titulo};
    int[] DESCRICAO = {R.string.UpgradeClick1Descricao, R.string.UpgradeClick2Descricao, R.string.UpgradeClick3Descricao, R.string.UpgradeClick4Descricao, R.string.UpgradeClick5Descricao};


    UpgradeClick_Gosma upgradeclickgosma;
    UpgradeClick_Dedeta upgradeclickdedeta;
    UpgradeClick_Sorte upgradeclicksorte;
    UpgradeClick_Douro upgradeclickdouro;
    UpgradeClick_Agua upgradeclickagua;

    List<UpgradesClick> todosUpgradesClick;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.upgrades_click);
        todosUpgradesClick = new ArrayList<>();

        loadData();

        Intent intent = getIntent();
        Cuspo cuspo = (Cuspo) intent.getParcelableExtra("objCuspo");
        TextView textoQtdCuspo = (TextView)findViewById(R.id.lojaQtdCuspo);
        textoQtdCuspo.setText(String.valueOf(cuspo.getQtd()));
        TextView textoQtdCuspoUni = (TextView)findViewById(R.id.lojaQtdCuspoUni);
        textoQtdCuspoUni.setText(String.valueOf(cuspo.getQtdUni()));


        upgradeclickgosma = new UpgradeClick_Gosma(this, 0, 20);
        upgradeclickdedeta = new UpgradeClick_Dedeta(this, 0, 100);
        upgradeclicksorte = new UpgradeClick_Sorte(this, 0, 500);
        upgradeclickdouro = new UpgradeClick_Douro(this, 0, 1000);
        upgradeclickagua = new UpgradeClick_Agua(this, 0, 5000);

        todosUpgradesClick.add(upgradeclickgosma);
        todosUpgradesClick.add(upgradeclickdedeta);
        todosUpgradesClick.add(upgradeclicksorte);
        todosUpgradesClick.add(upgradeclickdouro);
        todosUpgradesClick.add(upgradeclickagua);


        ListView listView = (ListView)findViewById(R.id.listviewupgclick);
        CustomAdapter customAdapter = new CustomAdapter();
        listView.setAdapter(customAdapter);
        ImageView btnBack = (ImageView)findViewById(R.id.btnback) ;
        btnBack.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(UpgradeClickActvity.this, MainActivity.class);
                intent.putExtra("upggosma", upgradeclickgosma);
                //intent.putExtra("upgdedeta", upgradeclickdedeta);
                startActivity(intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        saveData();
        //intent = new Intent(UpgradeClickActvity.this, MainActivity.class);
        Toast.makeText(UpgradeClickActvity.this, "Data saved" ,Toast.LENGTH_LONG).show();
    }

    class CustomAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return IMAGEM.length;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View view, ViewGroup parent) {
            view = getLayoutInflater().inflate(R.layout.upgradestemplate, null);

            ImageView imageView = (ImageView)view.findViewById(R.id.template_imagem);
            TextView textView_name = (TextView)view.findViewById(R.id.template_titulo);
            TextView textView_descricao = (TextView)view.findViewById(R.id.template_descricao);
            TextView textView_preco = (TextView)view.findViewById(R.id.template_preco);
            TextView textView_nivel = (TextView)view.findViewById(R.id.template_nivel);

            imageView.setImageResource(IMAGEM[position]);
            textView_name.setText(NOME[position]);
            textView_descricao.setText(DESCRICAO[position]);
            textView_preco.setText(String.valueOf(todosUpgradesClick.get(position).getPreco()));
            textView_nivel.setText(String.valueOf(todosUpgradesClick.get(position).getNivel()));

            return view;
        }
    }

    private void saveData(){
        SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(todosUpgradesClick);
        editor.putString("todosUpgradesClick", json);
        editor.apply();
    }

    private void loadData(){
        Toast.makeText(UpgradeClickActvity.this, "Carregou dados" ,Toast.LENGTH_LONG).show();
        SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
        Gson gson = new Gson();
        String json = sharedPreferences.getString("todosUpgradesClick", null);
        Type type = new TypeToken<List<UpgradesClick>>() {}.getType();
        todosUpgradesClick = gson.fromJson(json, type);
        if(todosUpgradesClick == null){
            todosUpgradesClick = new ArrayList<UpgradesClick>();
        }
    }

}

最后,错误日志:

2018-10-30 21:34:44.470 1843-1963/? E/LogCollectService: illegal eventid
2018-10-30 21:34:45.343 12820-12820/? E/XmlParser: startElement mResult:1024
2018-10-30 21:34:45.343 12820-12820/? E/XmlParser: startElement mResult:2097152
2018-10-30 21:34:45.351 408-2015/? E/ion: set flags ioctrl failed!
2018-10-30 21:34:45.439 12706-12706/paixao.com.findingdawae E/AndroidRuntime: FATAL EXCEPTION: main
    Process: paixao.com.findingdawae, PID: 12706
    java.lang.RuntimeException: Unable to pause activity {paixao.com.findingdawae/paixao.com.findingdawae.UpgradeClickActvity}: java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible
        at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3952)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3918)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3892)
        at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3860)
        at android.app.ActivityThread.-wrap16(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1588)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible
        at java.lang.reflect.AccessibleObject.setAccessible0(AccessibleObject.java:133)
        at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:119)
        at com.google.gson.internal.reflect.PreJava9ReflectionAccessor.makeAccessible(PreJava9ReflectionAccessor.java:31)
        at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:103)
        at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
2018-10-30 21:34:45.439 12706-12706/paixao.com.findingdawae E/AndroidRuntime:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:56)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
        at com.google.gson.Gson.toJson(Gson.java:704)
        at com.google.gson.Gson.toJson(Gson.java:683)
        at com.google.gson.Gson.toJson(Gson.java:638)
        at com.google.gson.Gson.toJson(Gson.java:618)
        at paixao.com.findingdawae.UpgradeClickActvity.saveData(UpgradeClickActvity.java:133)
        at paixao.com.findingdawae.UpgradeClickActvity.onPause(UpgradeClickActvity.java:87)
        at android.app.Activity.performPause(Activity.java:7071)
        at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1335)
        at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3941)
            ... 11 more
2018-10-30 21:34:45.443 1218-4703/? E/ReportTools: This is not beta user build
2018-10-30 21:34:45.518 554-830/? E/logserver: imonitor_add_dynamic_path, path:/data/system/dropbox/data_app_crash@1540935285455.txt.gz
2018-10-30 21:34:45.635 1218-6950/? E/HsmCoreServiceImpl: onTransact in code is: 102
2018-10-30 21:34:45.678 1020-12064/? E/AsyncOperation: serviceID=40, operation=LogOperation
    OperationException[Status{statusCode=Log from CONTEXT_MANAGER dropped because of storage full, resolution=null}]
        at oxj.a(:com.google.android.gms@14366021@14.3.66 (040408-213742215):72)
        at xey.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):27)
        at bdrz.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):2)
        at qjt.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):35)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at qpu.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215))
        at java.lang.Thread.run(Thread.java:776)
2018-10-30 21:34:45.685 1020-12064/? E/AsyncOperation: serviceID=40, operation=LogOperation
    OperationException[Status{statusCode=Log from LB_COUNTERS dropped because of storage full, resolution=null}]
        at oxj.a(:com.google.android.gms@14366021@14.3.66 (040408-213742215):72)
        at xey.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):27)
        at bdrz.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):2)
        at qjt.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):35)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at qpu.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215))
        at java.lang.Thread.run(Thread.java:776)
2018-10-30 21:34:45.720 1020-12064/? E/AsyncOperation: serviceID=40, operation=LogOperation
    OperationException[Status{statusCode=Log from CONTEXT_MANAGER dropped because of storage full, resolution=null}]
        at oxj.a(:com.google.android.gms@14366021@14.3.66 (040408-213742215):72)
        at xey.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):27)
        at bdrz.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):2)
        at qjt.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215):35)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at qpu.run(:com.google.android.gms@14366021@14.3.66 (040408-213742215))
        at java.lang.Thread.run(Thread.java:776)

标签: javaandroidabstract-classparcelable

解决方案


将无参数构造函数添加到您的UpgradesClick

public UpgradesClick() {

}

推荐阅读