Android 용 간단한 스톱워치를 만들려고합니다. 앱을 최소화 한 후 시간을 계산해야합니다. 스톱워치 로직을 서비스에 넣었고이 서비스를 제어 할 수있는 MainActivity
에이 서비스를 묶습니다. 계산 시간은 별도의 스레드에서 실행되며 메신저를 사용하여 시간을 MainActivity
(으)로 되돌려 보내고 있습니다. 스톱워치가 실행되는 동안 앱을 최소화하고 돌아 가지 않는 한 모든 것이 효과적입니다. 그 후 start/stop 키를 누르면 첫 번째 스레드를 중지하는 대신 두 번째 스레드 계산 시간이 실행됩니다. 무엇이 잘못되었는지 확인할 수 있었습니까? 감사하겠습니다 :)서비스가있는 백그라운드에서 스톱워치가 실행됩니다.
자바 클래스입니다 :
public class MainActivity extends Activity {
public static Handler sHandler;
private final int playPause = 0;
private final int reset = 1;
private int secs = 0;
private int mins = 0;
private int millis = 0;
private long currentTime = 0L;
private boolean isBound = false;
private MyService myService;
private Intent intent;
@BindView(R.id.timer)
TextView time;
@OnClick(R.id.fab_playPause)
public void playPause() {
myService.startStop();
}
@OnClick(R.id.fab_reset)
public void reset() {
myService.reset();
mins = 0;
secs = 0;
millis = 0;
setTime();
}
@OnClick(R.id.fab_exit)
public void exit() {
onDestroy();
}
@OnClick(R.id.fab_save)
public void save() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
intent = new Intent(this, MyService.class);
MainActivity.sHandler = new Handler() {
@Override
public void handleMessage(Message timeMsg) {
super.handleMessage(timeMsg);
currentTime = Long.valueOf(timeMsg.obj.toString());
secs = (int) (currentTime/1000);
mins = secs/60;
secs = secs % 60;
millis = (int) (currentTime % 1000);
setTime();
}
};
}
@Override
protected void onResume() {
super.onResume();
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
stopService(intent);
finishAffinity();
}
private ServiceConnection myConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getService();
isBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
public void setTime() {
time.setText("" + mins + ":" + String.format("%02d", secs) + ":"
+ String.format("%03d", millis));
}
}
과 :
public class MyService extends Service {
private boolean isRunning = false;
private long startTime = 0;
private long timeInMilliseconds = 0;
private long timeSwapBuff = 0;
private long updatedTime = 0;
private final IBinder mBinder = new LocalBinder();
private Message timeMsg;
public MyService() { }
public Runnable updateTimer = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
Log.d("Czas:", String.valueOf(updatedTime));
timeMsg = new Message();
timeMsg.obj = updatedTime;
MainActivity.sHandler.sendMessage(timeMsg);
MainActivity.sHandler.postDelayed(this, 0);
}
};
@Override
public void onCreate(){
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void startStop(){
if (isRunning) {
timeSwapBuff += timeInMilliseconds;
MainActivity.sHandler.removeCallbacks(updateTimer);
isRunning = false;
} else {
startTime = SystemClock.uptimeMillis();
MainActivity.sHandler.postDelayed(updateTimer, 0);
isRunning = true;
}
}
public void reset(){
MainActivity.sHandler.removeCallbacks(updateTimer);
isRunning=false;
startTime = 0L;
timeInMilliseconds = 0L;
timeSwapBuff = 0L;
updatedTime = 0L;
timeMsg = new Message();
timeMsg.obj = updatedTime;
MainActivity.sHandler.sendMessage(timeMsg);
}
public class LocalBinder extends Binder {
public MyService getService(){
return MyService.this;
}
}
}
와 GitHub의 링크 : https://github.com/zelaznymarek/stoper
알았습니다. onResume 대신 onCreate에 바인딩 된 서비스가 있고 bindService 앞에 startService가 추가되었습니다. 나는 바인딩이 충분하다고 생각했다 :) – ajron