Androidに静的データを保存 - カスタムリソース?
-
02-10-2019 - |
質問
私はAndroid Developmentを初めて使用しており、少し遊んでいます。私は、変化することのないデータの小さなデータベースのようなコレクションを持つプログラムを作成しようとしていました。現在最高の言語であるC#では、カスタムクラスのリストを使用して、それをXMLファイルにシリアル化し、それを実行時にアプリケーションに読み込みます。 Androidで /XMLリソースフォルダーを見つけましたが、自分が想像していることをどのようにやろうとしているのかわかりません。これを行うための最良の方法は何でしょうか?
データを変更する必要はありません。例:
Blob | A | B
----------------
Blob 1 | 23 | 42
Blob 2 | 34 | 21
私はそれがテーブルのようにレイアウトされていることを知っていますが、データベースを使用することは私にとって本当に意味がありません。 とりあえず.
基本的に、アプリケーションにやや複雑な静的データを保存する方法を探しています。何か案は?
編集: /rawフォルダーも見ました。そのため、 /res /rawまたは /res /xmlに物を保存できます。しかし、データを保存/解析する最良の方法が何であるかわかりません...
解決
最良の方法は、を使用することです Android Resource Heirarchy.
RES/値/ディレクトリでは、いくつかの基本的なデータ型に任意の数のキー価値ペアを保存できます。アプリでは、自動生成リソースID(リソースのキーに基づく名前)を使用してそれらを参照します。詳細と詳細については、上記のリンクを参照してください。
Androidは生データファイルもサポートしています。データをres/raw/yourfile.datの下にファイルディレクトリに保存できます
必要なテキストベースの形式でデータを作成し、リソースアクセスAPIを使用してアクティビティスタートアップで読み取ります。
他のヒント
これが最良のソリューションであると思います。私はすでにこれを使用して、すべてのプロジェクトに静的データを保存しています。
そのために... 1つのことを行い、1つの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プルパーサー データを解析する手法。プルパッシングテクニックのコーディングサンプルをオンにすることができます 例 , 、より良いアイデアについては、この例を参照してください。
楽しみ!!
私は過去にXML解析にSimpleを使用しました。 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(); }