Java Android:App在API23 / 22上非常慢,但在API19

时间:2017-03-28 15:38:58

标签: java android

我是Android开发和培训目的的初学者,我创建了一个简单的Android应用程序。这个应用程序是一个" findWaldo"喜欢玩家可以放大,平移和点击图像视图的游戏。它在touchEventListener中使用简单的onTouch函数来管理事件和基本的数学运算。

我在3台物理设备上运行此应用程序:

  • Galaxy Tab 3 7.0 Kitkat(API19):app流畅而快速

  • UMI Plus E(高性能设备)棉花糖(API23):应用非常慢(跳过约30帧)

  • Galaxy A5 2014 Marshmallow(API 23):应用非常慢(大约40帧跳过)

我的问题是:为什么我的应用程序在相当老的Android操作系统(Kitkat)上正常运行,但在最近的操作系统(Marshmallow)上却没有?是否有任何良好的实践或解决方案可以避免这种情况?

这是我的代码:

Game.java

公共类游戏扩展了AppCompatActivity {

/* Define variables */
private RelativeLayout layout; /* activity layout */
private int[] images = {R.drawable.image1, R.drawable.image2}; /* Images list */
private float[][][] waldoC = {
        {
                {596f, 626f},
                {652f, 710f}
        },
        {
                {1100f, 290f},
                {1200, 380f}
        }
}; /* min and max coordinates of waldo click zone */
private int currentImage; /* index of displayed image */
private Matrix matrix = new Matrix(); /* Matrix to scale image */
private Matrix savedMatrix = new Matrix(); /* saved matrix during translate or scale */
private Float previousDist = 1f; /* Image scale */
private ImageView image; /* Image view used to display image */
private final static int NONE = 0; /* none event state */
private final static int PAN = 1; /* panning event state */
private final static int ZOOM = 2; /* zooming event state */
private int mEventState; /* event state */
private float mStartX; /* start position x for translating */
private float mStartY; /* start position y for translating */
private float mMidX; /* middle of two fingers positions x for scaling */
private float mMidY; /* middle of two fingers positions y for scaling */
private float[] values = new float[9]; /* array to get matrix values */
private final Handler delay = new Handler(); /* delay handler */
private boolean disabled = false; /* click enabled */
private Chronometer chronometer; /* chronometer */


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    /* Get layout */
    layout = (RelativeLayout) findViewById(R.id.layout);

    /* New thread to run chronometer */
    new Thread(new Runnable() {
        @Override
        public void run() {
            /* Getting chronometer */
            chronometer = (Chronometer) findViewById(R.id.chronometer);
            chronometer.start(); /* Chronometer start */
        }
    }).start();

    /* Getting image view */
    image = (ImageView) findViewById(R.id.imageView);

    /* Setting random image */
    image.setImageResource(randomImage());

    /* Setting on touch listenener to detect pinch zoom */
    image.setOnTouchListener(new View.OnTouchListener() {
        /* Touch event */
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            /* Getting image view */
            ImageView image = (ImageView) view;

            /* Checking if touch event are disabled */
            if(disabled == true){
                return true;
            }

            /* Detecting panning image events
             in switch condition, & is used to bitwise "event get action"
             result with "action mask" to get only action
             */
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: /* screen is touched */
                    savedMatrix.set(matrix); /* save matrix */
                    mEventState = PAN; /* change event state to pan */
                    mStartX = event.getX(); /* save start x and y positions */
                    mStartY = event.getY();
                    matrix.getValues(values); /* get matrix values in values array */
                    isClick(event, values[2], values[5], values[0]); /* call to click check */
                    break;
                case MotionEvent.ACTION_UP: /* screen is no more touched */
                case MotionEvent.ACTION_POINTER_UP:
                    mEventState = NONE; /* change event state to none */
                    break;
                case MotionEvent.ACTION_MOVE: /* move detected */
                    if(mEventState == PAN) { /* if event state is pan */
                        matrix.set(savedMatrix); /* matrix takes values of saved matrix */
                        matrix.postTranslate(event.getX() - mStartX, event.getY() - mStartY);
                        /* post concats translations on x and y */
                    }
                    else if(mEventState == ZOOM) { /* zoom detected */
                        float newDist = spacing(event); /* call to spacing */
                        matrix.set(savedMatrix); /* matrix takes values of saved matrix */
                        float scale = newDist / previousDist; /* determine scale */
                        focus(event); /* call to focus */
                        matrix.postScale(scale, scale, mMidX, mMidY); /* post concats
                        to scale */
                    }
                    break;
                case MotionEvent.ACTION_POINTER_DOWN: /* if multi touch is detected */
                    previousDist = spacing(event); /* call to spacing */
                    mEventState = ZOOM; /* change event state to zoom */
                    savedMatrix.set(matrix); /* save matrix */
                    break;
            }

            image.setImageMatrix(matrix); /* set matrix to image view */

            return true;
        }
    });
}

/* determine spacing between two fingers positions */
private float spacing(MotionEvent event) {
    double x = event.getX(0) - event.getX(1);
    double y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}

/* determine focus point with 2 fingers positions */
private void focus(MotionEvent event) {
    mMidX = (event.getX(0) + event.getX(1))/2;
    mMidY = (event.getY(0) + event.getY(1))/2;
}

/* Randomize image */
private int randomImage(){
    Random r = new Random(); /* new random */
    currentImage = r.nextInt(images.length); /* generate random index
                                                in range of numebr of images */
    return images[currentImage]; /* returns image */
}

/* Check if touch event is a click to test waldo position */
private void isClick(MotionEvent event, final float translateX, final float translateY, final float scale){
    final Handler delay = new Handler(); /* delay handler */
    final MotionEvent e = event; /* create a final var for run function */

    /* wait for 1 second */
    delay.postDelayed(new Runnable(){
        @Override
        public void run() {
            if((e.getX() > mStartX - 10f && e.getX() < mStartX + 10f)) {
                /* if event does not move more than 10px, call to findWaldo */
                findWaldo(mStartX, mStartY, translateX, translateY, scale);
            }
        }
    }, 1000);

}

/* Check if click is on Waldo or not */
private void findWaldo(float x, float y, float translateX, float translateY, float scale){
        Log.d("POSITION", Float.toString(x - translateX) + " " + Float.toString(y - translateY));
        /* if x and y minus their translation correspond to Waldo area coordinates time scale */
        if((x - translateX >= waldoC[currentImage][0][0] * scale && x - translateX <= waldoC[currentImage][1][0] * scale)
            && (y - translateY >= waldoC[currentImage][0][1] * scale && y - translateY <= waldoC[currentImage][1][1] * scale)) {
                /* if waldo was found */
                ProgressBar spinner = new ProgressBar(this); /* create new spinner */
                spinner.setX(x - 100f); /* set spinner position around clicked position */
                spinner.setY(y);
                spinner.getIndeterminateDrawable().setColorFilter(Color.GREEN, PorterDuff.Mode.MULTIPLY);
                /* change spinner color to green */
                layout.addView(spinner, 200, 200); /* add spinner to view with size of 200 */
                disableTouch(true); /* call to disable touch */
                chronometer.stop(); /* stop chronometer and end thread */
                hallOfFame((String) chronometer.getText()); /* call to hall fo fame */
        }
        else { /* if waldo was no found */
            final ProgressBar spinner = new ProgressBar(this); /* create new spinner */
            spinner.setX(x - 100f); /* set spinner position around clicked position */
            spinner.setY(y);
            spinner.getIndeterminateDrawable().setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
            /* change spinner color to red */
            layout.addView(spinner, 200, 200); /* add spinner to view with size of 200 */
            disableTouch(true); /* call to disable touch */

            /* 2 seconds cooldown caused by player's error */
            delay.postDelayed(new Runnable() {
                @Override
                public void run() {
                    layout.removeView(spinner); /* remove spinner */
                    disableTouch(false); /* call to disable touch */
                }
            }, 2000);
        }
}

/* disable or enable touch events */
private void disableTouch(boolean value){
    disabled = value;
}

/* end the game */
private void hallOfFame(String time){
    Intent i = new Intent(getApplicationContext(), HallOfFame.class); /* new intent */
    i.putExtra("time", time); /* pass time to hall of fame actvity */
    startActivity(i); /* starts hall of fame activity */
    finish(); /* finish game activity */
}

}

activity_game.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout"
    tools:context="com.test.findwaldo.Game">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:text="@string/gameTitle"
        android:textSize="20dp"
        android:textColor="@color/colorPrimary"
        android:gravity="center"
        android:layout_alignParentEnd="true"
        android:layout_alignParentStart="true" />

    <Chronometer
        android:id="@+id/chronometer"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_below="@+id/title"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true"
        android:gravity="center"
        android:textSize="30dp"
        android:textColor="@color/colorPrimaryLight"/>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@mipmap/ic_launcher"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/chronometer"
        android:layout_alignParentStart="true"
        android:scaleType="matrix"/>

</RelativeLayout>

非常感谢您的帮助。

0 个答案:

没有答案