Search code examples
androidtimersharedpreferenceshandler

Timer with Handler and SharedPreference


Nowdays I tried to make a timer by using handler and sharedpreferences.

Today I had a problem with sharedprefereces.

The problem is that it is okay to push start button and go to background and then restart this app, the app is working correctly.

But it is not okay if i try twice the pattern(push start button -> background -> app -> background -> app) , the textview which display the time turns to zero.... I don't know what is problem....

Here is the code..

private Button mStartBtn, mStopBtn, mRecordBtn, mPauseBtn;
private TextView mTimeTextView, mRecordTextView;
private Thread timeThread = null;
private Boolean isRunning = false;
ArrayList<String> record = new ArrayList<>();
Boolean timeThreadd = false;
long i;
long mEndTime;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_stop_watch);
    if (Build.VERSION.SDK_INT >= 21) {
        getWindow().setStatusBarColor(Color.parseColor("#4ea1d3"));
    }

    mStartBtn = (Button) findViewById(R.id.btn_start);
    mStopBtn = (Button) findViewById(R.id.btn_stop);
    mRecordBtn = (Button) findViewById(R.id.btn_record);
    mPauseBtn = (Button) findViewById(R.id.btn_pause);
    mTimeTextView = (TextView) findViewById(R.id.timeView);
    mRecordTextView = (TextView) findViewById(R.id.recordView);

    mStartBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.setVisibility(View.GONE);
            mStopBtn.setVisibility(View.VISIBLE);
            mRecordBtn.setVisibility(View.VISIBLE);
            mPauseBtn.setVisibility(View.VISIBLE);
            if (isRunning != true) {
                isRunning = true;
            }// start 가 true 일때만 실행된다.

            timeThread = new Thread(new timeThread());

            timeThread.start();

        }
    });

    mStopBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.setVisibility(View.GONE);
            mRecordBtn.setVisibility(View.GONE);
            mStartBtn.setVisibility(View.VISIBLE);
            mPauseBtn.setVisibility(View.GONE);

            mRecordTextView.setText("");
            mTimeTextView.setText("00:00:00:00");
            timeThread.interrupt();
            i = 0;
            mEndTime = 0;
            timeThreadd = false;
            isRunning = false;
            if (record.size() > 1) {
                for (int i = 0; i < record.size(); i++) {
                    record.remove(i);
                }
            }

            SharedPreferences sharedPreferences = getSharedPreferences("timer", MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();

            editor.clear();
            editor.apply();


        }
    });

    mRecordBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            record.add(mTimeTextView.getText().toString());
            mRecordTextView.setText(mRecordTextView.getText() + mTimeTextView.getText().toString() + "\n");
        }// 앞에 mRecordTextView.getText()은 n번이상 저장할때 첫번째 값을 n-1번째 라인에 놓고
    });  // n번째 저장한것을 n번째 놓기 위해서 설정

    mPauseBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            isRunning = !isRunning;
            if (isRunning) {

                mPauseBtn.setText("PAUSE");
            } else {
                mPauseBtn.setText("PAUSE");

            }
        }

    });
}


@SuppressLint("HandlerLeak")
Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        int mSec = msg.arg1 % 100;
        int sec = (msg.arg1 / 100) % 60;
        int min = (msg.arg1 / 100) / 60;
        int hour = (msg.arg1 / 100) / 360;
        //1000 = 1 sec, 1000*60 = 1 min, 1000*60*10 = 10min 1000*60*60 = 1 hour

        @SuppressLint("DefaultLocale")
        String result = String.format(Locale.getDefault(), "%02d:%02d:%02d:%02d", hour, min, sec, mSec);

        mTimeTextView.setText(result);
    }
};

public class timeThread implements Runnable {

    @Override
    public void run() {
        mEndTime = System.currentTimeMillis() / 10 + i;
        timeThreadd = true;


        while (true) {
            while (isRunning) { //일시정지를 누르면 멈춤
                Message msg = new Message();
                msg.arg1 = (int) i++;
                handler.sendMessage(msg);

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {


                            mTimeTextView.setText("");
                            mTimeTextView.setText("00:00:00:00");
                        }
                    });
                    return;
                }
            }
        }
    }
}

@Override
protected void onStop() {
    super.onStop();
    SharedPreferences sharedpreferences = getSharedPreferences("timer", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedpreferences.edit();
    editor.putLong("time", i);
    editor.putBoolean("switch", isRunning);
    editor.putInt("recordsize", record.size());
    editor.putLong("endTime", mEndTime);
    Log.v("i", String.valueOf(i));
    Log.v("iswitch", String.valueOf(isRunning));
    Log.v("endTime", String.valueOf(mEndTime));
    isRunning = false;

    for (int i = 0; i < record.size(); i++) {
        editor.putString("record" + i, record.get(i));
    }
    editor.apply();
    if (timeThreadd != false) {
        timeThread.interrupt();
    }
    if (record.size() > 0) {
        for (int i = 0; i < record.size(); i++) {
            record.remove(i);
        }
    }

}

@Override
protected void onStart() {
    super.onStart();
    SharedPreferences sharedpreferences = getSharedPreferences("timer", MODE_PRIVATE);
    i = sharedpreferences.getLong("time", 0);

    isRunning = sharedpreferences.getBoolean("switch", isRunning);
    int b = sharedpreferences.getInt("recordsize", 0);
    for (int i = 0; i < b; i++) {
        String c = sharedpreferences.getString("record" + i, null);
        record.add(c);
        mRecordTextView.setText(mRecordTextView.getText() + c + "\n");
    }

    if (isRunning) {
        mEndTime = sharedpreferences.getLong("endTime", 0);

        Log.v("      set mEndTime",String.valueOf(mEndTime));
        i = System.currentTimeMillis() / 10 - mEndTime;


        Log.v("     set i",String.valueOf(i));
        if (i < 0) {
            isRunning = false;
            i = 0;
            mEndTime = 0;
            timeThreadd = false;
            mRecordBtn.setVisibility(View.GONE);
            mStartBtn.setVisibility(View.VISIBLE);
            mPauseBtn.setVisibility(View.GONE);
            mRecordTextView.setText("");
            mTimeTextView.setText("00:00:00:00");

        } else if (i > 0) {
            mStartBtn.setVisibility(View.GONE);
            mStopBtn.setVisibility(View.VISIBLE);
            mRecordBtn.setVisibility(View.VISIBLE);
            mPauseBtn.setVisibility(View.VISIBLE);
            timeThread = new Thread(new timeThread());


            timeThread.start();

        }
    }
}
}

Solution

  • I solve the problem.

       public void run() {
            if(timeThreadd!= true){
                mEndTime = System.currentTimeMillis() / 10 + i;
                timeThreadd = true;
            }
    

    The problem was System.currentTimeMillis().

    The System.currentTimeMillis() needs to store just one time when user push the start button.