I have 4 buttons, that each one of them doe's a different action (lets say each action takes 2 minutes)
When I click both buttons (with few minutes between them), both of them still get inside the 'if' part, although the flag i put.
Here is part of my code:
southToNorth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
north.incCounter();
north.setWaitingState(true);
pushToQueue(1);
if (isWorking==0) {
isWorking++;
start();
}
}
});
westToEast.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
east.incCounter();
east.setWaitingState(true);
pushToQueue(2);
if (isWorking==0) {
isWorking++;
start();
}
}
});
I Don't think that is a synchronization problem, i even put this code at the top of the start function:
private void start() {
if(isWorking>1)
return;
but still, both of them doe's all of the start function, what I'm trying to avoid.
(I have a global flag "int isWorking" initialized to zero )
Why both of them are getting inside the if part? How can I solve it?
Thank you very much!
A global flag should do it. You say you've tried it, but you haven't actually provided how you tried it, so I can't specifically help with that.
Make two variables and some static fields:
private static final int ACTION_NONE = -1;
private static final int ACTION_ONE = 0;
private static final int ACTION_TWO = 1;
private static final int ACTION_THREE = 2;
private static final int ACTION_FOUR = 3;
private boolean actionRunning = false;
private int queuedAction = ACTION_NONE;
When you try to run an action, check if there's currently an action running:
if (actionRunning) {
queuedAction = /* the corresponding static field */;
} else {
queuedAction = ACTION_NONE;
actionRunning = true;
}
Then, when whatever action you're using completes, run the appropriate queued action:
switch (queuedAction) {
case ACTION_ONE:
//run action 1
break;
case ACTION_TWO:
//etc
...
}
Related
Here is my code:
public void haritaDegerAtama(final Button b, final int deger, final int deger_b){
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(deger_b==0){
b.setBackgroundColor(getResources().getColor(R.color.acik_mavi));
deger_b=deger;
}else{
b.setBackgroundColor(getResources().getColor(R.color.acik_gri_ton1));
deger_b=0;
}
}
});
}
There are 120 buttons in my project. Because of that I want to prepare a function instead of to write onClickListener for all each button. But I am facing a problem in my code. The error is deger_b variable can't change because it's
a final variable. But I need to change değer_b variable.
How can I do that?
The final keyword is used in several contexts to define an entity that can only be assigned once. In your codes:
deger_b=deger;
deger_b=0;
will cause compiler errors. Remove final keyword before deger_b parameter.
i think you put final keyword for accessing the variable in inner scope but the final keyword prevents to reassign the variable so you ca change it to a property in your class and then use it in your function.
for example :
class YourClass{
private int deger_b = 0;
.
.
.
public void haritaDegerAtama(final Button b, final int deger){
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(deger_b==0){
b.setBackgroundColor(getResources().getColor(R.color.acik_mavi));
deger_b=deger;
}else{
b.setBackgroundColor(getResources().getColor(R.color.acik_gri_ton1));
deger_b=0;
}
}
});
}
.
.
.
}
I am developing an Android app that is recognising the activity the user us doing every 3 seconds (has to be that frequent by design) (e.g. static, walking, running). I have an Activity table in my database that increments the following values:
private int activeTime;
private int longestInactivityInterval;
private int currentInactivityInterval;
private int averageInactInterval;
Those are presented in a fragment. Currently, it is very "sensitive". For example, if the user is static (i.e. laying on their bed) and they pull their phone out of the pocket it will recognise activity like "walking". The history of recognised activities would look like that:
static
static
walking
static
static
How can I make sure that this incidental "walking" recognised activity is recognised as "static". Is there a way how I can correct that?
This is the class that is doing the Activity monitoring (incrementing values depending on what activity is recognised.
public class ActivityMonitor implements Observer, IActivityMonitor {
private User mUser;
private IActivityDataManager mDataManager;
public ActivityMonitor(IActivityDataManager dataManager) {
mDataManager = dataManager;
}
#Override
public void update(Observable observable, Object activity) {
monitorActivity(activity);
}
private void monitorActivity(Object activityClass) {
switch ((int) activityClass) {
case 0:
//activity = "walking";
case 1:
//activity = "running";
case 3:
//activity = "cycling";
mDataManager.incActiveTime();
mDataManager.clearCurrentInacInterval();
break;
case 2:
//activity = "static";
mDataManager.incCurrentInacInterval();
break;
}
}
I found a solution to the problem myself. I am using apache's common CircularFifoQueue with set size to 2.
This is how my solution looks like:
private void monitorActivity(Object activityClass) {
int activityInt = (int) activityClass;
correctionList.add(activityInt);
int correctResult = applyCorrection(activityInt);
if (correctResult == correctionList.size()) {
mDataManager.incActiveTime();
mDataManager.clearCurrentInacInterval();
} else {
mDataManager.incCurrentInacInterval();
}
}
private int applyCorrection(int classInt) {
int count = 0;
for (int item : correctionList) {
if (item == 0 || item == 1 || item == 3) {
count++;
}
}
return count;
}
Basically, it adds the classInt which could be (0,1,2 or 3) - walking = 0, running = 1, cycling = 3 and static = 2. The applyCorrection method looks through the queue with size 2 (this plays the role of the factor, 2 works great for me) and counts and checks the integers. If the returned count correctResult is 2 that means that the activity is for sure of time ACTIVE (1,2,3) and not STATIC (2).
I'm looking for a way to create a "header" or something like that to specify some variables like:
enum Misc
{
double EFFECT_DAMAGE = Math.pow(2,0);
double EFFECT_ABSORB = Math.pow(2,1);
double EFFECT_HEAL = Math.pow(2,2);
int SPELL_FIREBALL = 51673;
}
And in every .java file I want to be able to write:
double effect = 1;
if (effect == EFFECT)
{
...some code...
}
Is there a nice way to do this?
I'm creating a mini game for now and want to have all the files nice and tidy to manage my project in the future easier once it gets bigger.
Thx in advance.
public enum Misc
{
EFFECT_DAMAGE(0), // 2^0
EFFECT_ABSORB(1), // 2^1
FIREBALL(245151);
private double value;
private Misc(double d){
value = d;
}
public String toString(){
return String.valueOf(value);
}
}
Access like this:
System.out.println("Fireball damage:" + Misc.FIREBALL);
You cannot assign values this way to a enum in java.
Instead you should use a public class with public static final variables to make them constants.
public class Misc {
public static final double EFFECT_DAMAGE = Math.pow(2,0);
public static final double EFFECT_ABSORB = Math.pow(2,1);
public static final double EFFECT_HEAL = Math.pow(2,2);
public static final int SPELL_FIREBALL = 51673;
}
So you can use in your code like
if (effect == Misc.EFFECT_DAMAGE )
{
...some code...
}
If you want use only the field without the class name first you should import the class as static:
import static test.Misc.*;
....
if (effect == EFFECT_DAMAGE ) {
I have this class that creates threads, but I want to convert that class into Service hoping it wont be destroyed on orientation change.
Here is the class:
public class Getter {
private final String ip;
private final int amount, poolSize;
private Vector<Integer> results = new Vector<Integer>();
private final ExecutorService es;
private Collection<Future<?>> futures = new LinkedList<Future<?>>();
public Getter(String ip, int amount, int poolSize) {
this.ip = ip;
this.amount = amount;
this.poolSize = poolSize;
es = Executors.newFixedThreadPool(this.poolSize);
}
public boolean working() {
boolean work = false;
for (Future<?> future : futures) {
if (!future.isDone()) {
work = true;
}
}
return work;
}
public Vector<Integer> getResults() {
Collections.sort(results);
return results;
}
public int threads(){
return poolSize;
}
public void start() {
for (int i = 0; i <= amount; i++) {
futures.add(es.submit(new Get(ip)));
}
es.shutdown();
}
public void stop(){
for (Future<?> future : futures) {
future.cancel(true);
}
}
private class Get implements Runnable {
private String ip;
private Get(String ip) {
this.ip = ip;
}
public void run() {
try {
// network stuff
// adds result to results Vector.
} catch (Exception ex) {
}
}
}
}
so is this class possible to convert into Service so it would run on background no matter what, once its started?
you can add this to a manifest file that stops your app getting destroyed on orientation change:
android:configChanges="orientation"
but if you want to make a service then just copy this example:
http://developer.android.com/reference/android/app/Service.html
you could add the class to the service and then just add an accessor to your service connection.
You can also add something to the manifest file to let your service start when the device is turned on
see here
Trying to start a service on boot on Android
If you want a Service which runs "no matter what", you might want to set it as foreground.
Yes. I think this would make a good IntentService. Your next-best choice is probably AsyncTask.
More:
Generally, I would say, if the behavior of the background task is closely tied to whatever starts it (e.g., an Activity, Fragment, Service, whatever), then make it an AsyncTask. If it is self-contained and meant to serve several different components in a modular fashion, make it a Service. In either case, an AsyncTask or IntentService is very easy to make.
One of the Activities in my app starts/binds to a service (also part of my app). I would like that service to continue running as long as the app as a whole is still in the foreground, regardless of which Activity is active. But I need to make sure that the service is stopped when the app as a whole is paused (home button/back button).
How can I do that on an application level rather than an Activity level?
The easiest way is to have a singleton which keeps a track of the state of each activity, e.g showing just one activity as an example:
public class ActivityStates {
private static ActivityStates ref = null;
private static int firstAct = ACTIVITY_GONE;
public static synchronized ActivityStates getInstance() {
if (ref == null) {
ref = new ActivityStates();
}
return ref;
}
public int getFirstAct() {
return firstAct;
}
public void setFirstAct(int arg) {
this.firstAct = arg;
}
}
..
and define some static constants that you can import
public static final int ACTIVITY_GONE = 0;
public static final int ACTIVITY_BACKGROUND = 1;
public static final int ACTIVITY_FOREGROUND = 2;
then in each activity have a method
private void setActivityState(int state){
ActivityStates as = ActivityStates.getInstance();
as.setFirstAct(state);
}
Then in your onResume(), onPause, onDestroy() you can set the activitiy's state when you enter these methods, e.g in onResume have
setActivityState(ACTIVITY_FOREGROUND)
in onDestroy() have
setActivityState(ACTIVITY_GONE)
Then in you service, or wherever you want , you can use the get methods to find out the state of each activity and decide what to do.