Please scroll down to the "EDIT" :)
I'm trying to understand some basic android animation programming using Android Studio, and I have followed some tutorials on the internet. I already know some basic java programming, but I have a problem with my "copy/paste app" I made.
This is my 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);
}}
This is 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
The problem with this app is that the animation is really laggy, and I can't figure out why! I have tried to make the same animation with a simple rectangle, but the lag is still there.
The problem isn't the OnTouchListener, because I've tried to just increase the y value by 1 with each loop in the run method (while disabling the OnTouchListener), but it is still lagging.
I have tried with different emulators (Lollipop, Kitkat) and on my Samsung Galaxy S3 (Jelly Bean).
Are there any wise people out there that can help me with this problem? :)
Have a great day!
EDIT:
Okay, so I applied the answers I got, and now it runs smoothly, ON MY Samung Galaxy S3!
The lagging is still there on my emulator though. I've installed HAXM and the emulator runs smoothly out of the app I've created, but as soon as I launch the app and press the "PLAY" button, the animation lags when I interact with the app.
This is the properties for my emulator:
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
As far as I can see, your problem is in the onTouch()
method, in which you have this code:
try{
Thread.sleep(50);
}catch (InterruptedException e){
e.printStackTrace();
}
Which will sleep the MAIN thread, meaning that everything will make the entire application hold up for 50 milliseconds.
So try to remove that.