Android 动画滞后

Android animation lagging

请向下滚动到“EDIT”:)


我正在尝试使用 Android Studio 了解一些基本的 android 动画编程,并且我遵循了 Internet 上的一些教程。 我已经知道一些基本的 java 编程,但是我的 "copy/paste app" 我有一个问题。

这是我的 MainActivity:

public class MainActivity extends ActionBarActivity {
private Button play;

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

    play = (Button) findViewById(R.id.play_button);
    play.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            Intent startGame = new Intent("com.abc.test.DRAWGAME2");
            startActivity(startGame);
        }
    });
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}}

这是DrawGame2.java:

public class DrawGame2 extends Activity implements View.OnTouchListener {

private MyView surfaceView;
private float y;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    surfaceView = new MyView(this);
    surfaceView.setOnTouchListener(this);
    setContentView(surfaceView);
}

@Override
protected void onPause() {
    super.onPause();
    surfaceView.pause();
}

@Override
protected void onResume() {
    super.onResume();
    surfaceView.resume();
}

@Override
public boolean onTouch(View v, MotionEvent me) {

    try {
        Thread.sleep(50);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    switch (me.getAction()){
        case MotionEvent.ACTION_DOWN:
            y = me.getY();
            break;
        case MotionEvent.ACTION_UP:
            y = me.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            y = me.getY();
            break;
    }


    return true;
}

public class MyView extends SurfaceView implements Runnable {

    private Thread thread = null;
    private SurfaceHolder holder;
    private boolean isRunning = false;



    public MyView(Context context) {
        super(context);
        holder = getHolder();
        y = 0;
    }

    public void run() {
        while (isRunning) {
            if (!holder.getSurface().isValid()) {
                continue;
            }
            Canvas canvas = holder.lockCanvas();
            canvas.drawRGB(02,02,150);



            if (y != 0){
                Bitmap test = BitmapFactory.decodeResource(getResources(),R.drawable.greenball);
                canvas.drawBitmap(test, canvas.getWidth()/2 - test.getWidth()/2, y, null);
            }



            holder.unlockCanvasAndPost(canvas);
        }
    }

    public void pause() {
        isRunning = false;
        while (true) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        thread = null;
    }

    public void resume() {
        isRunning = true;
        thread = new Thread(this);
        thread.start();
    }

}}

Logcat:

02-12 11:01:06.676    1972-1972/com.abc.test I/art﹕ Not late-enabling -Xcheck:jni (already on)
    02-12 11:01:06.881    1972-1990/com.abc.test D/OpenGLRenderer﹕ Render dirty regions requested: true
    02-12 11:01:06.882    1972-1972/com.abc.test D/﹕ HostConnection::get() New Host Connection established 0xa686fb60, tid 1972
    02-12 11:01:06.917    1972-1972/com.abc.test D/Atlas﹕ Validating map...
    02-12 11:01:07.007    1972-1990/com.abc.test D/﹕ HostConnection::get() New Host Connection established 0xa686fd90, tid 1990
    02-12 11:01:07.037    1972-1990/com.abc.test I/OpenGLRenderer﹕ Initialized EGL, version 1.4
    02-12 11:01:07.102    1972-1990/com.abc.test D/OpenGLRenderer﹕ Enabling debug mode 0
    02-12 11:01:07.126    1972-1990/com.abc.test W/EGL_emulation﹕ eglSurfaceAttrib not implemented
    02-12 11:01:07.126    1972-1990/com.abc.test W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa6814940, error=EGL_SUCCESS
    02-12 11:01:07.705    1972-1990/com.abc.test W/EGL_emulation﹕ eglSurfaceAttrib not implemented
    02-12 11:01:07.705    1972-1990/com.abc.test W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa6814940, error=EGL_SUCCESS
    02-12 11:01:12.571    1972-1990/com.abc.test W/EGL_emulation﹕ eglSurfaceAttrib not implemented
    02-12 11:01:12.571    1972-1990/com.abc.test W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa5a69ba0, error=EGL_SUCCESS
    02-12 11:01:16.892    1972-1972/com.abc.test I/Choreographer﹕ Skipped 263 frames!  The application may be doing too much work on its main thread.
    02-12 11:01:16.899    1972-2270/com.abc.test D/﹕ HostConnection::get() New Host Connection established 0xa5dfcc10, tid 2270

这个应用程序的问题是动画真的很滞后,我不明白为什么! 我尝试用一​​个简单的矩形制作相同的动画,但延迟仍然存在。

问题不在于 OnTouchListener,因为我试图在 运行 方法中的每个循环中将 y 值增加 1(同时禁用 OnTouchListener),但它仍然滞后。

我在我的三星 Galaxy S3 (Jelly Bean) 上尝试过不同的模拟器(Lollipop、Kitkat)。

有没有聪明的人可以帮助我解决这个问题? :)

祝你有美好的一天!


编辑:

好的,所以我应用了我得到的答案,现在 运行 很顺利,在我的 Samung Galaxy S3 上!

虽然我的模拟器上仍然存在滞后。我已经从我创建的应用程序中顺利安装了 HAXM 和模拟器 运行s,但是一旦我启动应用程序并按下 "PLAY" 按钮,当我与应用

这是我的模拟器的属性:

    Name: Nexus_5_API_21
CPU/ABI: Intel Atom (x86)
hw.gpu.enabled: yes
Path: C:\Users\User\.android\avd\Nexus_5_API_21.avd
Target: Android 5.0.1 (API level 21)
Skin: nexus_5
SD Card: 100M
Snapshot: no
hw.lcd.density: 480
hw.dPad: no
avd.ini.encoding: UTF-8
hw.camera.back: none
disk.dataPartition.size: 200M
runtime.network.latency: none
skin.dynamic: no
hw.keyboard: yes
runtime.network.speed: full
hw.device.hash2: MD5:2fa0e16c8cceb7d385183284107c0c88
hw.ramSize: 1536
tag.id: default
tag.display: Default
hw.sdCard: yes
hw.device.manufacturer: Google
hw.mainKeys: no
hw.accelerometer: yes
hw.trackBall: no
hw.device.name: Nexus 5
hw.sensors.proximity: yes
hw.battery: yes
AvdId: Nexus_5_API_21
hw.sensors.orientation: yes
hw.audioInput: yes
hw.camera.front: none
hw.gps: yes
avd.ini.displayname: Nexus 5 API 21
snapshot.present: no
vm.heapSize: 64
runtime.scalefactor: auto

据我所知,您的问题出在 onTouch() 方法中,您在该方法中有以下代码:

try{
    Thread.sleep(50);
}catch (InterruptedException e){
   e.printStackTrace();
}

这将使 MAIN 线程休眠,这意味着一切都会使整个应用程序等待 50 毫秒。

所以尝试删除它。

解码资源也不利于性能。您应该尽早解码位图并在绘制时重新使用它。为什么不使用 onDraw 方法?