i have a problem with my self-written-in-app-clock...
it freezes sometimes. once it freezes for 2 seconds another time for up to 10 seconds. The time is shown correctly, but not fluently...
Here my Code:
CDT_2 = new CountDownTimer(250, 250) {
#Override
public void onTick(long millisUntilFinished) {
{
getDate();
int C_hours_output = C_hours - C_hours_basic;
int C_minutes_output = C_minutes - C_minutes_basic;
int C_seconds_output = C_seconds - C_seconds_basic;
if (C_seconds_output < 0) {
C_seconds_output = C_seconds_output + 60;
C_minutes_output = C_minutes_output - 1;
}
if (C_seconds_output < 10) {
STR_seconds = "0"
+ Integer.valueOf(C_seconds_output).toString();
} else {
STR_seconds = Integer.valueOf(C_seconds_output)
.toString();
}
if (C_minutes_output < 0) {
C_minutes_output = C_minutes_output + 60;
C_hours_output = C_hours_output - 1;
}
if (C_minutes_output < 10) {
STR_minutes = "0"
+ Integer.valueOf(C_minutes_output).toString();
} else {
STR_minutes = Integer.valueOf(C_minutes_output)
.toString();
}
if (C_hours_output < 0) {
C_hours_output = 0;
}
if (C_hours_output < 10) {
STR_hours = "0"
+ Integer.valueOf(C_hours_output).toString();
} else {
STR_hours = Integer.valueOf(C_hours_output).toString();
}
((TextView) acti.findViewById(R.id.TV_time_e01))
.setText(STR_seconds);
((TextView) acti.findViewById(R.id.TV_time_e0))
.setText(STR_minutes + ".");
((TextView) acti.findViewById(R.id.TV_time_e1))
.setText(STR_hours + ":");
}
}
#Override
public void onFinish() {
CDT_2.start();
}
}.start();
thanks in advance
The CountDownTimer class does not run on a separate thread, so it is splitting time with UI events and work. See this post for details.
You are better off implementing this with a Handler or Runnable. You can update your TextView elements using Activity.runOnUiThread
See these posts for similar solutions:
Android: How do I display an updating clock in a TextView
Android - implement a custom timer/clock
Related
I am trying to make a clock program using Java, and I got everything to work properly except I cannot get the program to change the negative values to 0. I also cannot get the program to set the values of hours, minutes, and seconds to 0 if they are out of range. I have a tester program that I have to use and the T1 and T2 clock values are incorrect in my code. T1 should be 0:0:0 and T2 should be 0:0:0 as well. However, when I output my code it comes out as T1 being -3:-21:-30 and T2 is 24:60:60. I know there is something wrong with my code, but I can't find the issue, if anyone would be able to help me that would be greatly appreciated. Below is my code and then the second section is the tester code that I have to use.
public class Clock
{
// instance variables
private int hours;
private int minutes;
private int seconds;
public void setHours(int newHours) {
hours = newHours;
if (hours<0 || hours > 24) {
hours = 0;
}
}
public void setMinutes(int newMinutes) {
minutes = newMinutes;
if (minutes<0 || minutes > 60) {
minutes = 0;
}
}
public void setSeconds(int newSeconds) {
seconds = newSeconds;
if(seconds<0 || seconds > 60) {
seconds = 0;
}
}
/**
* Constructor for objects of class Clock
*/
public Clock(int newHour, int newMinute, int newSecond)
{
if (newHour > -1 || newHour < 24) {
this.hours = newHour;
}
else {
setHours(hours);
}
if (newMinute > -1 || newMinute < 60) {
this.minutes = newMinute;
}
else {
setMinutes(minutes);
}
if (newSecond > -1 || newSecond < 60) {
this.seconds = newSecond;
}
else {
setSeconds(seconds);
}
}
public int getHours() {
return hours;
}
public int getMinutes() {
return minutes;
}
public int getSeconds() {
return seconds;
}
public String toString() {
return hours + ":"+minutes+":"+seconds;
}
public void tick() {
seconds = seconds +1;
if(seconds >= 60)
{
minutes ++;
seconds = 0;
}
if(minutes >= 60)
{
hours++;
minutes = 0;
}
if(hours >=24)
{
hours = 0;
}
}
}
The next piece is the tester code.
public class ClockTest {
public static void main(String [] args){
//Create some clocks and print their times
Clock c1 = new Clock(-3,-21,-30);
System.out.println("T1: "+ c1);
c1 = new Clock(24,60,60);
System.out.println("T2: "+ c1);
c1 = new Clock(3,21,30);
System.out.println("T3: "+ c1);
//Tick the clock twice and print its time
c1.tick();
c1.tick();
System.out.println("T4: "+ c1);
c1 = new Clock(3,30,59);
c1.tick();
System.out.println("T5: "+ c1);
c1 = new Clock(3,59,59);
c1.tick();
System.out.println("T6: "+ c1);
c1 = new Clock(23,59,59);
c1.tick();
System.out.println("T7: "+ c1);
c1 = new Clock(0,0,1);
c1.tick();
System.out.println("T8: "+ c1);
c1 = new Clock(1,1,1);
c1.setHours(22);
c1.setMinutes(30);
c1.setSeconds(35);
System.out.println("T9: "+ c1);
System.out.println("T10: " + c1.getHours() + ":"
+c1.getMinutes() + ":" + c1.getSeconds());
}
}
Your condition is wrong.
When you write this:
if (newHour > -1 || newHour < 24) {
You really mean this:
if (newHour > -1 && newHour < 24) {
#nicomp is correct and you should also be using >= 24 and 60 instead of >. You might consider changing the constructor for Clock to
public Clock(int newHour, int newMinute, int newSecond) {
setHours(newHour);
setMinutes(newMinute);
setSeconds(newSecond);
}
and then do all of your validation in the set methods, instead of having some validation in the set methods and some in the constructor.
I have a simple method running inside a handler. I am populating numbers using an array adapter. My code take more time to run on newer devices with Android 6 or higher, as oppose to old ones.
Here is part of my code, CCA is derived from ArrayAdapter:
numbersToRun = amount;
myHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (numbersToRun > 0) {
boolean isInt2 = IsIntegerOnly.isChecked();
if (isInt2) {
int n = Rnd.nextInt(max - min + 1) + min;
String Str = n + "";
RandomData.add(Str);
CCA.notifyDataSetChanged();
RandomsList.setSelection(CCA.getCount() - 1);
} else {
double d = min + (max - min) * Rnd.nextDouble();
String Str = String.format("%.4f", d) + "";
RandomData.add(Str);
CCA.notifyDataSetChanged();
RandomsList.setSelection(CCA.getCount() - 1);
}
numbersToRun--;
myHandler.postDelayed(this, new Double(interval*1000).longValue());
} else {
myHandler.removeCallbacksAndMessages(null);
}
}
}, 0);
Do I need to run garbage collection here?
What can I do in order to get good performance on stronger and newer devices?
I have to implement Go To Page feature in epub reader. I have try to implement this feature in source code of Page-Turner, but its not working successfully because of multiple xhtml in .epub file, as we know that each chapter have single xhtml file and its divide as per screen size in this app. So whenever screen size is big then total number of pages are less and more number of pages when screen is small, So there is no fix page number where to jump. I have edit and try to implement like giver below.
ReadingFragment.java
public void performSearch(String query) {
int index = Integer.parseInt(query);
if (index > bookView.getTotalNumberOfPages()) {
Toast.makeText(context, "Please enter number between 0 to " + bookView.getTotalNumberOfPages(), Toast.LENGTH_SHORT).show();
} else {
bookView.gotoPageNumber(index);
}
}
BookView.java
public void gotoPageNumber(int pageNum) {
strategy.gotoPage(pageNum);
progressUpdate();
}
PageChangeStrategy.java
public void gotoPage(int pageNumber);
FixedPagesStrategy.java
#Override
public void gotoPage(int pageNumber) {
PageTurnerSpine spinePos = bookView.getSpine();
this.storedPosition = -1;
int currentPage = getCurrentPage() + spinePos.getUptoPage(spinePos.getPosition());
Log.e(TAG, "Adding >> Upto Page : " + spinePos.getUptoPage(spinePos.getPosition())
+ ", currentPage : " + getCurrentPage());
Log.e(TAG, "pagenum : " + pageNum);
if (pageNumber > currentPage) { //pageNumber is greater then current page
int jumpSpine = spinePos.getIndexFromPage(pageNumber);
int currentSpine = spinePos.getPosition();
Log.e(TAG, "jumpSpine : " + jumpSpine + ", currentSpine : " + currentSpine);
if (jumpSpine == currentSpine) {
int diffrence = pageNumber - currentPage;
Log.e(TAG, "diffrence < : " + diffrence);
Log.e(TAG, "Minimum >> PageOffSets - 1 : " + (spinePos.getPageOffSets(currentSpine) - 1)
+ ", pageNum + diffrence : " + (pageNum + diffrence));
this.pageNum = Math.min(pageNum + diffrence, spinePos.getPageOffSets(currentSpine) - 1);
updatePosition();
} else {
PageTurnerSpine spine = bookView.getSpine();
if (spine == null || !spine.navigateFrontSpine(spine.getIndexFromPage(pageNumber))) {
return;
}
this.pageNum = 0;
gotoPage(pageNumber);
}
} else { //pageNumber is less then current page
int jumpSpine = spinePos.getIndexFromPage(pageNumber);
int currentSpine = spinePos.getPosition();
Log.e(TAG, "jumpSpine : " + jumpSpine + ", currentSpine : " + currentSpine);
if (jumpSpine == currentSpine) {
int diffrence = currentPage - pageNumber;
Log.e(TAG, "diffrence > : " + diffrence);
Log.e(TAG, "pagenum - diffrence : " + (pageNum - diffrence));
this.pageNum = Math.max(pageNum - diffrence, 0);
updatePosition();
} else {
PageTurnerSpine spine = bookView.getSpine();
if (spine == null || !spine.navigateBackSpine(spine.getIndexFromPage(pageNumber))) {
return;
}
this.pageNum = 0;
gotoPage(pageNumber);
}
}
Log.e(TAG, "In last pageNum : " + pageNum);
}
PageTurnerSpine.java
public int getIndexFromPage(int pageNumber) {
int total = 0;
int totalIndex = 0;
for (List<Integer> pagesPerSection : pageOffsets) {
total += pagesPerSection.size();
totalIndex = totalIndex + 1;
if (total - 1 >= pageNumber) {
return totalIndex - 1;
}
}
return 0;
}
public int getUptoPage(int position) {
int total = 0, max = 0;
for (List<Integer> pagesPerSection : pageOffsets) {
max = max + 1;
if (position == max - 1) {
return total;
}
total += pagesPerSection.size();
}
return 0;
}
public int getPageOffSets(int position) {
int max = 0;
for (List<Integer> pagesPerSection : pageOffsets) {
max = max + 1;
if (position == max - 1) {
return pagesPerSection.size();
}
}
return 0;
}
public boolean navigateFrontSpine(int indexSpine) {
if (this.position == size() - 1) {
return false;
}
this.position = indexSpine;
return true;
}
public boolean navigateBackSpine(int indexSpine) {
if (this.position == 0) {
return false;
}
this.position = indexSpine;
return true;
}
When i apply this code and run some time it work correctly. but some time it jump on other page number, like if i enter 110 then it will jump on 109. and when i am trying to jump on chapter starting page then contain dose not changes. Please help me.
https://github.com/NightWhistler/PageTurner
In this source code i have edited some file given above. they already exists in this project.
Mostly i see that most of epub reader like Kindle, FBReader, etc... does not implement Go To Page feature. So, i want to also know that is it possible to implement this feature or not?
Thanks for Help :)
You really need to consult the IDPF Epub standards at IDPF.org/epub .
One approach, that I think is optional within the standard (but am not sure about) is to mark the content with the physical page numbers from the paper book (if there is one), or decide on your own numbering system along with your Table of Contents, and use a corresponding virtual page as the start of it.
This enables going to the start of the same page, but the number of virtual pages per physical page will vary, depending on font sizes etc. currently in use.
It's a data issue as much as a programming one.
I'm working on a minigames plugin. After an arena finishes it should be regenerated - I use the unload and load trick. It has an obvious disadvantage - it freezes the server for a while to prepare spawn areas. I decided to put the arena reset code into an runnable asynchronous task runTaskAsynchronously(). However, when the server tries to run the code inside the thread, it throws an exception:
Caused by: java.lang.IllegalStateException: Asynchronous entity world add!
Here's a part of my code:
getServer().getScheduler().runTaskAsynchronously(this, new Runnable()
{
#Override
public void run()
{
String w_name = world.getName();
getServer().unloadWorld(world.getName(), false);
world = getServer().createWorld(new WorldCreator(w_name));
}
});
Any suggestions how to deal with this problem?
Bukkit doesn't like it when you try to edit anything through the API in an async task. Reading and processing is fine but bukkit enforces nothing when it comes to thread safety and thus affecting the world with more than 1 thread can cause issues.
Try splitting up your arena reset into smaller chunks and spreading out the operation over several ticks with a series of synchronous tasks, might help with the performance.
This isn't my code but it does a decent job of demonstrating the idea https://gist.github.com/aadnk/5443172
-- You can load worlds async using this: http://pastebin.com/K9CuVMS5 --
No you cannot, and if you tried it would have a high chance of world corruption. But if you don't care about it this is what you can do:
Bukkit loads worlds via Bukkit.createWorld(WorldCreator) which activates Server.createWorld(WorldCreator) which activates:
Validate.notNull(creator, "Creator may not be null");
String name = creator.name();
ChunkGenerator generator = creator.generator();
File folder = new File(this.getWorldContainer(), name);
World world = this.getWorld(name);
WorldType type = WorldType.getType(creator.type().getName());
boolean generateStructures = creator.generateStructures();
if(world != null) {
return world;
} else if(folder.exists() && !folder.isDirectory()) {
throw new IllegalArgumentException("File exists with the name \'" + name + "\' and isn\'t a folder");
} else {
if(generator == null) {
generator = this.getGenerator(name);
}
WorldLoaderServer converter = new WorldLoaderServer(this.getWorldContainer());
if(converter.isConvertable(name)) {
this.getLogger().info("Converting world \'" + name + "\'");
converter.convert(name, new ConvertProgressUpdater(this.console));
}
int dimension = 10 + this.console.worlds.size();
boolean used = false;
do {
Iterator sdm = this.console.worlds.iterator();
while(sdm.hasNext()) {
WorldServer hardcore = (WorldServer)sdm.next();
used = hardcore.dimension == dimension;
if(used) {
++dimension;
break;
}
}
} while(used);
boolean var25 = false;
ServerNBTManager var24 = new ServerNBTManager(this.getWorldContainer(), name, true);
WorldData worlddata = var24.getWorldData();
if(worlddata == null) {
WorldSettings internal = new WorldSettings(creator.seed(), EnumGamemode.getById(this.getDefaultGameMode().getValue()), generateStructures, var25, type);
internal.setGeneratorSettings(creator.generatorSettings());
worlddata = new WorldData(internal, name);
}
worlddata.checkName(name);
WorldServer var26 = (WorldServer)(new WorldServer(this.console, var24, worlddata, dimension, this.console.methodProfiler, creator.environment(), generator)).b();
if(!this.worlds.containsKey(name.toLowerCase())) {
return null;
} else {
var26.scoreboard = this.getScoreboardManager().getMainScoreboard().getHandle();
var26.tracker = new EntityTracker(var26);
var26.addIWorldAccess(new WorldManager(this.console, var26));
var26.worldData.setDifficulty(EnumDifficulty.EASY);
var26.setSpawnFlags(true, true);
this.console.worlds.add(var26);
if(generator != null) {
var26.getWorld().getPopulators().addAll(generator.getDefaultPopulators(var26.getWorld()));
}
this.pluginManager.callEvent(new WorldInitEvent(var26.getWorld()));
System.out.print("Preparing start region for level " + (this.console.worlds.size() - 1) + " (Seed: " + var26.getSeed() + ")");
if(var26.getWorld().getKeepSpawnInMemory()) {
short short1 = 196;
long i = System.currentTimeMillis();
for(int j = -short1; j <= short1; j += 16) {
for(int k = -short1; k <= short1; k += 16) {
long l = System.currentTimeMillis();
if(l < i) {
i = l;
}
if(l > i + 1000L) {
int chunkcoordinates = (short1 * 2 + 1) * (short1 * 2 + 1);
int j1 = (j + short1) * (short1 * 2 + 1) + k + 1;
System.out.println("Preparing spawn area for " + name + ", " + j1 * 100 / chunkcoordinates + "%");
i = l;
}
BlockPosition var27 = var26.getSpawn();
var26.chunkProviderServer.getChunkAt(var27.getX() + j >> 4, var27.getZ() + k >> 4);
}
}
}
this.pluginManager.callEvent(new WorldLoadEvent(var26.getWorld()));
return var26.getWorld();
}
}
Now by creating you own world loader, you can make it so it only generates a chunk every tick or so.
I'm trying to display 550 data points with periodic peaks (the flat line is 61). The problem is, that androidplot isn't drawing all the points correctly! From my log:
ECG I values 61,61,62,63,62,61,61,61,61,67,71,68,61,53,61,61,61,61,61,61,61,61,62,63,64,64,64,63,62,61,61,61
I've got the rangeboundaries set to plot.setRangeBoundaries(0,100, BoundaryMode.AUTO);, but as you can see, the peaks never drop to the 53 data point. I can see this lower point sometimes, but it gets smoothed out a fraction of a second later (as you can see in the screenshot).
My line and point formatter is:
LineAndPointFormatter lapf = new LineAndPointFormatter(p.color, null, null, null);
lapf.getLinePaint().setStrokeJoin(Paint.Join.MITER);
lapf.getLinePaint().setStrokeWidth(1);
I've tried with the both Paint.Join.ROUND and Paint.Join.BEVEL and got the same effect. I've also used the debugger to check that 53 is being inserted into the series.
EDIT
After some debugging, it looks like my pulse loop thread is wrong:
while (keepRunning) {
for (PulseXYSeries j : series) {
for (int k = 0; k < j.plotStep; k++) {
int at = (j.position + k) % j.getSize();
if (j.pulsing) {
if (j.pulsePosition == j.pulseValues.size() - 1) {
j.pulsing = false;
j.pulsePosition = 0;
} else {
try {
int pulseVal = j.pulseValues.get(j.pulsePosition);
j.setY(pulseVal,at);
j.pulsePosition += 1;
} catch(IndexOutOfBoundsException e) {
j.pulsePosition = 0;
}
}
} else {
j.setY(j.pulseValues.get(0), at);
long currTime = SystemClock.elapsedRealtime();
if (currTime - j.getLastPulse() >= j.getPulseDelay()) {
j.pulsing = true;
j.setLastPulse(currTime);
}
}
j.remove(((at + j.eraserSize) % j.getSize()));
}
j.position = (j.position + 1) % j.getSize(); // fixed it by changing +1 to + j.plotStep
}
Thread.sleep(delay);
}
My custom series looks like:
private class PulseXYSeries implements XYSeries {
private List<Integer> pulseValues = new ArrayList<Integer>();
private int pulsePerMinute;
public int pulsePosition;
public int position;
private ArrayList<Integer> values;
private String title;
private long lastPulse;
public boolean pulsing = false;
public int eraserSize = 20;
public int plotStep = 3;
}