放置并获取savedInstanceState数据

时间:2017-05-01 17:00:06

标签: java android

我试图通过尝试查找如何返回SomeIntegers g_values对象及其中的ArrayList AnInteger对象来尝试理解Activity生命周期。

实际上,它并没有多大意义,但它将作为我真实情况的范例,初始设置要求应用程序通过无数大量的预处理,例如访问和列表字体,分析我所有可用的游戏,在APK,在我的网站上存档和在线,玩家记录等。最终的应用程序是一个游戏和活动系统,以帮助所有年龄段的SpLD(阅读障碍)学生锻炼他们的阅读,拼写,组织技能和短期记忆。这是严肃的意图。虽然是免费运行,但最好与SpLD主管/导师一起使用,他们可以设置他们的工作时间表,甚至可以添加他们自己的游戏。

无论如何都是无关紧要的背景。

我可以使用对savedInstanceState的访问来保存我的有些复杂的对象(有些因为没有正确形式的putxxxxx方法而受到阻碍),还是应该放弃这种方法并从持久性文件或数据库中恢复数据?这可以在这个简单的例子的范围内进行讨论,真实的事情只是更多相同但具有不同的细节。

注意后添加。当应用程序需要保存其InstanceState时,还存在将用户/播放器带回到他/她所处位置的问题。由于主要的影响似乎是平板电脑的方向,我可以通过在启动时锁定方向来迈出一步。这样可以简化许多显示问题,但这是一个“不可接受的”问题。样式?

import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class TestBundle extends AppCompatActivity {
    SomeIntegers g_values;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.out.println("onCreate (" + (savedInstanceState == null ? "null)" : "set)"));
        if (savedInstanceState == null)
        {   g_values = new SomeIntegers();
            String result = g_values.report();
            System.out.println("Startup Result: " + result);
            setContentView(R.layout.activity_test_bundle); // Where do I put this line?
        }
        else
        {   //Do I get g_values back here?
            //More relevantly, can I, and how can I, put g_values in the
            //savedInstanceState when onSaveInstanceState is called?
            String result = g_values.report();
            System.out.println("Result: " + result);
        }
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        System.out.println("onSaveInstanceState (" + (outState == null ? "null)" : "set)"));
        //How do I add g_values to the Bundle?
    }
    // Following is just stuff to watch the progress of the
    // Activity in the ADB Log. Not of much relevance. Or is it?
    @Override
    protected void onStop() {
        super.onStop();
        System.out.println("onStop()");
    }
    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("onStart()");
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        System.out.println("onRestart()");
    }
    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("onResume()");
    }
    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("onPause()");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("onDestroy()");
    }
}

public class SomeIntegers {
    private ArrayList<AnInteger> c_values;
    SomeIntegers() {
        c_values = new ArrayList<AnInteger>();
        c_values.add (new AnInteger(1));
        c_values.add (new AnInteger(2));
        c_values.add (new AnInteger(3));
        c_values.add (new AnInteger(4));
        c_values.add (new AnInteger(29));
        c_values.add (new AnInteger(30));
    }
    String report() {
        String g = "";
        for (AnInteger ai  : c_values) {
            if (!g.isEmpty()) g = g + ", ";
            g = g + ai.getC_value();
        }
        return (g.isEmpty() ? "Empty" : g);
    }
}
public class AnInteger {
    private int c_value;
    AnInteger(int value) { c_value = value); }
    public int getC_value () { return c_value; }
}

谢谢。乔西希尔

2 个答案:

答案 0 :(得分:1)

恢复活动状态的概念基于设备方向。因此,例如,如果您从持久文件中提取一些更改,则加载它,当屏幕更改它时将重新创建数据的旋转角度。因此,活动使用包来包装该数据,并允许用户保存此类文件的当前工作状态,然后可以将其恢复。 Here is a great link。您的要求听起来与数据更改一致,根据我关于预期文件大小的第一个问题,您的要求听起来相对较小。

要处理复合数据类型和抽象数据类型,请考虑使用GSON.which是一个Java序列化/反序列化库,将Java对象转换为JSON并返回

因此我建议你在android中使用共享首选项的强大功能。如果你有一个相对较小的键值集合,你应该使用SharedPreferences API。 SharedPreferences对象指向包含键值对的文件,并提供读取和写入它们的简单方法。简单来说,共享首选项允许您以键,值对的形式保存和检索数据。

Android提供了许多存储应用程序数据的方法。如果您的需求需要存储一致性,我会采用数据库方法,我建议使用realm.Realm是一个移动数据库和SQLite的替代品。虽然是OO数据库,但它与其他数据库存在一些差异。 Realm没有使用SQLite作为它的引擎。相反,它拥有自己的C ++核心,旨在提供SQLite的移动优先替代方案。

希望这有用:)

答案 1 :(得分:1)

首先让您的数据模型实现Parcelable

AnInteger:

public class AnInteger implements Parcelable {
    private int c_value;

    public AnInteger(int value) {
        this.c_value = value;
    }

    public int getC_value() {
        return c_value;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.c_value);
    }

    protected AnInteger(Parcel in) {
        this.c_value = in.readInt();
    }

    public static final Parcelable.Creator<AnInteger> CREATOR = new Parcelable.Creator<AnInteger>() {
        @Override
        public AnInteger createFromParcel(Parcel source) {
            return new AnInteger(source);
        }

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

SomeIntegers:

public class SomeIntegers implements Parcelable {
    private ArrayList<AnInteger> c_values;

    public SomeIntegers() {
        c_values = new ArrayList<>();
        c_values.add(new AnInteger(1));
        c_values.add(new AnInteger(2));
        c_values.add(new AnInteger(3));
        c_values.add(new AnInteger(4));
        c_values.add(new AnInteger(29));
        c_values.add(new AnInteger(30));
    }

    public String report() {
        String g = "";
        for (AnInteger ai : c_values) {
            if (!g.isEmpty()) {
                g = g + ", ";
            }
            g = g + ai.getC_value();
        }
        return (g.isEmpty() ? "Empty" : g);
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(this.c_values);
    }

    protected SomeIntegers(Parcel in) {
        this.c_values = in.createTypedArrayList(AnInteger.CREATOR);
    }

    public static final Parcelable.Creator<SomeIntegers> CREATOR = new Parcelable.Creator<SomeIntegers>() {
        @Override
        public SomeIntegers createFromParcel(Parcel source) {
            return new SomeIntegers(source);
        }

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

然后在您的活动中保存和恢复变得非常简单,以下是使用您当前数据模型的示例:

//set up class fields/members
private final static String STATE_G_VALS = "STATE_G_VALS";
SomeIntegers g_values = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test_bundle);
    System.out.println("onCreate (" + (savedInstanceState == null ? "null)" : "set)"));
    if (savedInstanceState != null) {
        // get g_values back here
        g_values = savedInstanceState.getParcelable(STATE_G_VALS);
    }

    if (g_values == null) {
        // ok its null, lets make one
        g_values = new SomeIntegers();
    }
    // log some stuff
    String result = g_values.report();
    System.out.println("Result: " + result);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
    //set g_values to the Bundle/saved state (even if it is null)
    outState.putParcelable(STATE_G_VALS, g_values);
    super.onSaveInstanceState(outState);
}