我在listview中实现了倒数计时器。但问题是,当我关闭我的应用程序并重新打开时,计时器从开始重置。我希望计时器运行即使应用程序关闭。例如 - 如果时间是10分钟我关闭应用程序并在6分钟后打开计时器必须显示剩余时间为4分钟。
MainActivity.java
public class MainActivity extends Activity {
private ListView lvItems;
private List<Product> lstProducts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvItems = (ListView) findViewById(R.id.lvItems);
lstProducts = new ArrayList<>();
lstProducts.add(new Product("A", System.currentTimeMillis() + 10000));
lstProducts.add(new Product("B", System.currentTimeMillis() + 250000));
lstProducts.add(new Product("C", System.currentTimeMillis() + 200000));
lstProducts.add(new Product("D", System.currentTimeMillis() + 300000));
lvItems.setAdapter(new CountdownAdapter(MainActivity.this, lstProducts));
}
}
Product.java
public class Product {
String name;
long expirationTime;
public Product(String name, long expirationTime) {
this.name = name;
this.expirationTime = expirationTime;
}
}
CountdownAdapter.java
public class CountdownAdapter extends ArrayAdapter<Product> {
private LayoutInflater lf;
private List<ViewHolder> lstHolders;
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
@Override
public void run() {
synchronized (lstHolders) {
long currentTime = System.currentTimeMillis();
for (ViewHolder holder : lstHolders) {
holder.updateTimeRemaining(currentTime);
}
}
}
};
public CountdownAdapter(Context context, List<Product> objects) {
super(context, 0, objects);
lf = LayoutInflater.from(context);
lstHolders = new ArrayList<>();
startUpdateTimer();
}
private void startUpdateTimer() {
Timer tmr = new Timer();
tmr.schedule(new TimerTask() {
@Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
}
}, 1000, 1000);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = lf.inflate(R.layout.list_item, parent, false);
holder.tvProduct = (TextView) convertView.findViewById(R.id.tvProduct);
holder.tvTimeRemaining = (TextView) convertView.findViewById(R.id.tvTimeRemaining);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.setData(getItem(position));
return convertView;
}
class ViewHolder {
TextView tvProduct;
TextView tvTimeRemaining;
Product mProduct;
public void setData(Product item) {
mProduct = item;
tvProduct.setText(item.name);
updateTimeRemaining(System.currentTimeMillis());
}
public void updateTimeRemaining(long currentTime) {
long timeDiff = mProduct.expirationTime - currentTime;
if (timeDiff > 0) {
int seconds = (int) (timeDiff / 1000) % 60;
int minutes = (int) ((timeDiff / (1000 * 60)) % 60);
int hours = (int) ((timeDiff / (1000 * 60 * 60)) % 24);
tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec");
} else {
tvTimeRemaining.setText("Expired!!");
}
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.ram.asynctimer.MainActivity">
<ListView
android:id="@+id/lvItems"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvProduct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="Product Name"
android:textSize="16dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvTimeRemaining"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="Time Remaining : " />
</LinearLayout>
MyService.java
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// do your jobs here
return super.onStartCommand(intent, flags, startId);
}
}
答案 0 :(得分:0)
原因“计时器重置”是指您在关闭时没有保存每个项目计时器,当您启动应用程序时,您将再次设置新的计时器。
只需将每个项目计时器存储在onStop方法中,然后再次在onCreate中加载这些项目,并设置是否
if(item1_timer - System.currentTimeMillis()>0){
{
//set timer to item1 and so on
}else{
item1.timer = "Expired"
}
答案 1 :(得分:0)
如果您修改了Product.java以保留到期时间和剩余时间,那么您可以使用捆绑包保存和恢复该信息。
<强> Product.java 强>
public class Product {
String name;
long expirationTime;
long remainingTime
public Product(String name, long expirationTime, long remainingTime) {
this.name = name;
this.expirationTime = expirationTime;
if(remainingTime <= 0)
this.remainingTime = this.expirationTime;
else
this.remainingTime = remainingTime;
}
}
从这里,您可以使用共享首选项来保存所有产品的状态。
<强> MainActivity.java 强>
public class MainActivity extends Activity {
public static final String PREFS_NAME = "TimerValsFile";
private ListView lvItems;
private List<Product> lstProducts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvItems = (ListView) findViewById(R.id.lvItems);
lstProducts = new ArrayList<>();
// Access the shared preferences
SharedPreferences timerVals = getSharedPreferences(PREFS_NAME, 0);
// Restore remaining time from shared preferences
long remA = timerVals.getLong("A", -1);
long remB = timerVals.getLong("A", -1);
long remC = timerVals.getLong("A", -1);
long remD = timerVals.getLong("A", -1);
lstProducts.add(new Product("A", System.currentTimeMillis() + 10000), remA);
lstProducts.add(new Product("B", System.currentTimeMillis() + 250000), remB);
lstProducts.add(new Product("C", System.currentTimeMillis() + 200000), remC);
lstProducts.add(new Product("D", System.currentTimeMillis() + 300000), remD);
lvItems.setAdapter(new CountdownAdapter(MainActivity.this, lstProducts));
}
@Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences timerVals = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = timerVals.edit();
editor.putLong("A", lstProducts.get(0).remainingTime);
editor.putLong("B", lstProducts.get(1).remainingTime);
editor.putLong("C", lstProducts.get(2).remainingTime);
editor.putLong("D", lstProducts.get(3).remainingTime);
// Commit the edits!
editor.apply();
}
}
现在您要从实例状态加载,您需要修改ViewHolder类
class ViewHolder {
TextView tvProduct;
TextView tvTimeRemaining;
Product mProduct;
public void setData(Product item) {
mProduct = item;
tvProduct.setText(item.name);
updateTimeRemaining(System.currentTimeMillis());
}
public void updateTimeRemaining(long currentTime) {
mProduct.remainingTime -= currentTime;
if (mProduct.remainingTime > 0) {
int seconds = (int) (mProduct.remainingTime / 1000) % 60;
int minutes = (int) ((mProduct.remainingTime / (1000 * 60)) % 60);
int hours = (int) ((mProduct.remainingTime / (1000 * 60 * 60)) % 24);
tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec");
} else {
tvTimeRemaining.setText("Expired!!");
}
}
}
我还没有真正对此进行测试,但很快就能解决这个问题,但我希望这能为您提供一般的想法。这基本上是使用服务的替代方案。
来源:
SO: Android Shared preferences example
Android开发者指南: https://developer.android.com/guide/topics/data/data-storage.html#pref
https://developer.android.com/reference/android/content/SharedPreferences.Editor.html