显示时间和notifyDataSetChanged()时应用程序崩溃

时间:2015-08-23 13:51:12

标签: android datetime time parse-platform

我为使用notifyDataSetChanged()链接到显示时间的适配器的帖子创建新评论时,我的应用程序崩溃了。所有数据都来自parse.com,我存储了所有数据库信息。新制作的评论应该立即显示在列表视图中显示评论和时间的同一活动中。时间是由currentTime减去的createdAt()。

错误说:

java.lang.NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference

这是添加评论的按钮:

                            //Add a new comment
                            mAddComment.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    Log.d("log", "add button clicked");

                                    final ParseObject myComment = new ParseObject("Comments");
                                    final String comment = mComment.getText().toString();
                                    myComment.put("CommentOwner", currentUserUsername);
                                    myComment.put("Comment", comment);
                                    myComment.put("SocialId", ParseObject.createWithoutData("Social", socialId));
                                    myComment.saveInBackground();

                                    adapter.setNotifyOnChange(false);
                                    adapter.add(myComment);
                                    adapter.notifyDataSetChanged();
                                    setListAdapter(adapter);
                                    if (adapter.isEmpty()) {
                                    } else {
                                        mList.setSelection(mList.getAdapter().getCount() - 1);
                                    }
                                    mComment.setText("");
                                }
                            });

这是适配器内部显示时间的东西:

    public SocialCommentAdapter(Context context, List<ParseObject> Comment) {
        super(context, R.layout.socialcommentcustomlayout, Comment);
            mContext = context;
            mComment = Comment;
    }
    .
    .
    .
    .
    .
    final ParseObject commentObject = mComment.get(position);
    //get Time
    Date created = commentObject.getCreatedAt();
    Date currentDate = new Date();


    long timepast = currentDate.getTime() - created.getTime(); <<<< The Error points to this line of the code

    long days = TimeUnit.MILLISECONDS.toDays(timepast);
    timepast -= TimeUnit.DAYS.toMillis(days);
    long hours = TimeUnit.MILLISECONDS.toHours(timepast);
    timepast -= TimeUnit.HOURS.toMillis(hours);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(timepast);
    timepast -= TimeUnit.MINUTES.toMillis(minutes);
    long seconds = TimeUnit.MILLISECONDS.toSeconds(timepast);

    StringBuilder sb = new StringBuilder(64);
    if( days > 0){
        sb.append(days);
        sb.append("d");
    }else if (hours>0){
        sb.append(hours);
        sb.append("h");
    } else if (minutes >0){
        sb.append(minutes);
        sb.append("m");
    }else if ( seconds >0){
        sb.append(seconds);
        sb.append("s");
    }

    holder.timeComment.setText(sb.toString());

你们知道这有什么问题吗?你能帮助我吗?

谢谢

2 个答案:

答案 0 :(得分:2)

我知道你刚刚回答了自己的问题,但是我正在写我的答案,并希望添加一个关于为什么你的变量为空的解释,所以我会只是发布我的答案。

首先,commentObject.getCreatedAt();崩溃之上的几​​行返回null,因此您的created对象为空,这就是崩溃的原因。现在进行解释。

Reading the documentation on getCreatedAt(),我们看到它返回

的时间
  

...创建时间将是第一次ParseObject.save()调用的时间,而不是本地创建对象的时间。

现在,我们可以看到您在新的ParseObject上的onClick方法中调用了myComment.saveInBackground();,并将该对象添加到列表中。然后调用adapter.notifyDataSetChanged();,它会触发代码崩溃的getView方法。你的saveInBackground方法应该保存对象,但是,它将在后台执行...与你正在创建对象的线程不同的线程。

因此,我理解文档的方式以及我们在此处看到的内容,getCreatedAt()将返回null,直到保存ParseObject,此时它将返回具有正确数据的Date对象。因为您正在调用saveInBackground而不是save,所以保存发生在后台线程上,这意味着保存可能不会立即发生。执行顺序如下:

  1. 初始化ParseObject
  2. 您在对象上调用saveInBackground,可能还没有开始保存
  3. 您将对象添加到适配器并调用notify
  4. getView被触发,您的应用程序因日期仍然为空而崩溃
  5. 也许在这附近(在某些情况下更早)保存将完成,如果你的应用没有崩溃,Date将不再为null。
  6. 解决方法是检查变量是否为空:

    if (created != null) {
        long timepast = currentDate.getTime() - created.getTime();
        .
        . // your date forming code here
        .
        holder.timeComment.setText(sb.toString());
    } else {
        holder.timeComment.setText("new");
    }
    

    希望这有助于解释您获取空对象的原因。

答案 1 :(得分:1)

我发现了一些可以解决我问题的方法。

我认为问题在于创建的时间是空的。

所以我通过创建if / else方法解决了这个问题,如下所示:

    //get Time
    Date created = commentObject.getCreatedAt();
    Date currentDate = new Date();
    if( created == null ){
        holder.timeComment.setText("just now");
    }else{

        long timepast = currentDate.getTime() - created.getTime();

        long days = TimeUnit.MILLISECONDS.toDays(timepast);
        timepast -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(timepast);
        timepast -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(timepast);
        timepast -= TimeUnit.MINUTES.toMillis(minutes);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(timepast);

        StringBuilder sb = new StringBuilder(64);
        if( days > 0){
            sb.append(days);
            sb.append("d");
        }else if (hours>0){
            sb.append(hours);
            sb.append("h");
        } else if (minutes >0){
            sb.append(minutes);
            sb.append("m");
        }else if ( seconds >0){
            sb.append(seconds);
            sb.append("s");
        }

        holder.timeComment.setText(sb.toString());

    }

这样,如果它无法获得创建的时间,它只会说“刚才”。这对我很有用。