我的应用程序一直在崩溃,我无法理解它的错误,到处寻找答案,据我所知,人们说是因为设备内存不足,我不明白是什么原因造成的?
如果问题是上述问题之一,解决方案是什么?把图像放在assets文件夹中还是什么?下面是错误堆栈。 谢谢。
MainActivity.java
public class MainActivity extends Activity {
Class <? extends Activity> classVariable;
int last_level;
TextView text_play, text_level, game_title;
RelativeLayout playBtn, levelBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playBtn = (RelativeLayout) findViewById(R.id.playBtn);
levelBtn = (RelativeLayout) findViewById(R.id.levelBtn);
game_title = (TextView) findViewById(R.id.game_title);
text_play = (TextView) findViewById(R.id.text_play);
text_level = (TextView) findViewById(R.id.text_level);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/snap-itc.ttf");
text_play.setTypeface(tf);
text_level.setTypeface(tf);
game_title.setTypeface(tf);
// Check if file exists
File file = getBaseContext().getFileStreamPath("levels.json");
if (file.exists()) {
// Get the JSON Object from the data
JSONObject parent = this.parseJSONData();
try {
last_level = parent.getInt("level");
} catch (JSONException e) {
e.printStackTrace();
}
}
switch (last_level) {
case 1:
classVariable = Level002Activity.class;
break;
case 2:
classVariable = Level003Activity.class;
break;
case 3:
classVariable = Level004Activity.class;
break;
case 5:
classVariable = Level005Activity.class;
break;
default:
classVariable = Level001Activity.class;
}
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),
Level002Activity.class);
startActivity(i);
}
});
levelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent in = new Intent(getApplicationContext(),
Level001Activity.class);
startActivity(in);
}
});
}
public JSONObject parseJSONData() {
String JSONString = null;
JSONObject jsonObject = null;
try {
// Open the inputStream to the file
FileInputStream fin = openFileInput("levels.json");
int sizeOfJSONFile = fin.available();
// array that will store all the data
byte[] bytes = new byte[sizeOfJSONFile];
// reading data into the array from the file
fin.read(bytes);
// close the input stream
fin.close();
JSONString = new String(bytes, "UTF-8");
jsonObject = new JSONObject(JSONString);
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (JSONException x) {
x.printStackTrace();
return null;
}
return jsonObject;
}
}
调用ChooseLevelActivity.class
时会一直显示错误ChooseLevelActivity.java
public class ChooseLevelActivity extends Activity implements View.OnClickListener {
ImageView level001, level002, level003, level004, level005;
int last_level, best_move;
String best_time, level_selected;
TextView levelName, bestMove, bestTime;
Class <? extends Activity> classVariable;
Button playBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.choose_level);
level001 = (ImageView) findViewById(R.id.level001);
level002 = (ImageView) findViewById(R.id.level002);
level003 = (ImageView) findViewById(R.id.level003);
level004 = (ImageView) findViewById(R.id.level004);
level005 = (ImageView) findViewById(R.id.level005);
levelName = (TextView) findViewById(R.id.level_name);
bestMove = (TextView) findViewById(R.id.best_move);
bestTime = (TextView) findViewById(R.id.best_time);
playBtn = (Button) findViewById(R.id.playBtn);
// Get the JSON Object from the data
JSONObject parent = parseJSONData("levels.json");
// Array of ImageView
final ImageView[] levelsArray = {level001, level002, level003, level004, level005};
// This will store all the values inside "best_move and time" in an element string
try {
last_level = parent.getInt("level");
} catch (JSONException e) {
e.printStackTrace();
}
for(int i = 0; i < last_level; i++) {
levelsArray[i].setVisibility(View.VISIBLE);
levelsArray[i].setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.level001:
level_selected = "level001";
classVariable = Level001Activity.class;
break;
case R.id.level002:
level_selected = "level002";
classVariable = Level002Activity.class;
break;
case R.id.level003:
level_selected = "level003";
classVariable = Level003Activity.class;
break;
case R.id.level004:
level_selected = "level004";
classVariable = Level004Activity.class;
break;
case R.id.level005:
level_selected = "level005";
classVariable = Level005Activity.class;
break;
}
String fileName = "record_" + level_selected + ".json";
// Get the JSON Object from the data
JSONObject parents = parseJSONData(fileName);
// This will store all the values inside "best_move and time" in an element string
try {
best_move = parents.getInt("best_move");
best_time = parents.getString("best_time");
} catch (JSONException e) {
// e.printStackTrace();
}
levelName.setText("Level " + level_selected.substring(5));
bestMove.setText("Best Move: " + best_move);
bestTime.setText("Best Time: " + best_time);
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),
classVariable);
startActivity(i);
finish();
}
});
}
public JSONObject parseJSONData(String file) {
String JSONString = null;
JSONObject jsonObject = null;
try {
// Open the inputStream to the file
FileInputStream fin = openFileInput(file);
int sizeOfJSONFile = fin.available();
// array that will store all the data
byte[] bytes = new byte[sizeOfJSONFile];
// reading data into the array from the file
fin.read(bytes);
// close the input stream
fin.close();
JSONString = new String(bytes, "UTF-8");
jsonObject = new JSONObject(JSONString);
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (JSONException x) {
x.printStackTrace();
return null;
}
return jsonObject;
}
}
错误堆栈:
Process: com.example.ed.pieces, PID: 12939
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ed.pieces/com.example.ed.pieces.Level001Activity}: android.view.InflateException: Binary XML file line #289: Binary XML file line #289: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #289: Binary XML file line #289: Error inflating class <unknown>
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:393)
at android.app.Activity.setContentView(Activity.java:2166)
at com.example.ed.pieces.Level001Activity.onCreate(Level001Activity.java:62)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #289: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:645)
at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:393)
at android.app.Activity.setContentView(Activity.java:2166)
at com.example.ed.pieces.Level001Activity.onCreate(Level001Activity.java:62)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.view.LayoutInflater.createView(LayoutInflater.java:619)
at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 10240012 byte allocation with 4194304 free bytes and 7MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
at android.content.res.Resources.loadDrawable(Resources.java:2540)
at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
at android.view.View.<init>(View.java:3948)
at android.widget.ImageView.<init>(ImageView.java:145)
at android.widget.ImageView.<init>(ImageView.java:140)
at android.widget.ImageView.<init>(ImageView.java:136)
答案 0 :(得分:1)
内存不足错误
当您为处理多个图像集或大位图或某些动画内容的应用程序开发时,内存不足错误是非常常见的错误。在这种情况下,我们必须在处理图像或对象分配和释放时非常小心和高效。当分配超过堆限制或您的进程需要超过堆限制的内存量时,会出现OOM错误。
在Android中,每个应用程序都在Linux进程中运行。每个Linux进程都在其中运行虚拟机(Dalvik虚拟机)。进程可以要求的内存有一个限制,它对于不同的设备是不同的,并且对于手机和平板电脑也是不同的。当某个进程需要比其限制更高的内存时,会导致错误,即内存不足错误。
尝试这可以帮助您在清单文件中添加此标记。
android:largeHeap="true"
它将为您的应用分配大堆
要将Drawable转换为位图,请使用此
Drawable myDrawable = getResources().getDrawable(R.drawable.logo);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
使用此方法,您可以解码图像
public static Bitmap decodeImageFile(File f,int WIDTH,int HIGHT){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int REQUIRED_HIGHT=HIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
然后在使用此方法的地方调用此方法:
Bitmap b = decodeImageFile(f, 1280, 720);
答案 1 :(得分:0)
如果您的图像分辨率很高,我建议您使用缓冲区加载图像。
String defCoverPath = "drawable/" + "def_cover" + ".png";
yourView.setBackgroundDrawable(LoadResourceImage(defCoverPath));
public static BitmapDrawable LoadResourceImage(String resPath){
AssetManager assets = MyApp.GetContext().getResources().getAssets();
BitmapDrawable bitmapDrawable = new BitmapDrawable();
try {
InputStream buffer = new BufferedInputStream((assets.open(resPath)));
Bitmap bitmap = BitmapFactory.decodeStream(buffer);
bitmapDrawable = new BitmapDrawable(MyApp.GetContext().getResources(), bitmap);
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmapDrawable;
}