倒计时器recyclerview - android

时间:2016-07-14 17:37:57

标签: android synchronization android-recyclerview runnable countdowntimer

我已经在应用程序上工作了很长时间。这个应用程序应该采用姓氏并测量访问时间,这是恒定的(30分钟)。我有一个Family对象,其中包含名称,成员数和访问结束等信息,表示为未来的毫秒值。

我实现定时器部分的方法只是创建一个名为CountDownManager的类,它负责更新和计算列出的所有系列视图持有者的剩余时间。

问题在于,每当我从回收站视图中删除一个族(列表项)时,我的CountDownManager都会出现NullPointerException错误。

基本上我认为CountDownManager正在尝试访问数据集中不再可用的族。我试图通过简单地同步我删除一个系列的部分来解决这个问题,但它仍然会因同样的错误而崩溃。

以下是我的FamiliesAdapter的代码:

package bikurim.silverfix.com.bikurim.utils.managers;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;

import bikurim.silverfix.com.bikurim.Constants;
import bikurim.silverfix.com.bikurim.adapters.holders.FamilyViewHolder;
import bikurim.silverfix.com.bikurim.utils.interfaces.EventListener;
import bikurim.silverfix.com.bikurim.utils.Utils;

/**
 * Created by David on 07/07/2016.
 * @author David
 * Inspired by MiguelLavigne
 *
 * A custom CountDownTimer class, which takes care of all the running timers
 */
public class CountDownManager {

    private final long interval;
    private long base;

    // Holds references for all the visible text views
    private ArrayList<FamilyViewHolder> holders;

    private EventListener listener;

    public CountDownManager(long interval, EventListener listener) {
        this.listener = listener;
        this.interval = interval;
        holders = new ArrayList<>();
    }

    public void start() {
        base = System.currentTimeMillis();
        handler.sendMessage(handler.obtainMessage(MSG));
    }

    public void stop() {
        handler.removeMessages(MSG);
    }

    public void reset() {
        synchronized (this) {
            base = System.currentTimeMillis();
        }
    }

    public void addHolder(FamilyViewHolder holder) {
        synchronized (holders) {
            if(holder.isHolderAdded == false) {
                holders.add(holder);
                holder.isHolderAdded = true;
            }
        }
    }

    public void removeHolder(FamilyViewHolder holder) {
        synchronized (holders) {
            holders.remove(holder);
        }
    }

    synchronized void onTick(long elapsedTime) {
       try {
           if(!holders.isEmpty()) {
               long timeLeft, lengthOfVisit;
               for (FamilyViewHolder holder : holders) {
                   lengthOfVisit = holder.family.whenInMillis - base;
                   timeLeft =  lengthOfVisit - elapsedTime;
                   if(timeLeft > 0) {
                       Log.d("Time left:", "" + timeLeft);
                       if(timeLeft <= Constants.Values.ALERT_TIME && !holder.isStrokeChanged) {
                           listener.onLessThanMinute(holder);
                       }
                       holder.family.timeLeft = timeLeft;
                       holder.timeLeft.setText(Utils.updateFormatTime(timeLeft));
                   } else {
                       listener.onFinish(holder);
                       removeHolder(holder);
                   }
               }
           }
       } catch (ConcurrentModificationException e) {
            Log.d("Concurrent Error", "App will shut down now");
            e.printStackTrace();
       }
    }

    public void clear() {
        holders.clear();
    }

    private static final int MSG = 1;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            synchronized (CountDownManager.this) {
                long elapsedTime = System.currentTimeMillis() - base;
                onTick(elapsedTime);
                sendMessageDelayed(obtainMessage(MSG), interval);
            }
        }
    };
}

这是CountDownManager:

ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
                final int pos = viewHolder.getAdapterPosition();
                AlertDialog.Builder builder = new AlertDialog.Builder(FamilyListActivity.this);
                builder.setMessage(R.string.confirmation_message)
                        .setPositiveButton(R.string.proceed_dialog, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                synchronized (families) {
                                    Family family = families.get(pos);
                                    GenericViewHolder holder = null;
                                    try {
                                        holder = (GenericViewHolder) viewHolder;
                                    } catch (ClassCastException e) {
                                        e.printStackTrace();
                                    }

                                    String whereClause = FamiliesTablesContract.DATE_COLUMN + "=?";
                                    String args[] = new String[] {"" + family.date};
                                    Cursor cursor = dataManager.query(FamiliesTablesContract.TABLE_NAME, whereClause, args);
                                    int entryId = 0;

                                    try {
                                        cursor.moveToFirst();
                                        entryId = cursor.getInt(cursor.getColumnIndexOrThrow(FamiliesTablesContract._ID));
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    reminderManager.cancelReminder(entryId);
                                    String name = family.name;

                                    adapter.removeData(pos, holder);
                                    dialog.dismiss();
                                }
                            }
                        }).setNegativeButton(R.string.cancel_dialog, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        adapter.notifyItemChanged(pos);
                        dialog.dismiss();
                    }
                });
                builder.show();
            }
        };
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(recyclerView);

在我的活动中,这是我删除项目的部分,使用ItemTouchHelper的滑动移动:

07-14 19:34:03.742 5597-5597/bikurim.silverfix.com.bikurim E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: bikurim.silverfix.com.bikurim, PID: 5597
                                                                             java.lang.NullPointerException: Attempt to read from field 'long bikurim.silverfix.com.bikurim.models.Family.whenInMillis' on a null object reference
                                                                                 at bikurim.silverfix.com.bikurim.utils.managers.CountDownManager.onTick(CountDownManager.java:73)
                                                                                 at bikurim.silverfix.com.bikurim.utils.managers.CountDownManager$1.handleMessage(CountDownManager.java:105)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

这是我得到的错误:

{{1}}

0 个答案:

没有答案