Android 显示时间和notifyDataSetChanged()时应用程序崩溃
当我使用notifyDataSetChanged()为帖子创建新评论时,我的应用程序正在崩溃,该帖子链接到显示时间的适配器。所有数据都来自parse.com,我在那里存储所有数据库信息。新创建的注释应该立即显示在listview中,并显示注释和时间的相同活动中。时间由createdAt()计算,该时间被currentTime减去 错误显示:Android 显示时间和notifyDataSetChanged()时应用程序崩溃,android,datetime,time,parse-platform,Android,Datetime,Time,Parse Platform,当我使用notifyDataSetChanged()为帖子创建新评论时,我的应用程序正在崩溃,该帖子链接到显示时间的适配器。所有数据都来自parse.com,我在那里存储所有数据库信息。新创建的注释应该立即显示在listview中,并显示注释和时间的相同活动中。时间由createdAt()计算,该时间被currentTime减去 错误显示: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.ut
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());
publicsocialcommentadapter(上下文、列表注释){
super(上下文,R.layout.socialcommentcustomlayout,注释);
mContext=上下文;
mComment=评论;
}
.
.
.
.
.
final ParseObject commentObject=mComment.get(位置);
//有时间
创建日期=commentObject.getCreatedAt();
日期currentDate=新日期();
long-timepass=currentDate.getTime()-created.getTime();0){
某人追加(分钟);
sb.附加(“m”);
}否则,如果(秒>0){
某人追加(秒);
某人追加;
}
holder.timeComment.setText(sb.toString());
你们知道这有什么问题吗?你们能帮帮我吗
谢谢我找到了一些可以解决我问题的方法 我相信问题在于创造的时间是空的 因此,我通过创建一个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());
}
这样,如果它不能得到创建的时间,它只会说“刚才”。这对我很有效。我找到了一些可以解决我问题的方法 我相信问题在于创造的时间是空的 因此,我通过创建一个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());
}
这样,如果它不能得到创建的时间,它只会说“刚才”。这对我很有效。我找到了一些可以解决我问题的方法 我相信问题在于创造的时间是空的 因此,我通过创建一个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());
}
这样,如果它不能得到创建的时间,它只会说“刚才”。这对我很有效。我找到了一些可以解决我问题的方法 我相信问题在于创造的时间是空的 因此,我通过创建一个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());
}
这样,如果它不能得到创建的时间,它只会说“刚才”。这对我来说很好。 < P>我知道你刚才回答了你自己的问题,但是我正在写我的答案,并且想补充一个关于<强>为什么强>你的变量是NULL的解释,所以我只会把我的答案贴出来。
首先,
commentObject.getCreatedAt()代码>崩溃上方的几行返回null,因此您创建的对象为null,这就是崩溃的原因。现在我来解释一下
,我们看到它返回的时间将是
…创建时间将是第一次调用ParseObject.save()的时间,而不是在本地创建对象的时间
现在,我们可以看到您调用了myComment.savenbackground()在新的ParseObject上的onClick方法中使用code>,并将该对象添加到列表中。然后调用adapter.notifyDataSetChanged()
它会在代码崩溃时触发getView方法。您的saveInBackground方法应该保存对象,但是,它将在后台执行此操作。。。与正在创建对象的线程不同的线程
因此,根据我对文档的理解以及我们在这里看到的内容,getCreatedAt()
将返回null,直到保存ParseObject,此时它将返回带有正确数据的Date对象。因为您正在调用saveInBackground
而不是save
,所以保存发生在后台线程上,这意味着保存可能不会立即发生。执行顺序如下:
初始化ParseObject
在对象上调用saveInBackground,保存可能尚未开始
将对象添加到适配器并调用notify
getView被触发,您的应用程序崩溃,因为日期仍然为空
如果你的应用程序没有崩溃的话,也许在这里(在之前的某些情况下),保存将完成,日期将不再为空
解决此问题的方法是检查变量是否为null:
if (created != null) {
long timepast = currentDate.getTime() - created.getTime();
.
. // your date forming code here
.
holder.timeComment.setText(sb.toString());
} else {
holder.timeComment.setText("new");
}
希望这有助于解释为什么你得到一个空的对象。 我知道你刚才回答了你自己的问题,但是我正在写我的答案,并且想补充一个关于<强>为什么< <强> >你的变量是空的解释,所以我只会发布我的答案。
首先,commentObject.getCreatedAt()代码>崩溃上方的几行返回null,因此您创建的对象为null,这就是崩溃的原因。现在我来解释一下
,我们看到它返回的时间将是
…创建时间将是第一次调用ParseObject.save()的时间,而不是在本地创建对象的时间
现在,我们可以看到您调用了myComment.savenbackground()在新的ParseObject上的onClick方法中使用code>,并将该对象添加到列表中。然后调用adapter.notifyDataSetChanged()
它会在代码崩溃时触发getView方法。您的saveInBackground方法应该保存对象,但是,它将在后台执行此操作。。。与正在创建对象的线程不同的线程
因此,根据我对文档的理解以及我们在这里看到的内容,getCreatedAt()
将返回null,直到保存ParseObject,此时它将返回带有正确数据的Date对象。由于您正在调用saveInBackground
而不是save
,sa