How can I improve the performance of the code below? I have created method that will execute some other Method if Minute and Second of hour is 0, but I am still using looping and that is lagging my phone up to 30% mem usage, is there any suggestion to do that ?
this is my code
try {
do {
if ((Calendar.getInstance().get(Calendar.MINUTE) == 0) && (Calendar.getInstance().get(Calendar.SECOND) == 0)){
UtilitiesService.InitLoggingService(getApplicationContext());
blnPerfect = true;
//return null;
break;
//stopSelf();
}
} while (!blnPerfect);
} catch (Exception e) {
e.printStackTrace();
}
You can calculate the time to 0,0 and Start a Single Shot thread
Executors.newSingleThreadScheduledExecutor().schedule(new Callable() {
public Void call() {
doSomething();
return null;
}
}, X, TimeUnit.SECONDS);
Why don't you simply calculate how long you have to wait until the time is at the ZEROth minute and ZEROth second ... but seeing how long you need to wait, converting to milliseconds, an sleeping for that long?
Also, you should do this "event" timing in an asynchronous task/thread.
Related
I writing an android timer app that uses System.nanotime. The issue is that it's giving me underpredicted results as well negative numbers. redVal, blueVal, and greenVal are updated on each frame of the camera.
results
504455566
-95947265
9063721
61035
-99487305
-98937988
12664795
-75317382
code
for (testAmount = 0; testAmount < 80; testAmount++) {
runOnUiThread(new Runnable() {
public void run() {
lagSquare.setBackgroundColor(Color.rgb(255, 255, 255));
lagStartTime = System.nanoTime(); //start lagTimer start
}
});
while (redVal <= 100.0 && blueVal <= 100.0 && greenVal <= 100.0) {
x=0;
}
runOnUiThread(new Runnable() {
public void run() {
lagEndTime = System.nanoTime(); //start lagTimer end
lagSquare.setBackgroundColor(Color.rgb(000, 000, 000));//set lagSquare black
}
});
lagTimeResult = (lagEndTime - lagStartTime);
timeArray[testAmount] = lagTimeResult;
Log.i("LTR", String.valueOf(lagTimeResult));
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
You are trying to output a time difference which is relying upon values being set in different threads, without any synchronization. This will almost always end up with the wrong value:
for (testAmount = 0; testAmount < 80; testAmount++) {
// this will schedule the Runnable to run *sometime* in
// the future - but not necessarily right now
runOnUiThread(new Runnable() {
public void run() {
lagStartTime = System.nanoTime(); //start lagTimer start
}
});
// this will also schedule this Runnable to run *sometime* in
// the future - but not necessarily after the first one
runOnUiThread(new Runnable() {
public void run() {
lagEndTime = System.nanoTime(); //start lagTimer end
}
});
// this will probably execute first (before either of
// the other Runnables have completed)
lagTimeResult = (lagEndTime - lagStartTime);
}
You simply can't rely on the order of threads executing in the order you've coded them - and definitely not in a loop.
I can't understand from your question what you are trying to time, but the take-home rule is that whenever you have multiple threads, you can never rely on the order of execution without using some form of synchronization.
I need some help with starting/stopping my monsters.
We generate like this:
for (int i = 0; i < 20; i++) {
boolean notFree = true;
int x = 0, y = 0;
// while not free change
// not determinstisch setting!
while (notFree) {
x = (int) (Math.random() * Config.XSIZE);
y = (int) (Math.random() * Config.YSIZE);
if (map.getMapPosition(x, y) == Config.EMPTYPOSITION) {
notFree = false;
}
}
switch ((int) Math.floor(Math.random() * 2)) {
case 0:
monsterVerktor.add(new Monster(context, x, y, this.map, 1,
this.charac));
break;
case 1:
monsterVerktor.add(new DeathReaper(context, x, y, this.map, 1,
this.charac));
break;
default:
break;
}
}
And I stop them like this: (Start is same just with Startmoving...)
public void stopAllMonsters() {
for (Monster monster : monsterVerktor) {
monster.getControl().stopMovingThread();
}
}
The thread.stopMovingThread works like this:
public void stopMovingThread() {
this.monster.setAlife(false);
running = false;
moveDone = true;
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
To the run():
public void startMovementThread() {
running = true;
thread = new Thread() {
#Override
public void run() {
while (running) {
Log.d(TAG, "run Thread");
// get a little randomness in the movement ;)
try {
// up to 0.5s sleeping till next moving
sleep(new Random().nextInt(Config.RANDOMSLEEP));
} catch (InterruptedException e1) {}
while (monster.isAlife()) {// check if alife
moveDone = false; // resett movement Done
noMove = false;
// Charakter in near if one is in near he
// will move to it.
if (!checkCharInAggroRange()) {
noMove = rndMove(); // if we have no move
}
while (!moveDone) {
timeBegin = System.currentTimeMillis();
// if hes not done with the move
if (monster.moveToX == monster.positionX
&& monster.moveToY == monster.positionY) {
if (noMove) {
try {// sleep because no movement with a bit
// randomness
sleep(Config.MONSTERMOVINGTIME
+ (new Random()
.nextInt(Config.RANDOMSLEEP)));
} catch (InterruptedException e) {
Log.d(TAG,
"An error occured during sleep because"
+ " of no Animatino");
}
}
// false after sleep
moveDone = false;
break; // already at the right position!
// movetoX is left of position
} else if (monster.moveToX > monster.positionX) {
monster.positionX++;
// movetoX is left of it
} else if (monster.moveToX < monster.positionX) {
monster.positionX--;
// movetoY is left of position
} else if (monster.moveToY > monster.positionY) {
monster.positionY++;
// movetoY is left of position
} else if (monster.moveToY < monster.positionY) {
monster.positionY--;
}
// sleep if hes moving to fast!
timeDiff = System.currentTimeMillis() - timeBegin;
sleepTimer = (int) (Config.MONSTERTIMING - timeDiff);
if (sleepTimer > 0) { // if >0 we are fast enough
// and can sleep a bit ;)
try {
sleep(sleepTimer);
} catch (InterruptedException e) {
Log.d(TAG, "Gameloop thread cant sleep");
}
}
}
}
try {
sleep(Config.RESPAWNTIMER);
} catch (InterruptedException e) {
Log.d(TAG, "Monsterthread cant sleep");
}
// respawn it after a sleep :)
respawn();
}
}
};
thread.start();
}
Android stops working if we want to stop them and start them like this, and I dont get it why. We also stop/start our render like this. (Well it's a runable and this isn't)
Monster isAlife and etc:
public class Monster extends Drawable {
private static final String TAG = Monster.class.getSimpleName();
private int fullLife; // full life
private int curLife; // current life
public Context context;
private Character charac;
// ..
// Basic monsterstuff
private boolean alife, moveDone;
private int level;
public Status status;
private MonsterControl control;
// ..
public Monster(Context context, int mapPosX, int mapPosY, Map map,
int level, Character cha) {
this.context = context;
this.map = map;
this.setCharac(cha);
this.mapPosition[0] = mapPosX;
this.mapPosition[1] = mapPosY;
this.status = Status.IDLE;
// example for full life calculation
this.fullLife = level * 100 + ((int) (Math.random() * 10 * level)); // Examples
this.curLife = this.fullLife;
this.map.setMapPosition(mapPosX, mapPosY, Config.MONSTERSTATE);
// set monster position
// ..
// load the sprite bitmap
// ...
// Change this later!
alife = true;
Log.d(TAG, "Monster created");
// Starting the Controler
control = new MonsterControl(this, this.charac);
control.startMovementThread();
Log.d(TAG, "Monster start moving");
// exemplarisch cut of the sprite
this.monsterPicAnimation();
}
}
here the getter/setter for aLife
public boolean isAlife() {
return alife;
}
public void setAlife(boolean alife) {
this.alife = alife;
}
First off, your comment of "Android stops working", Are you implying a crash? Got a LogCat trace?
Other than that is this analysis correct?
1.Create a monster.
running = true;
isAlife = true; //or whatever monster.isAlife() checks
2.Thread starts.
while (running) {
...
while (monster.isAlife()) {
...
}
}
3.You try to stop the thread by (1) setting running to false, and (2) joining on the thread?
Assuming that is all true. The monster thread still runs until something kicks it from the nested while(monster.isAlife()) loop. Once that ends, the while(running) will evaluate false and the thread should terminate, moving on to the next monster in your collection. Without this ever terminating you'll be waiting on each monster to die while locking your main thread with join().
Apart from the logic of your code which I haven't looked at in details, there is a lack of synchronization around shared variables. In particular, as it is, your code provides no guarantee that your thread (in startMovementThread) will ever be able to observe the changes made to your flags from the main thread.
A good first step would be to make those variables volatile:
private volatile boolean alife, moveDone;
Note however that there might be other issues (depending on your requirements). For example, when those statements are executed in startMovementThread:
if (monster.moveToX == monster.positionX ...)
monster.positionX++;
any changes made in that thread might not be visible from the main thread and vice versa. If that can be an issue, you need to synchronize access to those variables too (and making them volatile will not be enough because, for example, monster.positionX++ is not atomic).
I solved it myself with and "good" idea.
The problem was, that i let them sleep at some points. If they sleep it cant stop/join the thread and even dont watch if its "running". So i solved it with a small methode that looks like this:
private void breakableSleep(int i, int intervall){
int x = 0;
while(running && x <= i){
try {
this.thread.sleep(intervall);
} catch (InterruptedException e) {
Log.d(TAG, "Monsterthread cant sleep");
}
x++;
}
}
it can be stoped at every intervall. Sure it will cost some Battery but did not finde any other way to stop the Monsters in a "fast" way because some sleep for around 3seconds if they died (respawning)
I also rewrote the whole startMovementThread because it did not look well in my opinion.
Best Regards
I am trying to run the audio recording http://developer.android.com/guide/topics/media/index.html, Its working fine, what I need is to show max amplitude while recording voice continuously. What is the best approach for that.
Max amplitude gives max amplitude of the given sample, so I taken sample for every 250 milli seconds and calculated max amplitude
public void run() {
int i = 0;
while(i == 0) {
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
try {
sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mRecorder != null) {
amplitude = mRecorder.getMaxAmplitude();
b.putLong("currentTime", amplitude);
Log.i("AMPLITUDE", new Integer(amplitude).toString());
} else {
b.putLong("currentTime", 0);
}
msg.setData(b);
mHandler.sendMessage(msg);
}
}
I used message handlers to modify front end using background process thread
Create a thread which runs all the time.
In the thread do this:
int amp = mrec.getMaxAmplitude();
if (amp > 0)
yourcode;
Do you need more information on the thread?
Situation: I would like to pull a network resource (a file), display it for 30 seconds, then load the next file. While displaying the initial file for 30 seconds, I'd like to preload the next file.
Question: Should I be using concurrent threads with a lock (like a linked blocking queue?) or a handler? Or something I'm missing?
Currently I have the onCreate call an asynctask that has a for loop which iterates through an array of paths for the files one at a time, which then calls the next asynctask (inside the for loop) which downloads the file from that path and then in the onPostExecute assigns the file to the UI view.
This works but I am unable to setup timing where the first file loads in the UI view then 30 seconds later the next file loads in the UI view and so on... Right now it loads the files fine but the 1st may take 40 seconds to display and the 2nd 25 seconds and the 3rd 60.
(FYI, the files are uniform size and only take 5~15 sec to load)
Here's a general example (non compile-able):
onCreate(){
new firstAsynchTask().execute(filePaths[]);
}
private class firstAsynchTask extends AsyncTask<String[], Void, Void> {
protected Void doInBackground(String[]... x) {
try {
for(int i = 0; x[0] != null && i < x.length; i++)
{
long startT = System.currentTimeMillis();
if(x[0][i].isFile())
{
SmbFile g = new SmbFile(x[0][i].getPath());
new secondAsynchTask().execute(g);
long TimeNow = (System.currentTimeMillis() - 30000);
if(startT > TimeNow)
{
try {
Thread.sleep(startT - TimeNow);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();}
}
}
if(i == x.length - 1)
{
i = 0;
}
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
private class SecondAsyncTask extends AsyncTask<File, Integer, Drawable> {
protected File doInBackground(File... x) {
SomeType FileTemp = new File();
try {
long startT = System.currentTimeMillis();
FileTemp = (get streamed file);
long TimeNow = (System.currentTimeMillis() - 30000);
if(startT > TimeNow)
{
Thread.sleep(startT - TimeNow);
return FileTemp;
}
else
{
return FileTemp;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
protected void onPostExecute(File result) {
if(result != null)
{
FileView centerFile = (FileView) findViewById(R.id.FileView1);
centerFile.setFile(result);
}
}
}
It looks like a simple producer-consumer approach would be sufficient for what you need. I would have an array of URLs that point to your network resource with a synchronised access. A single AsyncTask would be enough to pop a single URL off the queue, download and display it. How you will re-invoke the task depends on you: you can display downloaded resource and at the same time run task, putting downloaded resource to some temporary placeholder (a Drawable member field for example). Have a timer that every 30 seconds just puts temporary resource to the display and runs download/cache task again.
Of course this is a very simple solutions without handling cases when your task haven't finished in 30 seconds time frame, etc.
Another approach would be to have a boolean object that you will set to true every 30 seconds. Your AsyncTask runs, downloads image and on onPostExecute checks if previously mentioned boolean is set to true, if yes - displays image, sets flag to false and finishes. If flag is false then it enters a loop that sleeps for, say, 200ms and checks condition again, etc.
I use the following snippet to vibrate the phone in a specific pattern, but it throws and ArrayIndexOutOfBoundsException.
vibrator.vibrate(new long[] { selectedDuration, CONSTANT_DELAY }, REPEAT);
But
vibrator.vibrate(VIBRATE_DURATION);
works fine. Any pointers?
The docs say:
If you want to repeat, pass the index into the pattern at which to start the repeat.
Means REPEAT is only allowed to be 0 or 1 in your case.
This is the implementation:
public void vibrate(long[] pattern, int repeat)
{
// catch this here because the server will do nothing. pattern may
// not be null, let that be checked, because the server will drop it
// anyway
if (repeat < pattern.length) {
try {
mService.vibratePattern(pattern, repeat, mToken);
} catch (RemoteException e) {
}
} else {
throw new ArrayIndexOutOfBoundsException();
}
}