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 方法中处理。