I have this game and it truly requires a load of item generation so I have it all being handled in an AsyncTask however this class is taking an extremely long time to execute sometimes while other times it take miliseconds... What is causing this to sometimes be fast and sometimes slow?
public class handleStuff extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... arg0) {
Random r = new Random();
if(r.nextInt(200) == 0 && clouds.size() <= 6)
{
Cloud c = new Cloud(SCREEN_WIDTH, SCREEN_HEIGHT, cloudBM1.getWidth(), cloudBM2.getHeight());
clouds.add(c);
}
for(int i = clouds.size() - 1; i > -1; i--)
{
Cloud tempC = clouds.get(i);
if(tempC.x <= 0 - cloudBM1.getWidth() && tempC.dir == 0)
clouds.remove(i);
if(tempC.x >= SCREEN_WIDTH && tempC.dir == 1)
clouds.remove(i);
}
if(System.currentTimeMillis() - lastESpawn >= 750)
{
Enemy x = new Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, enemy.getWidth(), enemy.getHeight());
enemies.add(x);
lastESpawn = System.currentTimeMillis();
}
for(int i = enemies.size() - 1; i > -1; i--)
{
Enemy tempE = enemies.get(i);
if(tempE.x <= 0 - enemy.getWidth())
enemies.remove(tempE);
}
for(int i = 0; i < enemies.size(); i++)
{
Enemy tempE = enemies.get(i);
if(System.currentTimeMillis() - tempE.lastBulletSpawn >= 800 && tempE.x <= SCREEN_WIDTH)
{
EnemyBullet eb = new EnemyBullet(tempE.x, tempE.y, enemyBullet.getWidth(), enemyBullet.getHeight(), enemy.getWidth(), enemy.getHeight());
enemyBullets.add(eb);
tempE.lastBulletSpawn = System.currentTimeMillis();
}
}
for(int i = bullets.size() - 1; i > -1; i--)
{
Bullet tempB = bullets.get(i);
if(tempB.x >= SCREEN_WIDTH)
bullets.remove(i);
}
for(int i = enemyBullets.size() - 1; i > -1; i--)
{
EnemyBullet tempEB = enemyBullets.get(i);
if(tempEB.x <= 0 - enemyBullet.getWidth())
enemyBullets.remove(i);
}
if(System.currentTimeMillis() - lastPBSpawn >= 400)
{
Bullet b = new Bullet(x, y, player.getWidth(), player.getHeight());
bullets.add(b);
lastPBSpawn = System.currentTimeMillis();
}
for(int i = explosions.size() - 1; i > -1; i--)
{
Explosion tempEx = explosions.get(i);
tempEx.update();
if(tempEx.duration <= 0)
explosions.remove(i);
}
initial_load = true;
return null;
}
}
Well, nobody likes debugging and I bet no one will make the tests themselves. That is up to you. So what you do is you log how long an operation takes. That is very easy. Some example code.
public class HandleStuffJob extends AsyncTask<String, Integer, String> {
private long mTime;
#Override
protected String doInBackground(String... params) {
startLogging();
try {
doSomeFancyStuff();
}
catch (InterruptedException e) {
e.printStackTrace();
}
stopLogging();
return null;
}
private void startLogging() {
mTime = System.currentTimeMillis();
}
private void doSomeFancyStuff() throws InterruptedException {
/*
* For this demonstration I will just sleep the thread and pretend it to
* do some work.
*/
Thread.sleep(1234);
}
private void stopLogging() {
long now = System.currentTimeMillis();
Log.d("Test", "The operation took " + (now - mTime) + " milliseconds or " + ((now - mTime) / 1000) + " seconds.");
}
}
And please only use Upper Case characters for class names.
Related
This question already has answers here:
Convert String to operator(+*/-) in java
(5 answers)
Closed 4 years ago.
How I convert String containing Mathematic arithmetic operation's like "10 + 20 - 25", I am getting String from EditText,I want to convert get the Result of operation.
Here is my code to resolve your problem:
public class ExecuteHandler {
private static Character[] OPERATORS = { '/', '*', '+', '-' };
private static final String REGEXOPERATORS = "[/+,-,/*,//,-]";
private static final String REGEXDIGITS = "(\\d+)";
private ArrayList<Character> operators = new ArrayList<>();
private ArrayList<Integer> digits = new ArrayList<>();
public String execute(String math) {
StringBuilder result = new StringBuilder();
try {
getDigits(math);
getOperators(math);
getNextOperator(operators);
for (Integer digit : digits) {
result.append(String.valueOf(digit));
}
} catch (ArithmeticException | IndexOutOfBoundsException e) {
return "ERROR";
}
return result.toString().isEmpty() ? "ERROR" : result.toString();
}
public void clear() {
operators.clear();
digits.clear();
}
private void getNextOperator(ArrayList<Character> operators) {
for (Character op : OPERATORS) {
for (int i = 0; i < operators.size(); i++) {
if (operators.get(i) == '/') {
operators.remove(i);
digits.set(i, (digits.get(i) / digits.get(i + 1)));
digits.remove(i + 1);
i -= 1;
}
}
for (int i = 0; i < operators.size(); i++) {
if (operators.get(i) == '*') {
operators.remove(i);
digits.set(i, (digits.get(i) * digits.get(i + 1)));
digits.remove(i + 1);
i -= 1;
}
}
for (int i = 0; i < operators.size(); i++) {
if (operators.get(i) == '+') {
operators.remove(i);
digits.set(i, (digits.get(i) + digits.get(i + 1)));
digits.remove(i + 1);
i -= 1;
}
}
for (int i = 0; i < operators.size(); i++) {
if (operators.get(i) == '-') {
operators.remove(i);
digits.set(i, (digits.get(i) - digits.get(i + 1)));
digits.remove(i + 1);
i -= 1;
}
}
}
}
private void getDigits(String math) {
Pattern r = Pattern.compile(REGEXDIGITS);
Matcher m = r.matcher(math);
while (m.find()) {
int t = Integer.parseInt(math.substring(m.start(), m.end()));
digits.add(t);
}
}
private void getOperators(String math) {
Pattern r = Pattern.compile(REGEXOPERATORS);
Matcher m = r.matcher(math);
while (m.find()) {
operators.add(math.charAt(m.start()));
}
}
}
Call method execute with input is string like "10 + 20 - 25:", the result will be a string of value (if success) or ERROR (if any syntax error).
For android Room, i need a type converter to save Location objects. Converting Locations to String is rather simple, e.g.:
public static String locationStringFromLocation(final Location location) {
if (location==null) return "Location was null";
return Location.convert(location.getLatitude(), Location.FORMAT_DEGREES) + " " + Location.convert(location.getLongitude(), Location.FORMAT_DEGREES);
}
But the other way around seems less obvious. I could append all the properties and separate them with a delimiter, but that seems not quite elegant. Any ideas would be appreciated.
My current workaround is to just save latitude and longitude, but I'd prefer to have the object.
public static Location locationFromString(String location){
if (location != null && (location.contains(","))) {
Location result = new Location("Generated_location");
String[] locationStrings = location.split(",");
if (locationStrings.length == 2) {
result.setLatitude(Double.parseDouble(locationStrings[0]));
result.setLongitude((Double.parseDouble(locationStrings[1])));
return result;
} else { return null; }
} else return null;
}
static Location parseLocationString(String locString){
if(locString != null && locString.contains("Location")) {
Location location = new Location("");
String rep = locString.replace("Location", "")
.replace("[", "")
.replace("]", "");
String[] k = rep.split(" ");
for (int part = 0; part < k.length; part++) {
String string = k[part];
if(part == 0)location.setProvider(string);
else if (part == 1){
String[] latlng = string.split(",");
if(latlng.length > 1){
location.setLatitude(Double.parseDouble(latlng[0]));
location.setLongitude(Double.parseDouble(latlng[1]));
}
}
else if (part > 1){
String[] locationDetails = string.split("=");
if (locationDetails.length > 1){
String locationKey = locationDetails[0];
String locationValue = locationDetails[1];
if (locationKey.contains("hAcc")) {
if (!locationValue.contains("?"))
location.setAccuracy((float)Float.parseFloat(locationValue));
}else if (locationKey.contains("et")){
if( !locationValue.contains("?") )
if(Build.VERSION.SDK_INT >= 17) {
if(locationValue.contains("+")) {
long days = 0, hours, min, sec, mill;
//separate string value
String nmbr = locationValue.split("\\+")[1];
String[] hr;
//isolate each value
String[] d = nmbr.split("d");
if(d.length > 1){
days = Long.parseLong(d[0]);
}
if(d.length > 1)
hr = d[1].split("h");
else
hr = nmbr.split("h");
if(hr.length > 1) {
hours = Long.parseLong(hr[0]);
}else hours = 0;
if(days > 0)
hours += 24*days;
String[] m;
if(hr.length > 1)
m = hr[1].split("m");
else
m = hr[0].split("m");
if(m.length > 1) {
if(m[0].length() > 0)
try {
min = Long.parseLong(m[0]);
}catch(NumberFormatException e){
min = 0;
}
else min = 0;
} else min= 0;
String[] s = m[0].split("s");
if(s.length > 1) {
sec = Long.parseLong(s[0]);
}else sec = 0;
if(min != 0 || hours != 0) {
String[] ms = s[0].split("ms");
if (ms.length >= 0 && !ms[0].contains("s")) {
mill = Long.parseLong(ms[0]);
} else mill = 0;
}else{
String ms = s[1];
if (ms.length() >= 0 && !ms.contains("s")) {
mill = Long.parseLong(ms);
} else mill = 0;
}
long millInNano = 1000000;
long nano = mill * millInNano;
nano += (sec * 1000) * millInNano;
nano += ((min * 60) * 1000) * millInNano;
nano += (((hours * 60) * 60) * 1000) * millInNano;
location.setElapsedRealtimeNanos(nano);
}
}
}else if (locationKey.contains("vel")) {
if (!locationValue.contains("?"))
location.setSpeed(Float.parseFloat(locationValue));
}else if (locationKey.contains("vAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setVerticalAccuracyMeters(Float.parseFloat(locationValue));
}else if (locationKey.contains("sAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setSpeedAccuracyMetersPerSecond(Float.parseFloat(locationValue));
}else if (locationKey.contains("bAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setBearingAccuracyDegrees(Float.parseFloat(locationValue));
}
}
}
}
return location;
}else{
return null;
}
}
ArrayList<String> list1 = splitFileList;
for (int i = 0; i < list1.size(); i++) {
tempFileName = splitFileList.get(i);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + list1.get(i) + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
below is my Asynktask which i am trying execute inside for loop
private class TrimmVideo extends AsyncTask<Void, Void, Void> {
private final String mediaPath;
private final double endTime;
private final int length;
private double startTime;
private ProgressDialog progressDialog;
private TrimmVideo(String mediaPath, int startTime, int length) {
this.mediaPath = mediaPath;
this.startTime = startTime;
this.length = length;
this.endTime = this.startTime + this.length;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(VideoPlayActvity.this,
"Trimming videos", "Please wait...", true);
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
trimVideo();
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
btn_save_video.setVisibility(View.INVISIBLE);
super.onPostExecute(result);
}
private void trimVideo() {
try {
File file = new File(mediaPath);
FileInputStream fis = new FileInputStream(file);
FileChannel in = fis.getChannel();
Movie movie = MovieCreator.build(in);
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can only start decoding
// at such a sample we SHOULD make sure that the start of the new fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
//throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
} else {
startTime = correctTimeToNextSyncSample(track, startTime);
timeCorrected = true;
}
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
// entry.getDelta() is the amount of time the current sample covers.
if (currentTime <= startTime) {
// current sample is still before the new starttime
startSample = currentSample;
} else if (currentTime <= endTime) {
// current sample is after the new start time and still before the new endtime
endSample = currentSample;
} else {
// current sample is after the end of the cropped video
break;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
movie.addTrack(new CroppedTrack(track, startSample, endSample));
}
IsoFile out = new DefaultMp4Builder().build(movie);
File storagePath = new File(getExternalFilesDir(null) + "/" + Constant.SPLIT_VIDEO + "/");
storagePath.mkdirs();
File myMovie = new File(storagePath, fileModel == null ? "/" + tempFileName + Constant.FILE_EXTENSION : fileModel.getfilename() + Constant.FILE_EXTENSION);
FileOutputStream fos = new FileOutputStream(myMovie);
FileChannel fc = fos.getChannel();
out.getBox(fc);
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
fc.close();
fos.close();
fis.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private double correctTimeToNextSyncSample(Track track, double cutHere) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
return timeOfSyncSample;
}
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}
}
splitFileList list Contain 2 Size data a,b i want to execute synchronously one by one i.e loop start from 0 then it should complete asynk task for 0 then if loop will go one then it should complete please suggest me how to execute asynk task one by one in for loop .
You can't run synchronously by AsyncTask You must use thread some thing like this:
Thread t = new Thread(
new Runnable() {
public void run() {
try {
ArrayList<String> list1 = splitFileList;
for (int i = 0; i < list1.size(); i++) {
tempFileName = splitFileList.get(i);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + list1.get(i) + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
trimVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)); //here you can run synchronously work
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
try {
t.join();
.....
} catch (Exception e) {
e.printStackTrace();
}
private void trimVideo(String mediaPath, int startTime, int length) {
try {
File file = new File(mediaPath);
FileInputStream fis = new FileInputStream(file);
FileChannel in = fis.getChannel();
Movie movie = MovieCreator.build(in);
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can only start decoding
// at such a sample we SHOULD make sure that the start of the new fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
//throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
} else {
startTime = correctTimeToNextSyncSample(track, startTime);
timeCorrected = true;
}
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
// entry.getDelta() is the amount of time the current sample covers.
if (currentTime <= startTime) {
// current sample is still before the new starttime
startSample = currentSample;
} else if (currentTime <= endTime) {
// current sample is after the new start time and still before the new endtime
endSample = currentSample;
} else {
// current sample is after the end of the cropped video
break;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
movie.addTrack(new CroppedTrack(track, startSample, endSample));
}
IsoFile out = new DefaultMp4Builder().build(movie);
File storagePath = new File(getExternalFilesDir(null) + "/" + Constant.SPLIT_VIDEO + "/");
storagePath.mkdirs();
File myMovie = new File(storagePath, fileModel == null ? "/" + tempFileName + Constant.FILE_EXTENSION : fileModel.getfilename() + Constant.FILE_EXTENSION);
FileOutputStream fos = new FileOutputStream(myMovie);
FileChannel fc = fos.getChannel();
out.getBox(fc);
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
fc.close();
fos.close();
fis.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private double correctTimeToNextSyncSample(Track track, double cutHere) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
return timeOfSyncSample;
}
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}
If you can't implement #Hazem answer you can go with another approach.
For this you need to maintain counter for each of your data and forget about for loop.
First you need to call asynctask for first position of your list.Something like this:
if(list1.size() > 0) {
fileCounter=0;
tempFileName = splitFileList.get(fileCounter);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + tempFileName + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
Then in onPostExecute of your asyncTask
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
dbHandler.updateFlag(fileModel == null ? tempFileName : fileModel.getfilename());
btn_save_video.setVisibility(View.INVISIBLE);
super.onPostExecute(result);
// Update your counter here
fileCounter++;
// Check if your incremented counter doesn't exceed your list size
if(fileCounter < list1.size()) {
// Then call your asynctask again with updated counter data
empFileName = splitFileList.get(fileCounter);
String splitFileCheckinDirectory = splitVideofilepath + Constant.SPLIT_VIDEO + "/" + tempFileName + Constant.FILE_EXTENSION;
File myfile = new File(splitFileCheckinDirectory);
if (!myfile.exists()) {
new TrimmVideo(getExternalFilesDir(null) + "/" + getFileNameFromFilePath(mFilePath), mStartTImelist.get(i), mEndTimelist.get(i) - mStartTImelist.get(i)).execute();
}
}
}
Hope this will help you.
How to compare app version in android
I got latest version code and current version code , but the problem is
current version is 1.0
and latest version is 1.0.0
so how to compare that float value in android
I have written a small Android library for comparing version numbers: https://github.com/G00fY2/version-compare
What it basically does is this:
public int compareVersions(String versionA, String versionB) {
String[] versionTokensA = versionA.split("\\.");
String[] versionTokensB = versionB.split("\\.");
List<Integer> versionNumbersA = new ArrayList<>();
List<Integer> versionNumbersB = new ArrayList<>();
for (String versionToken : versionTokensA) {
versionNumbersA.add(Integer.parseInt(versionToken));
}
for (String versionToken : versionTokensB) {
versionNumbersB.add(Integer.parseInt(versionToken));
}
final int versionASize = versionNumbersA.size();
final int versionBSize = versionNumbersB.size();
int maxSize = Math.max(versionASize, versionBSize);
for (int i = 0; i < maxSize; i++) {
if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return 1;
} else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
return -1;
}
}
return 0;
}
This snippet doesn't offer any error checks or handling. Beside that my library also supports suffixes like "1.2-rc" > "1.2-beta".
I am a bit late to the party but I have a great solution for all of you!
1. Use this class:
public class VersionComparator implements Comparator {
public boolean equals(Object o1, Object o2) {
return compare(o1, o2) == 0;
}
public int compare(Object o1, Object o2) {
String version1 = (String) o1;
String version2 = (String) o2;
VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
VersionTokenizer tokenizer2 = new VersionTokenizer(version2);
int number1, number2;
String suffix1, suffix2;
while (tokenizer1.MoveNext()) {
if (!tokenizer2.MoveNext()) {
do {
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
if (number1 != 0 || suffix1.length() != 0) {
// Version one is longer than number two, and non-zero
return 1;
}
}
while (tokenizer1.MoveNext());
// Version one is longer than version two, but zero
return 0;
}
number1 = tokenizer1.getNumber();
suffix1 = tokenizer1.getSuffix();
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number1 < number2) {
// Number one is less than number two
return -1;
}
if (number1 > number2) {
// Number one is greater than number two
return 1;
}
boolean empty1 = suffix1.length() == 0;
boolean empty2 = suffix2.length() == 0;
if (empty1 && empty2) continue; // No suffixes
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)
// Lexical comparison of suffixes
int result = suffix1.compareTo(suffix2);
if (result != 0) return result;
}
if (tokenizer2.MoveNext()) {
do {
number2 = tokenizer2.getNumber();
suffix2 = tokenizer2.getSuffix();
if (number2 != 0 || suffix2.length() != 0) {
// Version one is longer than version two, and non-zero
return -1;
}
}
while (tokenizer2.MoveNext());
// Version two is longer than version one, but zero
return 0;
}
return 0;
}
// VersionTokenizer.java
public static class VersionTokenizer {
private final String _versionString;
private final int _length;
private int _position;
private int _number;
private String _suffix;
private boolean _hasValue;
VersionTokenizer(String versionString) {
if (versionString == null)
throw new IllegalArgumentException("versionString is null");
_versionString = versionString;
_length = versionString.length();
}
public int getNumber() {
return _number;
}
String getSuffix() {
return _suffix;
}
public boolean hasValue() {
return _hasValue;
}
boolean MoveNext() {
_number = 0;
_suffix = "";
_hasValue = false;
// No more characters
if (_position >= _length)
return false;
_hasValue = true;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c < '0' || c > '9') break;
_number = _number * 10 + (c - '0');
_position++;
}
int suffixStart = _position;
while (_position < _length) {
char c = _versionString.charAt(_position);
if (c == '.') break;
_position++;
}
_suffix = _versionString.substring(suffixStart, _position);
if (_position < _length) _position++;
return true;
}
}
}
2. create this function
private fun isNewVersionAvailable(currentVersion: String, latestVersion: String): Boolean {
val versionComparator = VersionComparator()
val result: Int = versionComparator.compare(currentVersion, latestVersion)
var op = "=="
if (result < 0) op = "<"
if (result > 0) op = ">"
System.out.printf("%s %s %s\n", currentVersion, op, latestVersion)
return if (op == ">" || op == "==") {
false
} else op == "<"
}
3. and just call it by
e.g. isNewVersionAvailable("1.2.8","1.2.9") where 1.2.8 is your current version here and 1.2.9 is the latest version, which returns true!
Why overcomplicate this so much?
Just scale the major, minor, patch version and you have it covered:
fun getAppVersionFromString(version: String): Int { // "2.3.5"
val versions = version.split(".") // [2, 3, 5]
val major = versions[0].toIntOrDefault(0) * 10000 // 20000
val minor = versions[1].toIntOrDefault(0) * 1000 // 3000
val patch = versions[2].toIntOrDefault(0) * 100 // 500
return major + minor + patch // 2350
}
That way when you compare e.g 9.10.10 with 10.0.0 the second one is greater.
Use the following method to compare the versions number:
Convert float to String first.
public static int versionCompare(String str1, String str2) {
String[] vals1 = str1.split("\\.");
String[] vals2 = str2.split("\\.");
int i = 0;
// set index to first non-equal ordinal or length of shortest version string
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
}
// compare first non-equal ordinal number
if (i < vals1.length && i < vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
return Integer.signum(diff);
}
// the strings are equal or one string is a substring of the other
// e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
return Integer.signum(vals1.length - vals2.length);
}
Refer the following SO question : Efficient way to compare version strings in Java
I am new to programming and I'm making a very simple blackjack game with only basic functions. When I run the program on the emulator it runs maybe for one hand, two, sometimes 5 or more but it always stops responding at some stage when i click on one of the three butons. There is a splash screen that runs for three seconds and the there is a thread comming from that activity that starts this menu activity. Could anyone maybe tell why this is happening? It usually happens when I clcik on one of the buttons even though there is no much comput
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btDeal = (Button) findViewById(R.id.deal);
playerCards1 = (TextView) findViewById(R.id.playerCards);
playerPoints = (TextView) findViewById(R.id.playerPoints);
dealerCards1 = (TextView) findViewById(R.id.dealerCard);
mpBusted= MediaPlayer.create(this, R.raw.busted);
mpWin = MediaPlayer.create(this, R.raw.win);
mpShuffling = MediaPlayer.create(this, R.raw.shuffling);
mpEven = MediaPlayer.create(this, R.raw.even);
mpHit= MediaPlayer.create(this, R.raw.hit);
btDeal.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
deal ();
}
}); //getTotalDealerCards()
//getTotalPlayerCards()
btHit = (Button) findViewById(R.id.hit);
btHit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Boolean busted = isBusted();
if(!busted){
hitPlayer();
playerCards1.setText(getPlayerCardsToString());
if (isBusted()){
mpBusted.start();
}else{
playerCards1.setText(getPlayerCardsToString());
playerPoints.setText(Integer.toString(getTotalPlayerPoints()));
}
}
}
});
btStand = (Button) findViewById(R.id.stand);
btStand.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
checkWinner();
}// testValue(getTotalPlayerCards())
});
}
/*********** Function declarations starts here **********/
//Sum and return the total points for the dealer cards
public int getTotalDealerPoints(){
int points = 0;
int aceFlag = 0; //flag to deal with Aces
int counter;
for (counter = 0; counter <= getTotalDealerCards(); counter++){
if (dealerCards [counter].getCard() + 1 == 1){
points += 11;
aceFlag++;
}
else if (dealerCards [counter].getCard() + 1 > 10)
points += 10;
else
points += dealerCards [counter].getCard() + 1;
}
do {
if (points > 21 && aceFlag > 0){
points -= 10;
aceFlag--;
}
} while (aceFlag>0);
return points;
}
//Get the total player points deal
public int getTotalPlayerPoints(){
int points = 0;
int aceFlag = 0; //flag to deal with Aces
int counter;
for (counter = 0; counter <= getTotalPlayerCards(); counter++){
if (playerCards [counter].getCard() + 1 == 1){
points += 11;
aceFlag++;
}
else if (playerCards [counter].getCard() + 1 > 10)
points += 10;
else
points += playerCards [counter].getCard() + 1;
}
do {
if (points > 21 && aceFlag > 0){
points -= 10;
aceFlag--;
}
} while (aceFlag>0);
return points;
}
//Deal function to start hand
public void deal (){
// If deal is pressed reset all and start over.
mpShuffling.start();
totalDealerPoints = 0;
totalPlayerPoints = 0;
totalCreatedCards = 0;
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
// create dealer & player cards and save them to dealer, player and total arrays.
for (int dealcounter = 0; dealcounter <=1 ; dealcounter++){
dealerCards[dealcounter]= createCard();
addCardToCreatedCards(dealerCards[dealcounter]);
playerCards[dealcounter] = createCard();
addCardToCreatedCards(playerCards[dealcounter]);
}
String theCards = getPlayerCardsToString();
String dealerCard = dealerCards[0].toString();
String playerpoints= Integer.toString(getTotalPlayerPoints());
playerCards1.setText(theCards);
dealerCards1.setText(dealerCard);
playerPoints.setText(playerpoints);//getTotalPlayerPoints()
while (getTotalDealerPoints() < 16){
hitDealer();
}
}
// Create card and validate against existing before returning object.
public Card createCard(){
int counter2 = 0;
int flag = 0;
int value;
int suit;
do {
flag = 0;
suit = randomer.nextInt(4);
value = randomer.nextInt(13);
// validate against permitted values before creating cards
while (counter2 <= getTotalPlayerCards()) {
if (createdCards[counter2].getSuit() == suit && createdCards[counter2].getCard() == value || suit > 3 || suit < 0 || value > 12 || value < 0){
flag = -1;
}
counter2++;
}
} while (flag != 0);
Card theCard = new Card (suit, value);
return theCard;
}
// Add card to the records of created cards
public void addCardToCreatedCards(Card aCard){
createdCards [totalCreatedCards] = aCard;
totalCreatedCards++;
}
// Add a card to dealers cards
public void hitPlayer(){
//If the hand was started add card, else deal to start hand.
if (getTotalPlayerCards()+1 != 0){
mpHit.start();
playerCards [getTotalPlayerCards()+1] = createCard();
addCardToCreatedCards(playerCards [getTotalPlayerCards()]);
}
else
deal();
}
// Create a new card for the dealer
public void hitDealer(){
dealerCards [getTotalDealerCards()+1] = createCard();
addCardToCreatedCards(dealerCards [getTotalDealerCards()]);
}
public String getPlayerCardsToString(){
String cards = "";
int total = getTotalPlayerCards();
if (getTotalPlayerPoints() <=21){
int counter = 0;
while (counter <= total){
cards += playerCards[counter].toString() + " ";
counter++;
}
return cards;
}else {
int counter=0;
while (counter <= total){
cards += playerCards[counter].toString() + " ";
counter++;
}
return cards;
}
}
public int getTotalPlayerCards(){
int initialCount = 0;
while (playerCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public int getTotalDealerCards(){
int initialCount = 0;
while (dealerCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public int getTotalCreatedCards(){
int initialCount = 0;
while (createdCards[initialCount] != null){
initialCount++;
}
return initialCount-1;
}
public Boolean isBusted(){
Boolean busted = false;
if (getTotalPlayerPoints()>21){
busted=true;
totalDealerPoints = 0;
totalPlayerPoints = 0;
mpBusted.start();
playerPoints.setText("You were busted!!");
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
}
return busted;
}
//Check for winner
public void checkWinner(){
if (getTotalDealerPoints() <= 21 || getTotalPlayerPoints() <= 21 && !isBusted()){
if (getTotalDealerPoints() > 21 || getTotalDealerPoints() < getTotalPlayerPoints()){
playerPoints.setText("You won!!");
mpWin.start();
}
else if(getTotalDealerPoints() > getTotalPlayerPoints()){
mpBusted.start();
playerPoints.setText("You were busted!!");
for (int i = 0; i < TOTAL_CARDS; i++){
dealerCards [i] = null;
playerCards [i] = null;
createdCards [i] = null;
}
}
else{
mpEven.start();
playerCards1.setText("We have same points!");
}
}
else {
deal ();
}
}
}
Use the debugger in eclipse to find out where it gets frozen.
Also the android emulator is very slow even with a fast PC.
Try using the low resolution simulators.
open DDMS from the android-sdk\tools and check which method or thread is taking more time to execute.
Use AsyncTask or Handler when there is a functional(Computational) things running.