我发现了一些有同样错误的帖子。但是,他们都没有为我的问题提供有效的解决方案。
我有两个活动类,MainActivity和GameActivity。 MainActivity按下按钮启动GameActivity。如果我按下手机上的后退按钮,它将返回主要活动。但是,当我再次按下按钮以启动新的GameActivity时,系统会提示我指向代码行的错误
setContentView(R.layout.activity_game);
错误:
08-02 02:16:56.365 2220-2220/joseph.imbroglio E/AndroidRuntime: FATAL EXCEPTION: main
Process: joseph.imbroglio, PID: 2220
java.lang.RuntimeException: Unable to start activity ComponentInfo{joseph.imbroglio/joseph.imbroglio.GameActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2661)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:640)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:428)
at android.app.Activity.setContentView(Activity.java:2241)
at joseph.imbroglio.GameActivity.onCreate(GameActivity.java:30)
at android.app.Activity.performCreate(Activity.java:6221)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2614)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:614)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:428)
at android.app.Activity.setContentView(Activity.java:2241)
at joseph.imbroglio.GameActivity.onCreate(GameActivity.java:30)
at android.app.Activity.performCreate(Activity.java:6221)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2614)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 72000012 byte allocation with 16777216 free bytes and 65MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:575)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:605)
at joseph.imbroglio.Entity.<init>(Entity.java:42)
at joseph.imbroglio.Face.<init>(Face.java:13)
at joseph.imbroglio.GameView.init(GameView.java:67)
at joseph.imbroglio.GameView.<init>(GameView.java:52)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:614)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:428)
at android.app.Activity.setContentView(Activity.java:2241)
at joseph.imbroglio.GameActivity.onCreate(GameActivity.java:30)
at android.app.Activity.performCreate(Activity.java:6221)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2614)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
MainActivity的onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mainActivity = this;
playbtn = (ImageView) findViewById(R.id.imageView);
final Intent intent = new Intent(getBaseContext(), GameActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
playbtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
playbtn.setImageResource(R.drawable.playbutton2);
startActivity(intent);
getIntent().removeExtra("startTest");
return true;
}
});
}
GameActivity的onCreate方法:
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
gameView = (GameView)findViewById(R.id.gameView);
gameView.setGameActivity(this);
gameThread = new Thread(gameView);
gameThread.start();
MainActivity.resetButton();
}
activity_game XML文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="joseph.imbroglio.GameActivity"
android:layout_width="match_parent" android:layout_height="match_parent">
<joseph.imbroglio.GameView
android:id="@+id/gameView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/textView"
android:textSize="24sp"
android:textColor="?android:attr/colorBackground" />
</RelativeLayout>
该resetButton方法的代码:
public static void resetButton(){
playbtn.setImageResource(R.drawable.playbutton);
}
根据要求,这里是GameView类的代码:
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.util.ArrayList;
/**
* Created by root on 7/4/16.
*/
public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback{
protected Resources resources;
private SurfaceHolder holder;
protected ArrayList<Entity> entities = new ArrayList<Entity>();
private long lastUpdate = 0;
protected GameActivity ga;
private Background background;
private Player player;
private Face face;
private TileSet tileSet;
private ArrayList<Fruit> fruits = new ArrayList<Fruit>();
private boolean surfaceCreated = false;
private boolean hasActiveHolder = false;
private boolean touchingRight = false;
private boolean touchingLeft = false;
private int accel = getResources().getDisplayMetrics().widthPixels/25;
private Physics physics;
public GameView(Context context){
super(context);
init();
}
public GameView(Context context, AttributeSet attrs){
super(context, attrs);
init();
}
public GameView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
init();
}
public void init(){
//this.setBackgroundColor(Color.RED);
//setWillNotDraw(false);
resources = this.getResources();
holder = getHolder();
background = new Background(this, R.drawable.background, 1);
player = new Player(this, R.drawable.yellowtest, 4);
face = new Face(this, R.drawable.face, 8);
tileSet = new TileSet(this);
populateFruits();
entities.add(background);
entities.add(player);
entities.add(face);
entities.addAll(tileSet.getTiles());
entities.addAll(fruits);
holder.addCallback(this);
physics = new Physics(entities);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
if(motionEvent.getX() >= getResources().getDisplayMetrics().widthPixels/2){
touchingRight = true;
} else {
touchingLeft = true;
}
return true;
}
if(motionEvent.getAction() == MotionEvent.ACTION_UP){
touchingLeft=false;
touchingRight=false;
player.neutralize();
return true;
}
return false;
}
});
}
public void draw(){
synchronized (this) {
while(!hasActiveHolder){
try{
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Canvas canvas = holder.lockCanvas();
if(canvas != null) {
paintCanvas(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
}
public void paintCanvas(Canvas canvas){
for(Entity e : entities){
e.draw(canvas);
}
tileSet.tileDead(fruits);
tileSet.checkFell(player.pos);
player.animation1();
face.eat();
}
@Override
public void run() {
while(ga.playing){
if((System.currentTimeMillis() - lastUpdate) < 16){
try {
Thread.sleep(Math.abs(16 - (System.currentTimeMillis()-lastUpdate)));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(this.surfaceCreated) {
physics.update();
manage();
draw();
lastUpdate = System.currentTimeMillis();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
surfaceCreated = true;
synchronized (this) {
hasActiveHolder = true;
this.notifyAll();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
surfaceCreated=false;
synchronized (this){
hasActiveHolder = false;
synchronized(this){
this.notifyAll();
}
}
}
public int getPlayerX(){
return player.x;
}
public int getPlayerY(){
return player.y;
}
public Player getPlayer(){
return player;
}
public void manage(){
if(player.x > (getResources().getDisplayMetrics().widthPixels - player.width)){
player.x = getResources().getDisplayMetrics().widthPixels - player.width;
}
if(player.x < 0){
player.x = 0;
}
face.x = player.x;
//if((!touchingLeft) && (!touchingRight)){
//player.ax = 0;
//}
if(player.isAlive()) {
if (touchingRight) {
player.ax += accel;
}
if (touchingLeft) {
player.ax -= accel;
}
}
}
public void populateFruits(){
for(int i = 0; i < 20; i++){
fruits.add(new Fruit(this, R.drawable.fruit, 2, getResources().getDisplayMetrics().widthPixels/20, getResources().getDisplayMetrics().widthPixels/20));
}
}
public Face getFace(){
return face;
}
public void setGameActivity(GameActivity gl){
ga = gl;
}
}
有关此问题的任何意见?
答案 0 :(得分:0)
我认为您用于应用的图片尺寸可能不支持您的手机。尽量减少图像的大小。
答案 1 :(得分:0)
假设您的GameActivity
第一次正确启动,但在按BACK(返回MainActivity
)然后启动GameActivity
崩溃(由于OutOfMemory)后,可能意味着GameActivity
的原始实例结束时,您没有正确完成清理工作。
根据您发布的代码,您可能会发生内存泄漏。这段代码:
gameView = (GameView)findViewById(R.id.gameView);
gameView.setGameActivity(this);
gameThread = new Thread(gameView);
gameThread.start();
将对gameView
的引用传递给gameThread
。 gameView
引用了GameActivity
的实例。如果您在Thread
的实例关闭时未正确清除此GameActivity
,则垃圾收集器将无法回收旧的GameActivity
及其所有资源(包括您尝试启动第二个实例之前的图像)。您可以使用堆分析和堆调试工具来帮助您找到这样的内存泄漏。