The strangest thing is happening. In my onClick(View ...) I have blocks of code, mostly 'if/else' blocks. The sequence is (in pseudo-code, to save you lengthy code):
I have an image that needs setting using imageButton.setImageResource(randomImage); then
I have a MediaPlayer associated with this image that needs playing, then
I place a sleep(1800) here otherwise the MediaPlayer runs into the next MediaPlayer (this works fine)
This image is compare to another image. If its not the same, then another MediaPlayer named 'boo' is played, and the image that should have been displayed in code 1. above, is replaced by 'flag' image. else //if its the right image then
Switch to 'another' image, play it's corresponding MeidaPlayer, Play a 'cheers' MediaPlayer and change image to a 'tick' image, then do some other logic stuff.
But what is happening is that the code 2. is playing, code 3. is happening. code 4. only the 'boo' mediaplayer is happening and I notice the imagebutton flashing. The image that was supposed to be set in code 1. is delayed and is happening only AFTER the 'boo' mediaplayer. The 'flag' image that replaces the first image setting in code 1. is happening but because code 1. is in delay, what is happening is that the image is not changing (although it is, it's just in delay and then it flashes so quickly that it appears not to change). So code 1. is in delay.
Also, if it goes into the else and the right image is clicked, then the image in code 5. DOES switch to 'another', but the corresponding MeidaPlayer doesn't play, the 'cheers' MediaPlayer doesn't play, the 'tick' image doesn't display, and the other logic doesn't occur. Its as if it is ignoring the code.
What's happening here? Is this a multi-threading situation here? Grouping different parts of the code in their own threads and starting them at once only throws exceptions. Any help will be greatly appreciated!
If you want to delay your code, use Handler.postDelayed(Runnable, long). This won't block the UI thread, and will execute when you want it to.
Whitout your code, it's really unclear what are you trying to achive, and how are you trying to achieve it.
Just to explain Adam's idea.
Put this in your Activity class :
final Handler handler = new Handler();
Runnable _rnbl = new Runnable() {
public void run() {
// Your code
}
};
And call it like this
handler.postDelayed(_rnbl , 5000);
Related
The title may be unclear, but I'm using this awesome library by CommonsWare(nice meeting you at DroidCon btw) to deal with the notorious issues with Android's fragmented camera api.
I want to take 5 photos, or frames..but not simultaneously. Each frame should capture another shot a few milliseconds apart, or presumably after the previous photo has been successfully captured. Can this be done?
I'm following the standalone implementation in the demos, and simply taking a photo using
mCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
takePicture(true, false);
}catch(Exception e){
e.printStackTrace();
}
}
});
Passing in true to takePicture() because I will need the resulting Bitmap. I also disabled single shot mode since I will want to take another photo right after the previous has be snapped, and the preview is resumed
By default, the result of taking a picture is to return the
CameraFragment to preview mode, ready to take the next picture.
If, instead, you only need the one picture, or you want to send the
user to some other bit of UI first and do not want preview to start up
again right away, override useSingleShotMode() in your CameraHost to
return true. Or, call useSingleShotMode() on your
SimpleCameraHost.Builder, passing in a boolean to use by default. Or,
call useSingleShotMode() on your PictureTransaction, to control this
for an individual picture.
I was looking for a callback like onPictureTaken() or something similar inside CameraHost, that would allow me to go ahead and snap another photo right away before releasing the camera, but I don't see anything like this. Anyone ever done something like this using this library? Can the illustious CommonsWare please shed some light on this as well(if you see this?)
Thank you!
Read past the quoted paragraph to the next one, which begins with:
You will then probably want to use your own saveImage() implementation in your CameraHost to do whatever you want instead of restarting the preview. For example, you could start another activity to do something with the image.
If what you want is possible, you would call takePicture() again in saveImage() of your CameraHost, in addition to doing something with the image you received.
However:
Even with large heap enabled, you may not have enough heap space for what you are trying to do. You may need to explicitly choose a lower resolution image for the pictures.
This isn't exactly within the scope of the library. It may work, and I don't have a problem with it working, but being able to take N pictures in M seconds isn't part of the library's itch that I am (very very slowly) scratching. In particular, I don't think I have tested taking a picture with the preview already off, and there may be some issues in my code in that area.
Long-term, you may be better served with preview frame processing, rather than actually taking pictures.
I'm trying to create an Android app that will include many (sometimes up to about 200) small images that will be animated (relocate and change size) about 20 at a time. After that they'll remain still.
Should I use the simple solution of the View class animation or should I use Drawable animation?
EDIT: I should be more specific..
There are a lot of tutorial out there and a lot of different ways to do the same thing. I'm looking for the best way to implement the next scenario:
Say I have 50 different small (30x30) images currently drawn on the screen.
I need to animate them so they will translate to a different DYNAMIC position. And while they are moving I need the image to be resized up and down (so I get kind of a jump effect if looking from top).
They need to move within a specific timeframe. For example: After the first image starts to move, the second will begin moving 50ms after the last and so on (wave effect)...
After one group of images is translated, another group will be formed, but the last group will still be on screen.
So what I'm asking is a little specifics about the best way to do this. For example: Should I create a XML file for each Image or should I just load them in code? Should I load all the images (there could be up to 200 small images, maybe more) at application start or will it be ok to load them on demand? What would be the best animation technique? Stuff like that.
The easiest solution I found: (API 16+)
Runnable endAction = new Runnable() {
public void run() {
tv.animate().x(400).y(1400).scaleX(1).scaleY(1);
}
};
tv.animate().x(600).y(100).scaleX(3).scaleY(3).withEndAction(endAction);
I would use Drawable animation but it doesn´t matter so much. The important thing you should do if the app runs very slow, is to use diferents threads using this code for example:
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
public void run() {
//YOUR ANIMATION HERE
}
});
In this way, you will be able to process the animation of a lot of images at the same time because the phone will execute the code in different computing threads.
You can use too AsyncTask like that (adding the class into your activity class):
private class doAnimation extends AsyncTask<ImageView, Void, Void>{
#Override
protected Void doInBackground(ImageView... image) {
image.startAnimation(animation);
return null;
}
}
And calling it using:
new doAnimation().execute(image1);
new doAnimation().execute(image2);
new doAnimation().execute(image3);
...
I've got a problem with creating gameloop for my first game. I've read a lot about it but still can't figure it out. It's based on OpenGL so I've used onDrawFrame as a game loop and it works fine on my phone. Problem is that onDrawFrame is refresh time depends on hardware so it runs way too fast on some devices. So what I want is adding a separate game loop that will refresh itself at constant period of time on all smartphones. (and onDrawFrame will only take care of graphics as it should)
As for now I have:
myGameRenderer class with all openGl stuff an onDrawFrame
myGLSurfaceView that supports touch events
myGameActivity
onDrawFrame activates myGameUpdate function that controls changing positions of all objects in game depending on info from myGLSurfaceView
I've tried with creating new Runnable but it doesn't seem to work, I can't figure out how to start that runnable and where i should place it (I've tried to place it in myGameRenderer class, but it didn't seem to work, nothing was moving:
private final Runnable mUpdateDisplay = new Runnable() {
#Override
public void run() {
update();
}};
private void update() {
//some update stuff blablabla
//some update stuff blablabla
mHandler.postDelayed(mUpdateDisplay,40); //to refresh at 25 fps
}
but I guess I don't get the idea of it - I mean I create this runnable.
I've tried to place it in onCreateSurface to start it but no effect.
So - is the generall idea ok? And how to start the loop? Where to place it? Or should I use any other way?
Ok it was simple - I was just missing r.run();
But as allways there's something. Now it works as i wanted - I mean frames doesn't depend on hardware, but everything is not as smooth as it was - and part of objects in 3d are flickering. Seems like some objects visibly are drawn faster, some later and it looks ugly.
So what am I doing wrong? Is there a better way?
when I start my game black screen comes for a while because resources are being loaded.
I went thorough a tutorial which show how to show progress bar while leading resources I followed it and now I can see progress bar. But the problem is this when progress bar is visible every thing else is stopped. And nothing happens. Only a black screen and a progress bar on it. Can any one tell me why every thing is paused and why loadresources and loadscene methods are not working? Please provide a solution.
You need to load your resources in a worker thread. A nice utility for doing this is AsyncTask. The guide topic Processes and Threads has an explanation of why you need something like this, as well as sample code showing how to do a simple AsyncTask that might be just what you need.
From Engine.java:
public void onDrawFrame(final GLState pGLState) throws InterruptedException {
final EngineLock engineLock = this.mEngineLock;
engineLock.lock();
try {
engineLock.waitUntilCanDraw();
this.mVertexBufferObjectManager.updateVertexBufferObjects(pGLState);
this.mTextureManager.updateTextures(pGLState);
this.mFontManager.updateFonts(pGLState);
this.onUpdateDrawHandlers(pGLState, this.mCamera);
this.onDrawScene(pGLState, this.mCamera);
engineLock.notifyCanUpdate();
} finally {
engineLock.unlock();
}
}
And that's why the engine hangs and the UI gets stuck. It's possible to display a loading screen while the textures are being loaded into hardware, without freezing, let's say, a ProgressBar. It's not easy and requires a lot of code, but it's possible and doesn't require crazy hacks, just some logic.
You need to have a Resources Manager (RM) and a Scene Manager (SM) who work together (with AsyncTasks) and are responsible for loading the textures for the current scene. Since you've a BaseGameActivity you can use this Activity instance to show a fullscreen Dialog with the progress bar. The logic is:
SM is asked to show Scene A
SM shows the loading Dialog
SM asynchronously tells the RM to load all Scene A resources into hardware (for each texture for Scene A, texture.load)
RM "onSceneTexturesLoadComplete" tells SM that all textures are loaded
Since texture.load doesn't guarantee the texture is actually loaded you'll need to have a TryToDismissDialog that extends TimerTask. This TryToDismissDialog from time to time will query the Scene A textures and check if they are actually loaded:
if (texturePack.getTexture().isLoadedToHardware()) {
texturesLoaded++;
}
If all textures are loaded you dismiss the Dialog and voilá you'll see the Scene ready.
Hope it helps
ps: this actually involves some lines of code, I've just posted here a quick steps/guide/pseudo-code. I'll not post the final solution because it's quite heavy and "project related".
I have created an animation drawable and image view in my main game thread which is configured from the activity that handles the game thread (starting it etc.). My code in this handling activity looks like this:
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.one), 1000);
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.two), 1000);
mDistractionsThread.animation.addFrame(getResources().getDrawable(R.drawable.three), 1000);
mDistractionsThread.animation.setOneShot(false);
mDistractionsThread.imageAnim =(ImageView) findViewById(R.id.img);
mDistractionsThread.imageAnim.setBackgroundDrawable(mDistractionsThread.animation);
mDistractionsThread.animation.start();
And as you can see the variable mDistractionsThread is a handle to the thread itself. This compiles fine but only displays the first frame (R.drawable.one) and does not animate at all. What is it I have missed?
I tried to set animation.start() from run() within mDistractionsThread but that just gave me an fatal exception because the View can only be altered from the class that alters its fields - which in this case is not the game thread.
How can I resolve this and get it animating through the frames, and for bonus points, moving across the x-axis?!
Many thanks
It matters where you start the animation. Try starting it in onFocusChanged() in the activity. It should help