我的应用程序正在模拟器上运行并完全运行,但在物理设备上崩溃

Posted

技术标签:

【中文标题】我的应用程序正在模拟器上运行并完全运行,但在物理设备上崩溃【英文标题】:My application is running and working fully on the Emulator, but crashing on a physical device 【发布时间】:2019-10-07 09:03:18 【问题描述】:

你们能帮我解决我的问题吗?我的程序在 android Studio Emulator(Pixel 2 API 28)上运行没有问题,但是在我将它安装到我的手机(Samsung Galaxy S8+ API 28)上之后,每次我点击播放按钮时它都会继续崩溃:(。我在一些手机上也试过了,我仍然有同样的问题

实际上这不是我的程序,但我在 youtube 上找到了它,但是在 youtube 中制作代码的人给了我在我的学期项目中使用它的绿灯。

关于如何在 youtube 中制作该程序的视频链接:

https://www.youtube.com/watch?v=5W3rVBDYFjE

这是你可以运行的源代码链接:

https://github.com/heyletscode/2D-Game-In-Android-Studio

我只想在物理设备上运行此代码,尤其是在我的手机三星 Galaxy S8+ 上。我似乎无法解决我有点绝望的问题。我对 Java 编程很陌生,非常抱歉。

@Marc 要求的 com.heyletscode.ihavetofly.Flight 类的代码


int toShoot = 0;
boolean isGoingUp = false;
int x, y, width, height, wingCounter = 0, shootCounter = 1;
Bitmap flight1, flight2, shoot1, shoot2, shoot3, shoot4, shoot5, dead;
private GameView gameView;

Flight(GameView gameView, int screenY, Resources res) 

    this.gameView = gameView;

    flight1 = BitmapFactory.decodeResource(res, R.drawable.fly1);
    flight2 = BitmapFactory.decodeResource(res, R.drawable.fly2);

    width = flight1.getWidth();
    height = flight1.getHeight();

    width /= 4;
    height /= 4;

    width *= (int) screenRatioX;
    height *= (int) screenRatioY;

    flight1 = Bitmap.createScaledBitmap(flight1, width, height, false);
    flight2 = Bitmap.createScaledBitmap(flight2, width, height, false);

    shoot1 = BitmapFactory.decodeResource(res, R.drawable.shoot1);
    shoot2 = BitmapFactory.decodeResource(res, R.drawable.shoot2);
    shoot3 = BitmapFactory.decodeResource(res, R.drawable.shoot3);
    shoot4 = BitmapFactory.decodeResource(res, R.drawable.shoot4);
    shoot5 = BitmapFactory.decodeResource(res, R.drawable.shoot5);

    shoot1 = Bitmap.createScaledBitmap(shoot1, width, height, false);
    shoot2 = Bitmap.createScaledBitmap(shoot2, width, height, false);
    shoot3 = Bitmap.createScaledBitmap(shoot3, width, height, false);
    shoot4 = Bitmap.createScaledBitmap(shoot4, width, height, false);
    shoot5 = Bitmap.createScaledBitmap(shoot5, width, height, false);

    dead = BitmapFactory.decodeResource(res, R.drawable.dead);
    dead = Bitmap.createScaledBitmap(dead, width, height, false);

    y = screenY / 2;
    x = (int) (64 * screenRatioX);



Bitmap getFlight() 

    if (toShoot != 0) 

        if (shootCounter == 1) 
            shootCounter++;
            return shoot1;
        

        if (shootCounter == 2) 
            shootCounter++;
            return shoot2;
        

        if (shootCounter == 3) 
            shootCounter++;
            return shoot3;
        

        if (shootCounter == 4) 
            shootCounter++;
            return shoot4;
        

        shootCounter = 1;
        toShoot--;
        gameView.newBullet();

        return shoot5;
    

    if (wingCounter == 0) 
        wingCounter++;
        return flight1;
    
    wingCounter--;

    return flight2;


Rect getCollisionShape() 
    return new Rect(x, y, x + width, y + height);


Bitmap getDead() 
    return dead;



-----------已编辑------------


GameView.java 代码

private Thread thread;
private boolean isPlaying, isGameOver = false;
private int screenX, screenY, score = 0;
public static float screenRatioX, screenRatioY;
private Paint paint;
private Bird[] birds;
private SharedPreferences prefs;
private Random random;
private SoundPool soundPool;
private List<Bullet> bullets;
private int sound;
private Flight flight;
private GameActivity activity;
private Background background1, background2;

public GameView(GameActivity activity, int screenX, int screenY) 
    super(activity);

    this.activity = activity;

    prefs = activity.getSharedPreferences("game", Context.MODE_PRIVATE);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 

        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .setUsage(AudioAttributes.USAGE_GAME)
                .build();

        soundPool = new SoundPool.Builder()
                .setAudioAttributes(audioAttributes)
                .build();

     else
        soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);

    sound = soundPool.load(activity, R.raw.shoot, 1);

    this.screenX = screenX;
    this.screenY = screenY;
    screenRatioX = 1920f / screenX;
    screenRatioY = 1080f / screenY;

    background1 = new Background(screenX, screenY, getResources());
    background2 = new Background(screenX, screenY, getResources());

    flight = new Flight(this, screenY, getResources());

    bullets = new ArrayList<>();

    background2.x = screenX;

    paint = new Paint();
    paint.setTextSize(128);
    paint.setColor(Color.WHITE);

    birds = new Bird[4];

    for (int i = 0;i < 4;i++) 

        Bird bird = new Bird(getResources());
        birds[i] = bird;

    

    random = new Random();



@Override
public void run() 

    while (isPlaying) 

        update ();
        draw ();
        sleep ();

    



private void update () 

    background1.x -= 10 * screenRatioX;
    background2.x -= 10 * screenRatioX;

    if (background1.x + background1.background.getWidth() < 0) 
        background1.x = screenX;
    

    if (background2.x + background2.background.getWidth() < 0) 
        background2.x = screenX;
    

    if (flight.isGoingUp)
        flight.y -= 30 * screenRatioY;
    else
        flight.y += 30 * screenRatioY;

    if (flight.y < 0)
        flight.y = 0;

    if (flight.y >= screenY - flight.height)
        flight.y = screenY - flight.height;

    List<Bullet> trash = new ArrayList<>();

    for (Bullet bullet : bullets) 

        if (bullet.x > screenX)
            trash.add(bullet);

        bullet.x += 50 * screenRatioX;

        for (Bird bird : birds) 

            if (Rect.intersects(bird.getCollisionShape(),
                    bullet.getCollisionShape())) 

                score++;
                bird.x = -500;
                bullet.x = screenX + 500;
                bird.wasShot = true;

            

        

    

    for (Bullet bullet : trash)
        bullets.remove(bullet);

    for (Bird bird : birds) 

        bird.x -= bird.speed;

        if (bird.x + bird.width < 0) 

            if (!bird.wasShot) 
                isGameOver = true;
                return;
            

            int bound = (int) (30 * screenRatioX);
            bird.speed = random.nextInt(bound);

            if (bird.speed < 10 * screenRatioX)
                bird.speed = (int) (10 * screenRatioX);

            bird.x = screenX;
            bird.y = random.nextInt(screenY - bird.height);

            bird.wasShot = false;
        

        if (Rect.intersects(bird.getCollisionShape(), flight.getCollisionShape())) 

            isGameOver = true;
            return;
        

    



private void draw () 

    if (getHolder().getSurface().isValid()) 

        Canvas canvas = getHolder().lockCanvas();
        canvas.drawBitmap(background1.background, background1.x, background1.y, paint);
        canvas.drawBitmap(background2.background, background2.x, background2.y, paint);

        for (Bird bird : birds)
            canvas.drawBitmap(bird.getBird(), bird.x, bird.y, paint);

        canvas.drawText(score + "", screenX / 2f, 164, paint);

        if (isGameOver) 
            isPlaying = false;
            canvas.drawBitmap(flight.getDead(), flight.x, flight.y, paint);
            getHolder().unlockCanvasAndPost(canvas);
            saveIfHighScore();
            waitBeforeExiting ();
            return;
        

        canvas.drawBitmap(flight.getFlight(), flight.x, flight.y, paint);

        for (Bullet bullet : bullets)
            canvas.drawBitmap(bullet.bullet, bullet.x, bullet.y, paint);

        getHolder().unlockCanvasAndPost(canvas);

    



private void waitBeforeExiting() 

    try 
        Thread.sleep(3000);
        activity.startActivity(new Intent(activity, MainActivity.class));
        activity.finish();
     catch (InterruptedException e) 
        e.printStackTrace();
    



private void saveIfHighScore() 

    if (prefs.getInt("highscore", 0) < score) 
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt("highscore", score);
        editor.apply();
    



private void sleep () 
    try 
        Thread.sleep(17);
     catch (InterruptedException e) 
        e.printStackTrace();
    


public void resume () 

    isPlaying = true;
    thread = new Thread(this);
    thread.start();



public void pause () 

    try 
        isPlaying = false;
        thread.join();
     catch (InterruptedException e) 
        e.printStackTrace();
    



@Override
public boolean onTouchEvent(MotionEvent event) 

    switch (event.getAction()) 
        case MotionEvent.ACTION_DOWN:
            if (event.getX() < screenX / 2) 
                flight.isGoingUp = true;
            
            break;
        case MotionEvent.ACTION_UP:
            flight.isGoingUp = false;
            if (event.getX() > screenX / 2)
                flight.toShoot++;
            break;
    

    return true;


public void newBullet() 

    if (!prefs.getBoolean("isMute", false))
        soundPool.play(sound, 1, 1, 0, 0, 1);

    Bullet bullet = new Bullet(getResources());
    bullet.x = flight.x + flight.width;
    bullet.y = flight.y + (flight.height / 2);
    bullets.add(bullet);



这是在我的三星 Galaxy S8+ 上安装并点击程序上的播放按钮后出现的 Logcat on Error 选项卡


2019-10-07 16:59:12.317 11879-11879/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-10-07 16:59:12.322 11879-11879/? E/Zygote: accessInfo : 1
2019-10-07 16:59:21.447 11879-11879/com.heyletscode.ihavetofly E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.heyletscode.ihavetofly, PID: 11879
    java.lang.RuntimeException: Unable to start activity ComponentInfocom.heyletscode.ihavetofly/com.heyletscode.ihavetofly.GameActivity: java.lang.IllegalArgumentException: width and height must be > 0
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7050)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
     Caused by: java.lang.IllegalArgumentException: width and height must be > 0
        at android.graphics.Bitmap.createBitmap(Bitmap.java:1074)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:1041)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:991)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:912)
        at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:782)
        at com.heyletscode.ihavetofly.Flight.<init>(Flight.java:35)
        at com.heyletscode.ihavetofly.GameView.<init>(GameView.java:70)
        at com.heyletscode.ihavetofly.GameActivity.onCreate(GameActivity.java:22)
        at android.app.Activity.performCreate(Activity.java:7327)
        at android.app.Activity.performCreate(Activity.java:7318)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7050) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

【问题讨论】:

发布您尝试过的代码。 用 logcat 发布一些代码 你试过这个解决方案吗? ***.com/questions/17605662/… 如果是,请发布您的代码。 public void dispatchMessage(@NonNull Message msg) if (msg.callback != null) handleCallback(msg); else if (mCallback != null) if (mCallback.handleMessage(msg)) return; 处理消息(味精);这是 Handler.java 中代码的一部分 这段代码中有很多“(@NonNull Message msg)”消息,它们都说“'android.annotation.NonNull'在'android.annotation'中是不公开的。注释'。无法从外部包访问“ 它与位图或ImageView有关,您尝试过这种解决方案吗? ***.com/questions/17605662/… 【参考方案1】:

实际问题出在 GameView.java:64 中,其中使用了固定的屏幕高度和宽度,而不是动态的。此代码在屏幕低于或等于 1920x1080 像素的设备上运行流畅。

当屏幕尺寸超过 screenRatioXscreenRatioY 时会导致问题 Flight.java:32 中变为 o strong> 通过强制转换,导致异常为

宽度和高度必须 > 0

要使用动态屏幕尺寸,您可以使用:

 Display display = getWindowManager().getDefaultDisplay();
 Point size = new Point();
 display.getSize(size);

分别使用 size.x 和 size.y 而不是 1920f 和 1080f。谢谢

【讨论】:

我有点明白这确实是 Asaduzzaman 先生的问题,我应该在哪里找到替换它的类/代码?我把 GameView.java 供你参考兄弟。我只是一个java初学者真的很抱歉 显示显示 = getWindowManager().getDefaultDisplay();点大小 = new Point(); display.getSize(大小); this.screenX = screenX; this.screenY = screenY; screenRatioX = size.x / screenX; screenRatioY = size.y / screenY;我尝试将它放在 GameView.java 上,但它显示“无法解析方法 'getWindowManager()'。它是红色字体 使用activity.getWindowManager().getDefaultDisplay(); :) 先生。 Asaduzzaman 我真的不知道该怎样感谢你。如果没有你,我不知道我会怎么做。非常感谢上帝保佑你!你真的帮了我很多:) 欣赏它。 欢迎@KennethQuilantang,祝你好运。

以上是关于我的应用程序正在模拟器上运行并完全运行,但在物理设备上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 无法在物理设备上加载图像资产(但在模拟器上加载它就好了)

无法在物理设备上获取联系人-iOS

Xamarin表单,在Visual Studio Android Emulator上运行的应用程序但在真实设备上崩溃

应用程序在模拟器中运行良好,但在 iphone 中崩溃

Flutter Web 不显示 Firebase 存储中的 NetworkImages,但在 android 模拟器上完美运行

Android模拟器的三星系统映像?