获取服务器时间会冻结并崩溃我的应用程序

时间:2018-09-24 09:44:19

标签: android multithreading time android-asynctask

我正在做一个应用程序,单击“开始”按钮获取当前时间,按“停止”获取时间。我一直在使用系统时间,没有任何错误,最近我将其更改为服务器时间,该时间在Asynctask中,但该应用程序不稳定,因为运行缓慢且退出时没有错误消息,但可以处理更快的连接。知道为什么吗?这是我的代码:

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;
    }
}

还要对自单击“开始”以来的当前时间进行图形计时器,所以我需要在处理程序中每秒获取服务器时间。.

    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;

           }
           });

每秒调用一次处理程序。

1 个答案:

答案 0 :(得分:1)

 ServerTimeThread sth = new ServerTimeThread();
 sth.start();
 from_time = simpledate.format(sth.time);

当您调用“ sth.time”时,线程刚刚启动并且仍在进行中。

'time'保持未初始化,它在线程结束时初始化

因此,访问“时间”时,绝对为空。

AsyncTask的两种方式

阻止操作

public class NTPDateTask extends AsyncTask<Void,Void,Date> {
@Override
   protected Date doInBackground(Void... voids) {
      Date date=fetchYourDate();
      //fetch your date here
      return date;
   }
}

然后打电话

Date result = new NTPDateTask().execute().get();

非阻塞操作(回调模式):

    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
    }
}

然后

new NTPDateTask().execute();

编辑:

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();
            }
        }
    }
  }
}

处理程序:

 // 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);
        }
    }
}

然后

    // 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是Java中的常见命名约定。

希望这些对您有所帮助。