Android, Use Timer to do a task at different times? - android

I searched other posts and I didn't find a case matching my problem, so please do not refer me to other posts.
I have a list of hundreds of different times starting like the below list:
timeList = {5, 13, 21, 40, ...}.
Suppose that they are saved in an arraylist. That means some task must be executed at 5 secs, 13 secs,... from a starting point . How can I use a Timer or any other way to achieve this?
Also I may have the timeList in a format like this if it helps:
timeList = {8:05, 8:13, 8:21, 8:40, ...}.
My current timer is like this:
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
synchronized public void run() {
//do some task
}
}, startPoint, Period);
But this is obviously working at fixed rate!

By using Timer.schedule(TimerTask task, long delay), set all your timers and wait for them to execute
Assuming you are getting in MM:SS format (ex: 8:58):
ArrayList<String> your_arraylist = new ArrayList<String>();
//your list above, fill it with MM:SS
final ArrayList<Long> seconds = new ArrayList<Long>();
final ArrayList<Long> minutes = new ArrayList<Long>();
long first_minute;
for (String time : your_arraylist) {
minutes.add(Long.parseLong(time.split(":")[0]));
seconds.add(Long.parseLong(time.split(":")[1]));
}
first_minute = minutes.get(0);
for (int i = 0; i < seconds.size(); i++) {
long waiting_duration;
if (seconds.get(i) < Calendar.SECOND) {
waiting_duration = (60 - Calendar.SECOND + seconds.get(i)) * 1000;
}
else {
waiting_duration = (seconds.get(i) - Calendar.SECOND) * 1000;
}
waiting_duration += (minutes.get(i) - first_minute) * 60 * 1000;
Timer timer = new Timer();
TimerTask timer_task = new TimerTask() {
#Override
public void run() {
// do jobs
}
};
timer.schedule(timer_task, waiting_duration);
}

Don't use Timer use a Handler instead.
private int[] mTimeList = {5000, 2000, 7000, 4000};
private int mCount;
private int mDelay;
private Handler mHandler = new Handler();
private void initRepeatedTimer() {
mHandler.postDelayed(new Runnable() {
public void run() {
Log.e(TAG, "run: " + mCount);
mDelay = mTimeList[mCount];
if (mCount < mTimeList.length - 1)
mCount++;
else
mCount = 0;
mHandler.postDelayed(this, mDelay);
}
}, mDelay);
}
You wil notice that the log is printed as per delay in the list.

Related

Android studio runnable, threads

I have two options to execute my program (I need to have Out_str as a result).
Option 1:
Out_str = "";
for (i = 1; i <= 20000; i++) {
Out_str = Out_str + "word";
}
Option2:
Runnable runnable1 = new Runnable() {
public void run() {
Out_str1 = "";
for (i1 = 1; i1 <= 10000; i1++) {
Out_str1 = Out_str1 + "word";
}
}
};
Runnable runnable2 = new Runnable() {
public void run() {
Out_str2 = "";
for (i2 = 1; i2 <= 10000; i2++) {
Out_str2 = Out_str2 + "word";
}
}
};
Thread thread1 = new Thread(runnable1);
thread1.start();
Thread thread2 = new Thread(runnable2);
thread2.start();
Why using threads does not make my program execute faster (in both cases the execution takes approx 12 sec with my laptop)? What shall I use in this case (to make it faster to obtain Out_str)? Will using services make help in this case?
The Thread allows you to run processes concurrently. You haven't gained any processing power though, with equal priority your threads would be run in a round-robin way I would guess.

Calculating data rate per second but the result always the same

Iam calculating the cellular data rate per second by using Handler, the code is being executed every second and the overall traffic been calculated then it suppose to subtract the old traffic since boot from the current traffic since boot to get the current data rate per second.
The problem I'm facing that the current data rate value is not correct, it is always giving me the total overall traffic since boot. May be I did something wrong, I'm still beginner with android. The code below.
public class MainActivity extends AppCompatActivity {
private double RXOld;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
////////////////////////Code to be executed every second////////////////////////////////////////
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
double overallTraffic = TrafficStats.getMobileRxBytes();
double currentDataRate = overallTraffic - RXOld;
TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
view1.setText("Current Data Rate per second= " + currentDataRate);
double RXOld = overallTraffic;
handler.postDelayed(this, 1000);
}
}, 1000 );
}
The new Code after rectification which shall give the current data rate per second
public class MainActivity extends AppCompatActivity {
final double [] RXOld = new double [1];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
////////////////////////Code to be executed every second////////////////////////////////////////
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
double overallTraffic = TrafficStats.getMobileRxBytes();
double currentDataRate = overallTraffic - RXOld [0];
TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
view1.setText("Current Data Rate per second= " + currentDataRate);
RXOld [0] = overallTraffic;
handler.postDelayed(this, 1000);
}
}, 1000 );
First of all, consider using a Timer, and declare the TextView at the beginning. I think this code should work, but I didn't test it:
final TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
final double[] oldT = new double[1];
Timer timer1 = new Timer();
TimerTask tt1 = new TimerTask() {
#Override
public void run() {
double overallTraffic = TrafficStats.getMobileRxBytes();
double trafficRate = overallTraffic - oldT[0];
oldT[0] = overallTraffic;
view1.setText("Current Data Rate per second= " + trafficRate);
}
};
timer1.scheduleAtFixedRate(tt1,1000,1000);
Note: if you use a new variable into the run() of the TimerTask, the variable MUST be declared final. You can easyly change its value by makeing the variable an array of 1 element ('int[] varName = new int[1]' instead of 'int varName'), and using varName[0] instead of varName

Change color after specific time

How is it possible to make an app that changes between color automatically after specific time. My code doesn't work for some reason
Random r = new Random();
Timer t = new Timer();
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
long m = System.nanoTime();
int seconds = (int) (m/1000);
if(seconds <= 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
For ex. the screen is black and after specific time white. And that the time decreases itslef, the changing goes faster.
Please try the following code for the color change.
Use the countdown timer for changing the color with condition.
new CountDownTimer(5000,1000)
{
onFinish()
{
if(flag==1)
{
//color set black
flag=0;
//start the countdown timer again.
}
else
{
//color set white
flag=1;
//start the countdown timer again.
}
}
}
Try following the code
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
//Adding Log Statement to check
Log.i(Tag, String.valueOf(seconds);
if(seconds % 10 < 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
You are trying to convert nanoseconds to seconds, but actually you are doing is not the same!!
try
int seconds = (int) (m/1000000000);
to convert to nan0-seconds to seconds
EDIT:
if you just want to keep changing color use this code:
public static int color = 1;
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
and its definition:
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
if(color == 1){
ll.setBackgroundColor(Color.BLACK);
color = 2;
}else{
ll.setBackgroundColor(Color.WHITE);
color = 1;
}
customHandler.postDelayed(this, 5000);// will repeat after 5 seconds
}
};
You can use tread to manage this, try this . thread will be the best way to achieve this, since you want to continuously change the color at regular interval.
Handler handler ;
LinearLayout ll ;
int i = 0;
int colors[] = {Color.BLACK, Color.WHITE, Color.BLUE, Color.GREEN, Color.GRAY};
Runnable runnable = new Runnable() {
#Override
public void run() {
ll.setBackgroundColor(colors[i]);
i++;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
.......
handler = new Handler();
ll = (LinearLayout) findViewById(R.id.ll);
Thread myTread = new Thread(){
public void run() {
try {
while(true){
sleep(3000);
handler.post(runnable);
}
}
catch (InterruptedException e) {}
}
};
myTread.start();
}
the code will change the background color every 3secssleep(3000) as written in the code. also each time it changes it select from a set of pre-define color array.
you can also use random generation of colors. either you randomly generate the rgb values or you can store the colors in an array as i have done and randomly iterate over it

ImageSlider Using Thread

I want slider in my imageview but it gives me only one image at a time if any one of you have a solution please tell me.
here in my activity class.
images come from the API and there is a whole path of every image and its a web url
ArrayList<String> imagepath1 = i.getExtras().getStringArrayList("event_photo");
for (int i1 = 0; i1 < imagepath1.size(); i1++) {
stockArr = new String[imagepath1.size()];
stockArr = imagepath1.toArray(stockArr);
// imagepath = stockArr.toString();
String imagepath = stockArr[i1];
}
if (!TextUtils.isEmpty(imagepath)) {
if (imagepath.endsWith(".jpeg") || imagepath.endsWith(".jpg")
|| imagepath.endsWith(".gif") || imagepath.endsWith(".png")) {
imageLoader = new ImageLoader(mcontext);
mUpdateResults = new Runnable() {
public void run() {
Animation rotateimage = AnimationUtils.loadAnimation(
getApplicationContext(), R.anim.alpha);
for (int i2 = 0; i2 < stockArr.length; i2++) {
imageLoader.DisplayImage(imagepath1.get(i2),
imagetop);
// imagetop.startAnimation(rotateimage);
/*imagetop.setImageResource(number[currentimageindex
% stockArr.length]);*/
}
}
};
final Handler mHandler = new Handler();
int delay = 500; // delay for 1 sec.
int period = 5000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
mHandler.post(mUpdateResults);
}
}, delay, period);
} else {
}
}
Please Help if any one have a solution

Stopwatch developed by me is lagging behind other standard stopwatch by 8-10 seconds & increases

I have developed a stopwatch in Android . The stopwatch has the feature of Lap calculation too.
I have started the stopwatch . I tested the stopwatch developed by me with multiple standard stopwatches . The problem is that after 1 minutes , the stopwatch developed keeps lagging behind the other stopwatches & the difference keeps on increasing. I got around 8-10 seconds lagging after the 3 minutes.
The following code I am using:
Two classes I am using , one for the Stopwatch implementation & the other for Stopwatch display
StopwatchImplementation.java
/** The timer used to implement the Stopwatch logic. */
private Timer mSWatch = null;
/**
* Starts the Stopwatch.
*/
public void watchStart() {
if (mSWatch != null)
mSWatch .cancel();
mSWatch = new Timer();
mSWatch .schedule(new TimerTask() {
#Override
public void run() {
mListener.updateUIThread();
}
}, 0, 100);
}
/** Runnable The Timer_ tick where the time is updated */
Runnable Timer_Tick = new Runnable() {
public void run() {
updateTime(); // Updates the time , calculates the lap duration
}
};
private int mHours = 0;
/** The mins. */
private int mMins = 0;
/** The secs. */
private int mSecs = 0;
/** The fraction of a sec. */
private int mFSec = 0;
/** The lap hours. */
private int mLapHours = 0;
/** The lap mins. */
private int mLapMins = 0;
/** The lap secs. */
private int mLapSecs = 0;
/** The lap fraction of sec.... 1/10th of a sec*/
private int mLapFSec = 0;
public void updateTime() {
try {
mLapFSec++;
if (mLapFSec >= 10) {
mLapFSec = 0;
mLapSecs++;
if (mLapSecs >= 60) {
mLapSecs = 0;
mLapMins++;
if (mLapMins >= 60) {
mLapMins = 0;
mLapHours++;
}
}
}
mFSec++;
if (mFSec >= 10) {
mFSec = 0;
mSecs++;
if (mSecs >= 60) {
mSecs = 0;
mMins++;
if (mMins >= 60) {
mMins = 0;
mHours++;
}
}
}
}
StopwatchScreen.java
StopwatchImplementation mStopWatch = new StopwatchImplementation(this);
/**
* Update ui thread.
*/
public void updateUIThread() {
StopWatchScreen.this.runOnUiThread(mStopWatch.Timer_Tick);
}
public void startPressed() {
mStopWatch.watchStart();
}
Kindly provide any inputs regarding where the calculation is going wrong.
Thanks in advance.
Warm Regards,
CB
You cannot rely on the scheduling of a TimerTask for precision timing. You have asked for the updateTime method to be called every 100 milliseconds, but the Android system will only adhere to this roughly - it might take 99 or 101 milliseconds before the next time updateTime is called. Because of this you should avoid timing mechanisms which rely on simply increasing a counter.
For this reason you should record the start time, then compare the current time to the start time to get the amount of time elapsed. For instance:
private long startTime;
public void watchStart() {
startTime = SystemClock.elapsedRealtime();
...
}
public void updateTime() {
final long currentTime = SystemClock.elapsedRealtime();
final long elapsedTime = currentTime - startTime;
// convert elapsedTime in seconds, minutes etc
final int seconds = (elapsedTime/1000)%60;
final int minutes = (elapsedTime/(1000*60))%60;
final int hours = (elapsedTime/(100*60*60))%24;
...
}

Categories

Resources