1

Ich versuche, Facebook Native Ads zu implementieren, indem Sie sie als eine alternative Ansicht in meinem RecyclerAdapter einschließen. Hat jemand damit Erfahrungen gemacht? Ich habe meine ganze Klasse für gutes Maß eingeschlossen.Facebook Native Ads mit RecyclerAdapter

public class FeedRecyclerAdapter extends LoadingRowRecyclerAdapter implements AdListener { 

    private static final int VIEW_TYPE_FEED = 1; 
    private static final int VIEW_TYPE_AD = 2; 

    private final Context context; 
    private final List<Feed> feedItems; 
    private final ImageLoader feedItemImageLoader; 
    private FeedItemClickListener feedItemClickListener; 
    private boolean isLongPressed = false; 

    private NativeAd nativeAd; 
    private NativeAdsManager manager; 
    View adView; 

    public FeedRecyclerAdapter(Context context, List<Feed> feedItems, ImageLoader feedItemImageLoader, NativeAd nativeAd, NativeAdsManager manager) { 
     this.context = context; 
     this.feedItems = feedItems; 
     this.feedItemImageLoader = feedItemImageLoader; 
     this.nativeAd = nativeAd; 
     this.manager = manager; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     switch (viewType) { 
      case VIEW_TYPE_FEED: 
       return new FeedViewHolder(new FeedItemView(context)); 
      case VIEW_TYPE_AD: 
       return new AdditionalHolder(LayoutInflater.from(context).inflate(R.layout.ad_test3, parent, false)); 
     } 

     return super.onCreateViewHolder(parent, viewType); 
    } 

    public class AdditionalHolder extends RecyclerView.ViewHolder { 
     protected LinearLayout templateContainer; 
     protected ImageView blank_holder; 
     private LinearLayout nativeAdContainer; 
     private LinearLayout adView; 
     private AdChoicesView adChoicesView; 
     ImageView nativeAdIcon; 
     TextView nativeAdTitle; 
     TextView nativeAdBody; 
     MediaView nativeAdMedia; 
     TextView nativeAdSocialContext; 
     Button nativeAdCallToAction; 

     public AdditionalHolder(View view) { 
      super(view); 

      //// Add ad into the ad container. 
      nativeAdContainer = (LinearLayout) view.findViewById(R.id.ad_unit); 
      LayoutInflater inflater = LayoutInflater.from(context); 
      adView = (LinearLayout) inflater.inflate(R.layout.ad_test3, nativeAdContainer, false); 
      nativeAdContainer.addView(adView); 

      // Create native UI using the ad metadata. 
      nativeAdIcon = (ImageView) view.findViewById(R.id.native_ad_icon); 
      nativeAdTitle = (TextView) view.findViewById(R.id.native_ad_title); 
      nativeAdBody = (TextView) view.findViewById(R.id.native_ad_body); 
      nativeAdMedia = (MediaView) view.findViewById(R.id.native_ad_media); 
      nativeAdSocialContext = (TextView) view.findViewById(R.id.native_ad_social_context); 
      nativeAdCallToAction = (Button) view.findViewById(R.id.native_ad_call_to_action); 

     } 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { 
     if (getItemViewType(position) == VIEW_TYPE_FEED) { 
      bindFeedItemView((FeedViewHolder) viewHolder, position); 
     } else if (getItemViewType(position) == VIEW_TYPE_AD) { 

      AdditionalHolder new_holder = (AdditionalHolder) viewHolder; 
      try { 
       new_holder.templateContainer.removeViewInLayout(adView); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      nativeAd = manager.nextNativeAd(); 
      try { 
       adView = NativeAdView.render(context, nativeAd, NativeAdView.Type.HEIGHT_300); 
      } catch (NullPointerException e) { 
       e.printStackTrace(); 
      } 

      new_holder.templateContainer.addView(adView); 
      new_holder.blank_holder.setVisibility(View.GONE); 

      // Setting the Text. 
      new_holder.nativeAdSocialContext.setText(nativeAd.getAdSocialContext()); 
      new_holder.nativeAdCallToAction.setText(nativeAd.getAdCallToAction()); 
      new_holder.nativeAdTitle.setText(nativeAd.getAdTitle()); 
      new_holder.nativeAdBody.setText(nativeAd.getAdBody()); 

      // Downloading and setting the ad icon. 
      NativeAd.Image adIcon = nativeAd.getAdIcon(); 
      NativeAd.downloadAndDisplayImage(adIcon, new_holder.nativeAdIcon); 

      // Download and setting the cover image. 
      NativeAd.Image adCoverImage = nativeAd.getAdCoverImage(); 
      new_holder.nativeAdMedia.setNativeAd(nativeAd); 

      // Add adChoices icon 
      if (new_holder.adChoicesView == null) { 
       new_holder.adChoicesView = new AdChoicesView(context, nativeAd, true); 
       new_holder.adView.addView(new_holder.adChoicesView, 0); 
      } 

      nativeAd.registerViewForInteraction(new_holder.adView); 

     } 
    } 

    // Differentiate between feedItem views and nativeAds 
    @Override 
    public int getItemViewType(int position) { 
     int viewType = 1; 
     if ((position % 9 == 0) && position != 1) viewType = 2; 
     return viewType; 
    } 

    // For feedItems 
    private void bindFeedItemView(FeedViewHolder viewHolder, int position) { 
     final FeedItemView feedItemView = viewHolder.feedItemView; 
     final Feed feedDesign = feedItems.get(position); 

     // TODO we can probably conditionally show or hide these based on the type of feed item, same as in FeedActivitySingle 
     feedItemView.showOrHideEditButton(true); 
     feedItemView.showOrHideBuyButton(false); 
     feedItemView.showOrHideFlipButton(false); 
     feedItemView.showOrHidePriceText(false); 

     // Set the results into TextViews 
     feedItemView.setProductPriceText(String.valueOf(feedDesign.getDesign().getPrice())); 
     feedItemView.setDownloadsText(String.valueOf(feedDesign.getDesign().getDownloadCount())); 
     feedItemView.setLikesText(String.valueOf(feedDesign.getDesign().getLikesCount())); 
     feedItemView.setUsernameText(feedDesign.getDesign().getAuthor().getUsername()); 
     feedItemView.setTimestampText(feedDesign.getTimestampText()); 
     feedItemView.getSaveImage().setImageResource(feedDesign.isInPersonalGallery() ? R.drawable.ic_action_saved : R.drawable.ic_not_saved); 
     feedItemView.getLikeImage().setImageResource(feedDesign.isLiked() ? R.drawable.ic_action_like_feed_full : R.drawable.ic_action_like_feed); 

     feedItemView.getTrashImage().setVisibility(ParseHelper.isCurrentUser(feedDesign.getDesign().getAuthor().getObjectId()) ? View.VISIBLE : View.GONE); 
     feedItemView.getFeedSocialShareImage().setVisibility(View.VISIBLE); 

     feedItemImageLoader.DisplayImage(feedDesign.getDesign().getCompressedImage().getUrl(), feedItemView.getImage(), feedItemView.getProgressBar()); 

     if(feedDesign.getDesign().getAuthor().getProfilePicture() != null) { 
      feedItemImageLoader.DisplayImage(feedDesign.getDesign().getAuthor().getProfilePicture().getUrl(), feedItemView.getProfilePicture(), null); // TODO should this use profilePictureFileCache? 
     } else { 
      viewHolder.feedItemView.getProfilePicture().setImageResource(R.drawable.ic_anonymous); 
     } 

     SetCommentViews(feedItemView, feedDesign.getComments()); 
     SetClickListeners(feedItemView, feedDesign); 
    } 

    @Override 
    protected int getContentDataSize() { 
     return feedItems.size(); 
    } 

    @Override 
    protected int getViewType(int position) { 
     if (position == 1) { 
      return VIEW_TYPE_FEED; 
     } else { 
      return VIEW_TYPE_AD; 
     } 
    } 

    // Facebook Ad methods 
    @Override 
    public void onError(Ad ad, AdError adError) { 

    } 

    @Override 
    public void onAdLoaded(Ad ad) { 

    } 

    @Override 
    public void onAdClicked(Ad ad) { 

    } 

    public void setFeedItemClickListener(FeedItemClickListener feedItemClickListener) { 
     this.feedItemClickListener = feedItemClickListener; 
    } 

    private void SetCommentViews(FeedItemView feedItemView, List<Comment> comments) { 

     feedItemView.getViewAllComments().setVisibility(View.VISIBLE); 
     feedItemView.setViewAllComments("View more comments"); 

     // reset layouts to hidden 
     feedItemView.getComment1Layout().setVisibility(View.GONE); 
     feedItemView.getComment2Layout().setVisibility(View.GONE); 
     feedItemView.getComment3Layout().setVisibility(View.GONE); 

     if (comments == null || comments.size() == 0) { 
      feedItemView.getViewAllComments().setVisibility(View.GONE); 
      return; 
     } 

     // note these are meant to fall-through without break statements 
     switch (comments.size()) { 
      case 3: 
       feedItemView.getComment3Layout().setVisibility(View.VISIBLE); 
       feedItemView.setCommentUser3(comments.get(2).getAuthor().getUsername()); 
       feedItemView.setCommentText3(comments.get(2).getComment()); 
      case 2: 
       feedItemView.getComment2Layout().setVisibility(View.VISIBLE); 
       feedItemView.setCommentUser2(comments.get(1).getAuthor().getUsername()); 
       feedItemView.setCommentText2(comments.get(1).getComment()); 
      case 1: 
       feedItemView.getComment1Layout().setVisibility(View.VISIBLE); 
       feedItemView.setCommentUser1(comments.get(0).getAuthor().getUsername()); 
       feedItemView.setCommentText1(comments.get(0).getComment()); 
       break; 
     } 
    } 

    private void SetClickListeners(final FeedItemView feedItemView, final Feed feedDesign) { 

     // setup gesture detector with current view, view holder, and feed design 
     final GestureDetector gestureDetector = new GestureDetector(context, new GestureListener(feedDesign, feedItemView)); 

     // set gesture detector on image view 
     feedItemView.setImageTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View view, MotionEvent motionEvent) { 
       if (motionEvent.getAction() == ACTION_UP){ 
        if (isLongPressed){ 
         isLongPressed = false; 
         feedItemClickListener.onMarkteFeedImageLongPressed_Release(); 
         Log.d("anyTAG","Up"); 
         return true; 
        } 
       } 
       if (motionEvent.getAction() == ACTION_MOVE){ 
        return true; 
       } 
       return gestureDetector.onTouchEvent(motionEvent); 
      } 
     }); 

     feedItemView.setTrashImageClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onTrashClicked(feedDesign); 
      } 
     }); 

     feedItemView.setFeedSocialShareClickListener(v -> { 
      if (feedItemClickListener != null) { 
       try { 
        feedItemClickListener.onSocialShareClicked(feedDesign); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 

     feedItemView.setLikeImageClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onLikeClicked(feedDesign, feedItemView); 
      } 
     }); 

     feedItemView.setSaveImageClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onSaveClicked(feedDesign, feedItemView); 
      } 
     }); 

     feedItemView.setAuthorClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onAuthorClicked(feedDesign); 
      } 
     }); 

     feedItemView.setCommentTextClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onCreateCommentClicked(feedDesign); 
      } 
     }); 

     feedItemView.setViewAllCommentsClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onCreateCommentClicked(feedDesign); 
      } 
     }); 

     feedItemView.setEditImageClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onCreateEditImageClicked(feedDesign); 
      } 
     }); 

     feedItemView.setCommentImageClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onCreateCommentClicked(feedDesign); 
      } 
     }); 

     feedItemView.setCommentUser1ClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onAuthorClicked(feedDesign.getComments().get(0).getAuthor().getObjectId()); 
      } 
     }); 

     feedItemView.setCommentUser2ClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onAuthorClicked(feedDesign.getComments().get(1).getAuthor().getObjectId()); 
      } 
     }); 

     feedItemView.setCommentUser3ClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onAuthorClicked(feedDesign.getComments().get(2).getAuthor().getObjectId()); 
      } 
     }); 

     feedItemView.setProfilePictureClickListener(v -> { 
      if (feedItemClickListener != null) { 
       feedItemClickListener.onProfilePictureClicked(feedDesign); 
      } 
     }); 

    } 

    class FeedViewHolder extends RecyclerView.ViewHolder { 

     FeedItemView feedItemView; 

     public FeedViewHolder(FeedItemView view) { 
      super(view); 
      this.feedItemView = view; 
     } 

    } 

    // Gesture detector for double tap 
    private class GestureListener extends GestureDetector.SimpleOnGestureListener { 

     private Feed feedDesign; 
     private FeedItemView feedItemView; 

     public GestureListener(Feed feedDesign, FeedItemView feedItemView) { 
      this.feedDesign = feedDesign; 
      this.feedItemView = feedItemView; 
     } 

     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public boolean onDoubleTap(MotionEvent event) { 
      Log.d("FeedRecyclerAdapter", feedDesign.getDesign().getCompressedImage().getUrl()); 

      if (feedItemClickListener != null) { 
       feedItemClickListener.onImageDoubleTapped(feedDesign, feedItemView); 
      } 

      return true; 
     } 

     @Override 
     public void onLongPress(MotionEvent event) { 

      if (event.getAction() == ACTION_DOWN) 
      { 
       if (!isLongPressed){ 
        isLongPressed = true; 
        feedItemClickListener.onMarketFeedImageLongPressed(feedDesign, feedDesign.getDisplayedSide()); 
       } 
      } 
     } 
    } 
} 

ich die folgende Ausnahme erhalten:

07-01 16:32:12.509 23168-23168/com.elgami.customizer E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.elgami.customizer, PID: 23168 
java.lang.NullPointerException: Attempt to invoke virtual method 'com.facebook.ads.NativeAd com.facebook.ads.NativeAdsManager.nextNativeAd()' on a null object reference 
at com.elgami.feed.FeedRecyclerAdapter.onBindViewHolder(FeedRecyclerAdapter.java:121) 
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5768) 
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5801) 
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5037) 
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913) 
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029) 
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414) 
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377) 
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:578) 
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3260) 
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3069) 
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3518) 
at android.view.View.layout(View.java:16636) 
at android.view.ViewGroup.layout(ViewGroup.java:5437) 
at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:598) 
at android.view.View.layout(View.java:16636) 
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:16636) 
at android.view.ViewGroup.layout(ViewGroup.java:5437) 
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079) 
at android.view.View.layout(View.java:16636) 
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:16636) 
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:16636) 
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:16636) 
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:16636) 
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:16636) 
at android.view.ViewGroup.layout(ViewGroup.java:5437) 
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171) 
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931) 
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107) 
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013) 
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
at android.view.Choreographer.doFrame(Choreographer.java:606) 
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
at android.os.Ha 

Zunächst scheint es, über diese Linie beschwert werden:

nativeAd = manager.nextNativeAd(); 

Hier ist ein Kern meine FeedActivity Klasse:

+0

Dieser Fehler zeigt an, dass '' Manager' ist null' wenn Sie versuchen, 'nextNativeAd' darauf zu nennen. Sie sollten überprüfen, ob Sie tatsächlich einen gültigen Manager an Ihren Konstruktor übergeben. –

+0

Wie würde ich das feststellen? – santafebound

+1

Sie könnten beginnen, indem Sie suchen, wo Sie 'new FeedRecyclerAdapter (...) 'und überprüfe zum Beispiel, dass du nicht versehentlich einen literalen' null'-Wert als 'manager'-Argument an deinen Konstruktor übergibst. Wenn Sie nicht sofort sehen, warum Sie dort eine "Null" erhalten, schließen Sie einen Debugger an, um besser zu verstehen, was mit Ihrem Programm passiert, während es läuft. Es gibt gute Tipps unter http://stackoverflow.com/q/218384/1321716. Wenn Sie es immer noch nicht herausfinden können, aktualisieren Sie Ihren Code, um weiteren Code hinzuzufügen, damit andere versuchen können, Ihnen zu helfen. –

Antwort

1

Ein NullPointerException tritt auf, wenn Sie versuchen, eine Methode aufzurufen oder auf ein Feld einer Objektreferenz zuzugreifen, diese Referenz jedoch kein gültiges Objekt enthält. Ein einfaches Beispiel wäre:

String someString; 
char firstChar = someString.charAt(0); // ERROR! 

Dieser Code wirft einen Fehler, da die someString Variable eine gültige String Instanz verweisen nicht auf, wenn charAt genannt wird. Beachten Sie, dass die erste Zeile keine eine String Instanz erstellt, sondern nur eine Variable deklariert, die Punkt an eine String. In der Tat ist dieser Code Äquivalent zu:

String someString = null; 
char firstChar = someString.charAt(0); 

Weitere Informationen zu NullPointerException s, warum sie auftreten und wie man sie beheben: see this question.

In Ihrem Fall wird der Fehler durch line 176 in FeedActivity verursacht:

feedRecyclerAdapter = new FeedRecyclerAdapter(this, feedItems, new ImageLoader(new FeedItemFileCache(this)), nativeAd, manager); 

Hier ist manager eine Instanz Feld der FeedActivity Klasse, definiert auf line 87:

public NativeAdsManager manager; 

Das Problem ist, dass Dieses Feld ist nie mit einem Wert belegt: Zu diesem Feld gibt es keine Zuweisungen (z. B. manager = ...). Wenn die Zeile 176 ausgeführt wird, empfängt die FeedRecyclerAdapternull als ihr manager Argument, und wirft eine NullPointerException später in onBindViewHolder, wenn es versucht, diese manager zu verwenden.

Die Lösung besteht darin, einen gültigen NativeAdsManager in Ihrem FeedActivity zu erstellen und ihn manager zuzuweisen, bevor Sie ihn an FeedRecyclerAdapter übergeben. , einen solchen Code sollte wie folgt aussehen:

public class YourActivity extends Activity implements NativeAdsManager.Listener { 

    private NativeAdsManager manager; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 

     manager = new NativeAdsManager(this, "YOUR_PLACEMENT_ID", 5); 
     manager.setListener(this); 
     manager.loadAds(); 

    } 
} 
+0

Danke, das ist sinnvoll in der Haupt-Feed-Aktivität zu initialisieren. Diese Ausnahme wurde mindestens gelöst! – santafebound