将静态数据存储在Android-自定义资源中?
-
02-10-2019 - |
题
我是Android开发的新手,而且我一直在玩它。我试图创建一个程序,该程序具有一个类似于数据库的小数据库的收藏。在我当前最好的语言C#中,我将使用自定义类的列表并将其序列化到XML文件,然后在运行时将其阅读到我的应用程序中。我在Android中找到了 /XML资源文件夹,但是我不确定如何做自己想象的事情。这样做的最好方法是什么?
数据将永远不需要更改。例子:
Blob | A | B
----------------
Blob 1 | 23 | 42
Blob 2 | 34 | 21
我知道这是像表一样布置的,但是使用数据库对我来说并没有任何意义,因为数据永远不会更改,我需要一种存储它的方法才能最初填充数据库 反正.
因此,基本上,我正在寻找一种在我的应用程序中存储一些复杂数据的方法。有任何想法吗?
编辑:我还看到了 /原始文件夹。因此,我可以将物品存储在 /res /raw或 /res /xml中。但是我不确定是存储/解析数据的最佳方法是什么?
解决方案
最好的方法是使用 Android Resource Heirarchy.
在RES/值/目录中,您可以为几种基本数据类型存储任意数量的键值对。在您的应用程序中,您将使用自动化资源ID(基于资源的密钥的名称)参考它们。有关更多文档和详细信息,请参见上面的链接。
Android还支持原始数据文件。您可以将数据存储在res/raw/yourfile.dat下的文件目录中
您以任何需要的基于文本的格式创建数据,然后使用资源访问API在活动启动上阅读它。
其他提示
我认为这是最好的解决方案,我已经在使用此项目将静态数据存储在我的每个项目中。
为此...您可以做一件事,制作一个XML文件,即“ temp.xml” ..并将数据存储在temp.xml中:
<?xml version="1.0" encoding="utf-8"?>
<rootelement1>
<subelement> Blob 1
<subsubelement> 23 </subsubelement>
<subsubelement> 42 </subsubelement>
</subelement>
<subelement>Blob 2
<subsubelement> 34 </subsubelement>
<subsubelement> 21 </subsubelement>
</subelement>
</rootelement1>
然后使用 XML Pullparser 解析数据的技术。您可以在上面有plapparsing技术的编码样品 例子 , ,请参阅此示例以获取更好的想法。
享受!!
我过去曾经用简单的XML解析。我认为,如果您知道在XML中会发生什么,那么它的代码数量最少,在您的情况下。
根据 Doc, /xml
是要走的路。
xml/
可以通过调用可以在运行时读取的任意XML文件
Resources.getXML().
必须在此处保存各种XML配置文件,例如可搜索的配置。
我还做了一个工作示例:
XML结构:
<?xml version="1.0" encoding="utf-8"?> <quizquestions> <quizquestion> <header_image_src>ic_help_black_24dp</header_image_src> <question>What is the Capital of U.S.A.?</question> <input_type>Radio</input_type> <answer correct="false">New York City</answer> <answer correct="true">Washington D.C.</answer> <answer correct="false">Chicago</answer> <answer correct="false">Philadelphia</answer> </quizquestion> <quizquestion> <header_image_src>ic_help_black_24dp</header_image_src> <question>What is the family name of the famous dutch painter Vincent Willem van .... ?</question> <input_type>EditText</input_type> <answer correct="true">Gogh</answer> </quizquestion> </quizquestions>
Java类保存数据:
public class QuizQuestion { private int headerImageResId; private String question; private String inputType; private ArrayList<String> answers; private ArrayList<Boolean> answerIsCorrect; private ArrayList<Integer> correctAnswerIndexes; /** * constructor for QuizQuestion object */ QuizQuestion() { headerImageResId = 0; question = null; inputType = null; answers = new ArrayList<>(); answerIsCorrect = new ArrayList<>(); correctAnswerIndexes = new ArrayList<>(); } public void setHeaderImageResId(int headerImageResId) { this.headerImageResId = headerImageResId; } public int getHeaderImageResId() { return headerImageResId; } void setQuestion(String question) { this.question = question; } public String getQuestion() { return question; } void setInputType(String inputType) { this.inputType = inputType; } public String getInputType() { return inputType; } void addAnswer(String answer, boolean isCorrect) { if (isCorrect) correctAnswerIndexes.add(answers.size()); answers.add(answer); answerIsCorrect.add(isCorrect); } public ArrayList<String> getAnswers() { return answers; } public String getAnswer(int index) { // check index to avoid out of bounds exception if (index < answers.size()) { return answers.get(index); } else { return null; } } public int size() { return answers.size(); } }
解析器本身:
/** * Created by bivanbi on 2017.02.23.. * * class to parse xml resource containing quiz data into ArrayList of QuizQuestion objects * */ public class QuizXmlParser { public static String lastErrorMessage = ""; /** * static method to parse XML data into ArrayList of QuizQuestion objects * @param activity is the calling activity * @param xmlResourceId is the resource id of XML resource to be parsed * @return null if parse error is occurred or ArrayList of objects if successful * @throws XmlPullParserException * @throws IOException */ public static ArrayList<QuizQuestion> parse(Activity activity, int xmlResourceId) throws XmlPullParserException, IOException { String logTag = QuizXmlParser.class.getSimpleName(); Resources res = activity.getResources(); XmlResourceParser quizDataXmlParser = res.getXml(R.xml.quiz_data); ArrayList<String> xmlTagStack = new ArrayList<>(); ArrayList<QuizQuestion> quizQuestions = new ArrayList<>(); QuizQuestion currentQuestion = null; boolean isCurrentAnswerCorrect = false; quizDataXmlParser.next(); int eventType = quizDataXmlParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { // begin document if(eventType == XmlPullParser.START_DOCUMENT) { Log.d(logTag,"Begin Document"); } // begin tag else if(eventType == XmlPullParser.START_TAG) { String tagName = quizDataXmlParser.getName(); xmlTagStack.add(tagName); Log.d(logTag,"Begin Tag "+tagName+", depth: "+xmlTagStack.size()); Log.d(logTag,"Tag "+tagName+" has "+quizDataXmlParser.getAttributeCount()+" attribute(s)"); // this is a beginning of a quiz question tag so create a new QuizQuestion object if (tagName.equals("quizquestion")){ currentQuestion = new QuizQuestion(); } else if(tagName.equals("answer")) { isCurrentAnswerCorrect = quizDataXmlParser.getAttributeBooleanValue(null,"correct",false); if (isCurrentAnswerCorrect == true) { Log.d(logTag, "Tag " + tagName + " has attribute correct = true"); } else { Log.d(logTag, "Tag " + tagName + " has attribute correct = false"); } } } // end tag else if(eventType == XmlPullParser.END_TAG) { String tagName = quizDataXmlParser.getName(); if (xmlTagStack.size() < 1) { lastErrorMessage = "Error 101: encountered END_TAG "+quizDataXmlParser.getName()+" while TagStack is empty"; Log.e(logTag, lastErrorMessage); return null; } xmlTagStack.remove(xmlTagStack.size()-1); Log.d(logTag,"End Tag "+quizDataXmlParser.getName()+", depth: "+xmlTagStack.size()); // reached the end of a quizquestion definition, add it to the array if (tagName.equals("quizquestion")){ if (currentQuestion != null) quizQuestions.add(currentQuestion); currentQuestion = null; } } // text between tag begin and end else if(eventType == XmlPullParser.TEXT) { String currentTag = xmlTagStack.get(xmlTagStack.size()-1); String text = quizDataXmlParser.getText(); Log.d(logTag,"Text: "+text+", current tag: "+currentTag+", depth: "+xmlTagStack.size()); if (currentQuestion == null) { Log.e(logTag,"currentQuestion is not initialized! text: "+text+", current tag: "+currentTag+", depth: "+xmlTagStack.size()); continue; } if (currentTag.equals("header_image_src")) { int drawableResourceId = activity.getResources().getIdentifier(text, "drawable", activity.getPackageName()); currentQuestion.setHeaderImageResId(drawableResourceId); } else if (currentTag.equals("question")) { currentQuestion.setQuestion(text); } else if (currentTag.equals("answer")) { currentQuestion.addAnswer(text, isCurrentAnswerCorrect); } else if (currentTag.equals("input_type")) { currentQuestion.setInputType(text); } else { Log.e(logTag,"Unexpected tag "+currentTag+" with text: "+text+", depth: "+xmlTagStack.size()); } } eventType = quizDataXmlParser.next(); } Log.d(logTag,"End Document"); return quizQuestions; } }
最后,称解析器:
// read quiz data from xml resource quiz_data try { quizQuestions = QuizXmlParser.parse(this,R.xml.quiz_data); Log.d("Main","QuizQuestions: "+quizQuestions); } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); quizQuestions = null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); quizQuestions = null; } if (quizQuestions == null) { Toast.makeText(this,"1001 Failed to parse Quiz XML, sorry", Toast.LENGTH_LONG).show(); finish(); }