Хранить статические данные в Android - пользовательский ресурс?
Я новичок в разработке для Android, и я немного поиграл с этим. Я пытался создать программу, которая имеет небольшую коллекцию неизменяемых данных, похожую на базу данных. В C#, моем лучшем на данный момент языке, я бы использовал список пользовательских классов и сериализовал бы его в XML-файл, а затем считывал его в свое приложение во время выполнения. Я нашел папку ресурсов /xml в Android, но я не уверен, как мне поступить так, как я планирую. Каков наилучший способ сделать это?
Данные никогда не нужно будет менять. Пример:
Blob | A | B
----------------
Blob 1 | 23 | 42
Blob 2 | 34 | 21
Я знаю, что это похоже на таблицу, но использование базы данных не имеет для меня никакого смысла, потому что данные никогда не изменятся, и мне нужен был бы способ сохранить их для первоначального заполнения базы данных в любом случае.
Поэтому в основном я ищу способ хранения несколько сложных статических данных в моем приложении. Есть идеи?
РЕДАКТИРОВАТЬ: я также видел папку /raw. Так что я могу хранить вещи в /res/raw или /res/xml. Но я не уверен, что будет лучшим способом для хранения / анализа данных...
4 ответа
Лучший способ - использовать иерархию ресурсов Android.
В каталоге res/ values / вы можете хранить любое количество пар ключ-значение для нескольких основных типов данных. В вашем приложении вы можете ссылаться на них, используя автоматически сгенерированный идентификатор ресурса (имя, основанное на ключе вашего ресурса). Смотрите ссылку выше для получения дополнительной документации и деталей.
Android также поддерживает необработанные файлы данных. Вы можете хранить свои данные в файловой директории в res/ raw / yourfile.dat
Вы создаете свои данные в любом текстовом формате, который хотите, а затем читаете их при запуске активности, используя apis доступа к ресурсам.
Я думаю, что это ЛУЧШЕЕ решение, и я уже использую это для хранения статических данных в каждом своем проекте.
Для этого... Вы можете сделать одну вещь, сделать один 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 для анализа данных. Вы можете иметь примеры кодирования техники PullParsing в Примере, обратитесь к этому примеру для лучшей идеи.
Наслаждаться!!
Согласно документу, /xml
это путь
xml/
Произвольные файлы XML, которые можно прочитать во время выполнения, вызвав
Resources.getXML().
Различные файлы конфигурации XML должны быть сохранены здесь, такие как конфигурация с возможностью поиска.
Документация дляgetXML()
Я также сделал рабочий пример:
структура 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(); }
Я использовал Simple для разбора XML в прошлом. Я думаю, что он имеет наименьшее количество кода, если вы знаете, чего ожидать в XML, что в вашем случае вы делаете.