Android Studio 项目中的错误
Error in Android Studio project
我有 2 个活动:Feed 和 User。这两个活动使用相同的适配器、相同的布局,但在第一个 activity 适配器中加载提要(并崩溃),在第二个 activity 适配器中加载用户的提要(不崩溃)。
这是我在 Feed.class 的控制台中找到的:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.flaunder.flaunder, PID: 5906
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at com.android.volley.toolbox.ImageLoader.getCacheKey(ImageLoader.java:503)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:213)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:191)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:182)
at com.flaunder.flaunder.QuestionsAdapter.onBindViewHolder(QuestionsAdapter.java:69)
at com.flaunder.flaunder.QuestionsAdapter.onBindViewHolder(QuestionsAdapter.java:30)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6062)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6095)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5277)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5153)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2061)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1445)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1408)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:580)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3374)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3183)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3627)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1367)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:849)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1193)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
at android
适配器从服务器的数据库获取 json 并解析它们。 json 的字段对于 Feed 和 User 是相同的。
适配器中的代码:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
regular = Typeface.createFromAsset(context.getAssets(),"OpenSans-Regular.ttf");
bold = Typeface.createFromAsset(context.getAssets(),"OpenSans-Semibold.ttf");
//Getting the particular item from the list
QuestionList questionHero = questionList.get(position);
//Loading image from url
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(questionHero.getUserphoto(), ImageLoader.getImageListener(holder.genUserPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
imageLoader.get(questionHero.getPhoto(), ImageLoader.getImageListener(holder.genPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
//Showing data on the views
holder.genUserPhoto.setImageUrl(questionHero.getUserphoto(), imageLoader);
holder.genQuestion.setText(questionHero.getQuestion());
holder.genQuestion.setTypeface(bold);
holder.genAnswer.setText(questionHero.getAnswer());
holder.genAnswer.setTypeface(regular);
holder.genFroms.setText(questionHero.getFroms());
holder.genFroms.setTypeface(regular);
holder.genTos.setText(questionHero.getTos());
holder.genTos.setTypeface(regular);
holder.genFromslogin.setText(questionHero.getFromslogin());
holder.genToslogin.setText(questionHero.getToslogin());
holder.genToslogin2.setText(questionHero.getToslogin());
holder.genDate.setText(questionHero.getDate());
holder.genDate.setTypeface(regular);
holder.genLikenum.setText(questionHero.getLikenum());
holder.genLikenum.setTypeface(regular);
holder.genCommentnum.setText(questionHero.getCommentnum());
holder.genCommentnum.setTypeface(regular);
holder.genPhoto.setImageUrl(questionHero.getPhoto(), imageLoader);
holder.genVideo.setText(questionHero.getVideo());
holder.genId.setText(questionHero.getQid());
}
供稿:
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the superhero object
QuestionList qHero = new QuestionList();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
//Adding data to the superhero object
qHero.setQuestion(json.getString("question"));
qHero.setAnswer(json.getString("answer"));
qHero.setUserphoto(json.getString("userphoto"));
qHero.setFroms(json.getString("froms"));
qHero.setTos(json.getString("tos"));
qHero.setFromslogin(json.getString("fromslogin"));
qHero.setToslogin(json.getString("toslogin"));
qHero.setDate(json.getString("date"));
qHero.setLikenum(json.getString("likenum"));
qHero.setCommentnum(json.getString("commentnum"));
qHero.setPhoto(json.getString("photo"));
qHero.setVideo(json.getString("video"));
qHero.setQid(json.getString("id"));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the superhero object to the list
listQuestions.add(qHero);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
适配器初始化:
class ViewHolder extends RecyclerView.ViewHolder{
//Views
public NetworkImageView genUserPhoto;
public TextView genQuestion;
public TextView genAnswer;
public TextView genFroms;
public TextView genTos;
public TextView genFromslogin;
public TextView genToslogin;
public TextView genToslogin2;
public TextView genDate;
public TextView genLikenum;
public TextView genCommentnum;
public NetworkImageView genPhoto;
public TextView genVideo;
public TextView genId;
public TextView genPhotourl;
public CardView cardRview;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
genUserPhoto = (NetworkImageView) itemView.findViewById(R.id.genUserPhoto);
genQuestion = (TextView) itemView.findViewById(R.id.genQuestion);
genAnswer = (TextView) itemView.findViewById(R.id.genAnswer);
genFroms = (TextView) itemView.findViewById(R.id.genFroms);
genTos = (TextView) itemView.findViewById(R.id.genTos);
genFromslogin = (TextView) itemView.findViewById(R.id.genFromslogin);
genToslogin = (TextView) itemView.findViewById(R.id.genToslogin);
genToslogin2 = (TextView) itemView.findViewById(R.id.genToslogin2);
genDate = (TextView) itemView.findViewById(R.id.genDate);
genLikenum = (TextView) itemView.findViewById(R.id.genLikenum);
genCommentnum = (TextView) itemView.findViewById(R.id.genCommentnum);
genPhoto = (NetworkImageView) itemView.findViewById(R.id.genPhoto);
genVideo = (TextView) itemView.findViewById(R.id.genVideo);
genId = (TextView) itemView.findViewById(R.id.genId);
genPhotourl = (TextView) itemView.findViewById(R.id.genPhotourl);
cardRview = (CardView) itemView.findViewById(R.id.cardRview);
}
}
因此,在您解析 JSON 时,某些键可能为空或不存在。在这种情况下,您的 questionHero 将包含 null。所以在调用代码之前你应该像这样检查
if (questionHero.getUserphoto() != null ) {
//in case you handle visibility in else block make //holder.genUserPhoto.setVisibility(View.VISIBLE) here visible
imageLoader.get(questionHero.getUserphoto(), ImageLoader.getImageListener(holder.genUserPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
} else {
//reset image by questionHero.genUserPhoto.setImageBitmap(null), or handle //visibility of holder.genUserPhoto
}
与 questionHero.getPhoto()
的写法相同
为什么需要可见性或重置?
Recycler 视图重复使用项目,因此相同的视图将在其他位置重复使用,以防万一您不处理,最终会在错误的位置显示错误的图像。
几个性能提示
regular = Typeface.createFromAsset(context.getAssets(),"OpenSans-Regular.ttf");
bold = Typeface.createFromAsset(context.getAssets(),"OpenSans-Semibold.ttf");
永远不要在 bindViewHolder 中使用这样的代码,当你滚动时,这个方法会被一次又一次地调用,每次它都会从资产中创建字体,这足以让你的滚动变得迟缓。您应该为此创建一个单例class,它将创建一次字体并缓存它并在需要时提供给应用程序。
holder.genDate.setTypeface(regular);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
现在你已经在 bindViewHolder 中编写了这段代码,将这段代码移到 createViewHolder 中,因为设置一次字体就足够了,同样你应该获得一次图像加载器,尽管它不会有太大区别,因为 ImageLoader 本身是单例的,但是在 ViewHolder 级别仍然很好,只有视图的数据或属性会因每个回收器视图项目而改变,应该在 bindViewHolder 方法中处理。
我有 2 个活动:Feed 和 User。这两个活动使用相同的适配器、相同的布局,但在第一个 activity 适配器中加载提要(并崩溃),在第二个 activity 适配器中加载用户的提要(不崩溃)。
这是我在 Feed.class 的控制台中找到的:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.flaunder.flaunder, PID: 5906
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at com.android.volley.toolbox.ImageLoader.getCacheKey(ImageLoader.java:503)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:213)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:191)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:182)
at com.flaunder.flaunder.QuestionsAdapter.onBindViewHolder(QuestionsAdapter.java:69)
at com.flaunder.flaunder.QuestionsAdapter.onBindViewHolder(QuestionsAdapter.java:30)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6062)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6095)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5277)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5153)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2061)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1445)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1408)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:580)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3374)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3183)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3627)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1367)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:849)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1193)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
at android
适配器从服务器的数据库获取 json 并解析它们。 json 的字段对于 Feed 和 User 是相同的。
适配器中的代码:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
regular = Typeface.createFromAsset(context.getAssets(),"OpenSans-Regular.ttf");
bold = Typeface.createFromAsset(context.getAssets(),"OpenSans-Semibold.ttf");
//Getting the particular item from the list
QuestionList questionHero = questionList.get(position);
//Loading image from url
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(questionHero.getUserphoto(), ImageLoader.getImageListener(holder.genUserPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
imageLoader.get(questionHero.getPhoto(), ImageLoader.getImageListener(holder.genPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
//Showing data on the views
holder.genUserPhoto.setImageUrl(questionHero.getUserphoto(), imageLoader);
holder.genQuestion.setText(questionHero.getQuestion());
holder.genQuestion.setTypeface(bold);
holder.genAnswer.setText(questionHero.getAnswer());
holder.genAnswer.setTypeface(regular);
holder.genFroms.setText(questionHero.getFroms());
holder.genFroms.setTypeface(regular);
holder.genTos.setText(questionHero.getTos());
holder.genTos.setTypeface(regular);
holder.genFromslogin.setText(questionHero.getFromslogin());
holder.genToslogin.setText(questionHero.getToslogin());
holder.genToslogin2.setText(questionHero.getToslogin());
holder.genDate.setText(questionHero.getDate());
holder.genDate.setTypeface(regular);
holder.genLikenum.setText(questionHero.getLikenum());
holder.genLikenum.setTypeface(regular);
holder.genCommentnum.setText(questionHero.getCommentnum());
holder.genCommentnum.setTypeface(regular);
holder.genPhoto.setImageUrl(questionHero.getPhoto(), imageLoader);
holder.genVideo.setText(questionHero.getVideo());
holder.genId.setText(questionHero.getQid());
}
供稿:
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the superhero object
QuestionList qHero = new QuestionList();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
//Adding data to the superhero object
qHero.setQuestion(json.getString("question"));
qHero.setAnswer(json.getString("answer"));
qHero.setUserphoto(json.getString("userphoto"));
qHero.setFroms(json.getString("froms"));
qHero.setTos(json.getString("tos"));
qHero.setFromslogin(json.getString("fromslogin"));
qHero.setToslogin(json.getString("toslogin"));
qHero.setDate(json.getString("date"));
qHero.setLikenum(json.getString("likenum"));
qHero.setCommentnum(json.getString("commentnum"));
qHero.setPhoto(json.getString("photo"));
qHero.setVideo(json.getString("video"));
qHero.setQid(json.getString("id"));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the superhero object to the list
listQuestions.add(qHero);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
适配器初始化:
class ViewHolder extends RecyclerView.ViewHolder{
//Views
public NetworkImageView genUserPhoto;
public TextView genQuestion;
public TextView genAnswer;
public TextView genFroms;
public TextView genTos;
public TextView genFromslogin;
public TextView genToslogin;
public TextView genToslogin2;
public TextView genDate;
public TextView genLikenum;
public TextView genCommentnum;
public NetworkImageView genPhoto;
public TextView genVideo;
public TextView genId;
public TextView genPhotourl;
public CardView cardRview;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
genUserPhoto = (NetworkImageView) itemView.findViewById(R.id.genUserPhoto);
genQuestion = (TextView) itemView.findViewById(R.id.genQuestion);
genAnswer = (TextView) itemView.findViewById(R.id.genAnswer);
genFroms = (TextView) itemView.findViewById(R.id.genFroms);
genTos = (TextView) itemView.findViewById(R.id.genTos);
genFromslogin = (TextView) itemView.findViewById(R.id.genFromslogin);
genToslogin = (TextView) itemView.findViewById(R.id.genToslogin);
genToslogin2 = (TextView) itemView.findViewById(R.id.genToslogin2);
genDate = (TextView) itemView.findViewById(R.id.genDate);
genLikenum = (TextView) itemView.findViewById(R.id.genLikenum);
genCommentnum = (TextView) itemView.findViewById(R.id.genCommentnum);
genPhoto = (NetworkImageView) itemView.findViewById(R.id.genPhoto);
genVideo = (TextView) itemView.findViewById(R.id.genVideo);
genId = (TextView) itemView.findViewById(R.id.genId);
genPhotourl = (TextView) itemView.findViewById(R.id.genPhotourl);
cardRview = (CardView) itemView.findViewById(R.id.cardRview);
}
}
因此,在您解析 JSON 时,某些键可能为空或不存在。在这种情况下,您的 questionHero 将包含 null。所以在调用代码之前你应该像这样检查
if (questionHero.getUserphoto() != null ) {
//in case you handle visibility in else block make //holder.genUserPhoto.setVisibility(View.VISIBLE) here visible
imageLoader.get(questionHero.getUserphoto(), ImageLoader.getImageListener(holder.genUserPhoto, R.drawable.header, android.R.drawable.ic_dialog_alert));
} else {
//reset image by questionHero.genUserPhoto.setImageBitmap(null), or handle //visibility of holder.genUserPhoto
}
与 questionHero.getPhoto()
为什么需要可见性或重置?
Recycler 视图重复使用项目,因此相同的视图将在其他位置重复使用,以防万一您不处理,最终会在错误的位置显示错误的图像。
几个性能提示
regular = Typeface.createFromAsset(context.getAssets(),"OpenSans-Regular.ttf");
bold = Typeface.createFromAsset(context.getAssets(),"OpenSans-Semibold.ttf");
永远不要在 bindViewHolder 中使用这样的代码,当你滚动时,这个方法会被一次又一次地调用,每次它都会从资产中创建字体,这足以让你的滚动变得迟缓。您应该为此创建一个单例class,它将创建一次字体并缓存它并在需要时提供给应用程序。
holder.genDate.setTypeface(regular);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
现在你已经在 bindViewHolder 中编写了这段代码,将这段代码移到 createViewHolder 中,因为设置一次字体就足够了,同样你应该获得一次图像加载器,尽管它不会有太大区别,因为 ImageLoader 本身是单例的,但是在 ViewHolder 级别仍然很好,只有视图的数据或属性会因每个回收器视图项目而改变,应该在 bindViewHolder 方法中处理。