我正在编写一款可帮助小孩学习数学的Android应用。用户可以选择一些问题选项并回答问题。如果他/她正确回答所有这些,他/她可以获得奖品。每个问题选项都有不同的奖品。有22种不同的问题选择。我在网上发现了22张图片并将它们放入我的drawable文件夹中。然后我写了一个充满地图的类,叫做QuestionOptionMaps
。在这里,希望你知道我想在这里做什么:
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);
我真的不明白为什么会这样。其他应用程序有更多的图像,为什么他们不崩溃?有没有办法解决这个问题?
答案 0 :(得分:3)
在清单文件的android:largeHeap="true"
标记中添加application
。
再试一次。
但不推荐这种方式。看看以下帖子。
答案 1 :(得分:1)
我认为你的drawables分辨率更高。您必须降低其分辨率,或者您可以使用以下备用解决方案
<application
....
android:largeHeap="true">
实际上android:largeHeap
是增加分配内存到app的工具。
没有明确定义使用此标志的必要性。如果您需要更多内存 - Android为您提供了增加内存的工具。但是使用的必要性,你定义自己。
来自Android文档:
是否应该使用大型创建应用程序的进程 达尔维克堆。这适用于为此创建的所有进程 应用。它只适用于第一个加载到的应用程序 处理;如果您使用共享用户ID来允许多个 要使用进程的应用程序,它们都必须使用此选项 一直或他们将有不可预测的结果。
大多数应用程序不应该需要这个,而应该专注于减少 它们的整体内存使用率以提高性能。启用此功能 也不保证可用内存的固定增加,因为 某些设备受其总可用内存的限制。
要在运行时查询可用内存大小,请使用这些方法 getMemoryClass()或getLargeMemoryClass()。
<强>缺点:强>
在所有情况下都不建议使用largeHeap,请非常小心地使用它,它可能会减慢其他正在运行的应用程序,并且还会影响应用程序的反应性,因为垃圾收集器会被更频繁地请求。有关详细信息,请查看Google i / o Link
中的此演讲我希望它会对你有所帮助。