Issue
I am doing an app where I click the START button and get current time, and hitting STOP gets the time again. I´ve been using system time without any errors, recently I changed it to server time, which is in an Asynctask, but the app is unstable since, slowed down and exits without error messages, but on faster connections it can process. Any idea why? This is my code:
class getDST2 extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... arg0) {
try {
TimeTCPClient client = new TimeTCPClient();
try {
client.setDefaultTimeout(60000);
client.connect("time.nist.gov");
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
do_casu = simpledate.format(client.getDate());
} finally {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result) {
getDSTdone = true;
}
}
Also doing a graphic timer of the current time since Start was clicked so I need to get server time every second inside a handler.. code:
handler.post(r = new Runnable() {
public void run() {
hasStartedtt2 = true;
calendar = Calendar.getInstance();
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
new getDST2().execute(); // THIS IS THE ASynctask, returns the "do_casu" String
zaciatok_hour = zaciatok.substring(11, 13);
zaciatok_minute = zaciatok.substring(14, 16);
koniec_hour = do_casu.substring(11, 13);
koniec_minute = do_casu.substring(14, 16);
zaciatok_sekundy = zaciatok.substring(17, 19);
koniec_sekundy = do_casu.substring(17, 19);
final_hour = ((Integer.parseInt(koniec_hour) - Integer.parseInt(zaciatok_hour)));
final_minute = Integer.parseInt(koniec_minute) - Integer.parseInt(zaciatok_minute);
final_seconds = Integer.parseInt(koniec_sekundy) - Integer.parseInt(zaciatok_sekundy) - 1;
}
});
Handler is called every second.
Solution
ServerTimeThread sth = new ServerTimeThread();
sth.start();
from_time = simpledate.format(sth.time);
when you call 'sth.time',the thread just start and is still in progress.
'time' is remain uninitialized,it is init at end of thread
So when accessing 'time',it is null absolutely.
2 way for AsyncTask
Blocking operation:
public class NTPDateTask extends AsyncTask<Void,Void,Date> {
@Override
protected Date doInBackground(Void... voids) {
Date date=fetchYourDate();
//fetch your date here
return date;
}
}
then call
Date result = new NTPDateTask().execute().get();
Non-Blocking operation(Callback pattern):
public class NTPDateTask extends AsyncTask<Void,Void,Date> {
@Override
protected Date doInBackground(Void... voids) {
Date date = fetchYourDate();
//fetch your date here
return date;
}
@Override
protected void onPostExecute(Date date) {
//this is 'callback'
//do the thing you want when task finish
//onPostExecute is called when doInBackground finished,and it runs on UIThread
}
}
then
new NTPDateTask().execute();
EDIT:
class TCPTimeDisplayWorker implements Runnable {
static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
boolean isActive = true;
private Handler targetHandler;
public TCPTimeDisplayWorker(Handler targetHandler) {
//pass the handler ref here
this.targetHandler = targetHandler;
}
@Override
public void run() {
while (isActive) {
long startTime = System.currentTimeMillis();
Date date = fetchDateFromTCPClient();
//fetch Server Date here
String currentDateText = simpleDateFormat.format(date);
targetHandler.sendMessage(Message.obtain(targetHandler, 0, currentDateText));
long endTime = System.currentTimeMillis();
long lapse = endTime - startTime;
if (lapse < 1000) {
try {
Thread.sleep(1000 - lapse);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Handler:
// Non-static inner class will hold outer-class reference,may risk in memory leak
static class MainHandler extends Handler {
private WeakReference<TextView> textViewWeakReference;
// declare as WeakRef to avoid memory leak
public MainHandler(Looper looper, WeakReference<TextView> textViewWeakReference) {
super(looper);
this.textViewWeakReference = textViewWeakReference;
}
@Override
public void handleMessage(Message msg) {
if (textViewWeakReference.get() != null) {
//handle the message from message queue here
String text = (String) msg.obj;
textViewWeakReference.get().setText(text);
}
}
}
then
// must use the same handler to send msg from Background thread and
// handle at Main Thread
// a handler create on a thread will bound to that thread
mainHandler = new MainHandler(Looper.getMainLooper(), new WeakReference<>(mTextViewSystemTime));
new Thread(new TCPTimeDisplayWorker(mainHandler)).start();
btw,CamelCase is the common naming convention in Java.
Hope these are helpful.
Answered By - Druid Virtual
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.