我正在寫一個Android應用程序,幫助小孩學數學。用戶可以選擇一些問題選項並回答問題。如果他/她正確回答所有問題,他/她可以獲得獎勵。每個問題選項都有不同的獎勵。有22個不同的問題選項。我在網上找到了22張圖片,並將它們放在我的可繪製文件夾中。然後,我寫了一個充滿地圖的課程,名爲QuestionOptionMaps
。在這裏,希望你知道我想在這裏做什麼:我只是加載22個drawable,爲什麼OutOfMemoryError?
package com.smartkidslovemaths.util;
import com.smartkidslovemaths.QuestionOptions;
import com.smartkidslovemaths.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
public class QuestionOptionMaps {
private QuestionOptionMaps() {}
public static ArrayList<QuestionOptions> getOptionsList() {
return optionsList;
}
public static HashMap<QuestionOptions, Integer> getOptionsDrawableMap() {
return optionsDrawableMap;
}
public static HashMap<QuestionOptions, String> getOptionsKeysMap() {
return optionsKeysMap;
}
public static HashMap<QuestionOptions, Integer> getOptionsTimerMap() {
return optionsTimerMap;
}
private static ArrayList<QuestionOptions> optionsList;
private static HashMap<QuestionOptions, Integer> optionsDrawableMap;
private static HashMap<QuestionOptions, String> optionsKeysMap;
private static HashMap<QuestionOptions, Integer> optionsTimerMap;
static {
optionsList = new ArrayList<>();
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 1, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 2, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 3, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 1, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 2, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADDITION, 3, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 1, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 2, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 3, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 1, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 2, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.SUBTRACTION, 3, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 1, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 2, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 3, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 1, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 2, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.ADD_AND_SUB, 3, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.MULTIPLICATION, 1, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.MULTIPLICATION, 2, false));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.MULTIPLICATION, 1, true));
optionsList.add (new QuestionOptions (QuestionOptions.OperationType.MULTIPLICATION, 2, true));
ArrayList<String> prefKeyArray = new ArrayList<>();
prefKeyArray.add ("p110");
prefKeyArray.add ("p120");
prefKeyArray.add ("p130");
prefKeyArray.add ("p111");
prefKeyArray.add ("p121");
prefKeyArray.add ("p131");
prefKeyArray.add ("p210");
prefKeyArray.add ("p220");
prefKeyArray.add ("p230");
prefKeyArray.add ("p211");
prefKeyArray.add ("p221");
prefKeyArray.add ("p231");
prefKeyArray.add ("p310");
prefKeyArray.add ("p320");
prefKeyArray.add ("p330");
prefKeyArray.add ("p311");
prefKeyArray.add ("p321");
prefKeyArray.add ("p331");
prefKeyArray.add ("p410");
prefKeyArray.add ("p420");
prefKeyArray.add ("p411");
prefKeyArray.add ("p421");
optionsKeysMap = getHashMapFromCollections (optionsList, prefKeyArray);
ArrayList<Integer> idArray = new ArrayList<>();
idArray.add (R.drawable.p110);
idArray.add (R.drawable.p120);
idArray.add (R.drawable.p130);
idArray.add (R.drawable.p111);
idArray.add (R.drawable.p121);
idArray.add (R.drawable.p131);
idArray.add (R.drawable.p210);
idArray.add (R.drawable.p220);
idArray.add (R.drawable.p230);
idArray.add (R.drawable.p211);
idArray.add (R.drawable.p221);
idArray.add (R.drawable.p231);
idArray.add (R.drawable.p310);
idArray.add (R.drawable.p320);
idArray.add (R.drawable.p330);
idArray.add (R.drawable.p311);
idArray.add (R.drawable.p321);
idArray.add (R.drawable.p331);
idArray.add (R.drawable.p410);
idArray.add (R.drawable.p420);
idArray.add (R.drawable.p411);
idArray.add (R.drawable.p421);
optionsDrawableMap = getHashMapFromCollections (optionsList, idArray);
//TODO initialize the collections
}
private static <K, V> HashMap<K, V> getHashMapFromCollections (Collection<K> keys, Collection<V> values) {
if (keys.size() != values.size())
throw new AssertionError();
HashMap<K, V> map = new HashMap<>();
K[] keyArray = (K[])keys.toArray();
V[] valueArray = (V[])values.toArray();
for (int i = 0 ; i < keys.size() ; i++) {
map.put (keyArray[i], valueArray[i]);
}
return map;
}
}
大部分是剛剛初始化地圖。我沒有初始化optionsTimer
地圖,因爲這是一個待辦事項。現在我創建了一個PrizeActivity
,顯示用戶獲得的所有獎品。它基本上顯示了你所有的獎品和金額。因爲有很多的獎品,我決定動態添加意見到ScrollView
。這裏是佈局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.smartkidslovemaths.PrizeActivity">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/trophy_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
這裏是我怎麼加的觀點:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_prize);
for (QuestionOptions option : QuestionOptionMaps.getOptionsList()) {
displayAPrize (option);
}
}
private void displayAPrize (QuestionOptions options) {
Resources res = getResources();
int parentMargin = (int)res.getDimension (R.dimen.prize_display_margin);
LinearLayout.LayoutParams parentParams =
new LinearLayout.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
parentParams.setMargins (parentMargin, parentMargin, parentMargin, parentMargin);
LinearLayout.LayoutParams imageParams =
new LinearLayout.LayoutParams (
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
);
LinearLayout parent = new LinearLayout (this);
parent.setLayoutParams (parentParams);
parent.setOrientation (LinearLayout.VERTICAL);
ImageView image = new ImageView (this);
image.setLayoutParams (imageParams);
int imageId = QuestionOptionMaps.getOptionsDrawableMap().get (options);
image.setImageResource (imageId);
parent.addView (image);
TextView text = new TextView (this);
text.setLayoutParams (imageParams);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (this);
String key = QuestionOptionMaps.getOptionsKeysMap().get (options);
int prizeCount = prefs.getInt (key, 0);
text.setText ("x" + prizeCount);
parent.addView (text);
((LinearLayout)findViewById (R.id.trophy_content)).addView (parent);
}
當我運行應用程序,它與OutOfMemoryError
崩潰!這裏是調用堆棧:
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:503)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:356)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:816)
at android.content.res.Resources.loadDrawable(Resources.java:2117)
at android.content.res.Resources.getDrawable(Resources.java:702)
at android.widget.ImageView.resolveUri(ImageView.java:636)
at android.widget.ImageView.setImageResource(ImageView.java:365)
at com.smartkidslovemaths.PrizeActivity.displayAPrize(PrizeActivity.java:46)
at com.smartkidslovemaths.PrizeActivity.onCreate(PrizeActivity.java:22)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
at android.app.ActivityThread.access$600(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
46號線是這一行:
image.setImageResource (imageId);
我真的不明白爲什麼會這樣。其他應用程序有更多的圖像,爲什麼他們不會崩潰?有沒有什麼辦法解決這一問題?
這也很重要的圖像是多大。 – Karakuri
@Karakuri他們總共有1.9 MB – Sweeper
再一次,圖像*文件*的大小沒有任何重要性。它們的尺寸只是很重要,因爲它定義了內存中位圖的大小 – njzk2