title: In gridview adapter, getView(position == 0) was invoked too many times to measure layout when setImageBitmap() in a loader
body: <p>I have a <code>GridView</code> for showing some icons.</p>
  
  <p>BEFORE I had read this <a href="http://developer.android.com/training/displaying-bitmaps/index.html" rel="nofollow noreferrer">Displaying Bitmaps Efficiently</a> from Android developer site, I was decoding bitmap from local path directly in <code>getView()</code> of adapter, like this :</p>
  
  <pre><code>public View getView(int position, View convertView, ViewGroup parent) {
        ...
        ImageView icon = ...... (from getTag() of convertView)
        icon.setImageBitmap(BitmapUtil.decode(iconPath));
        ...
  }
  </code></pre>
  
  <p>this way works fine anyway, I called it [Direct Mode], the output log for <code>getView()</code> method should be :</p>
  
  <pre><code>getView(0)   // measure kid's layout.
  getView(0)
  getView(1)
  getView(2)
  ...
  getView(n)       // when scrolling gridview.
  getView(n+1)
  ...
  getView(n+3)    // scrolling again.
  getView(n+4)
  ...
  </code></pre>
  
  <p>then I am trying to change the code to [Loader Mode] mentioned in article <a href="http://developer.android.com/training/displaying-bitmaps/index.html" rel="nofollow noreferrer">Displaying Bitmaps Efficiently</a>, as following :</p>
  
  <pre><code>public View getView(int position, View convertView, ViewGroup parent) {
        ...
        ImageView icon = ...... (from getTag() of convertView)
        loadIcon(icon, iconPath);
        ...
  }
  </code></pre>
  
  <p>in <code>loadIcon()</code> :</p>
  
  <pre><code>...
  final CacheImageLoader loader = new CacheImageLoader(getActivity(), imageView, imageUrl, savePath);
  final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), placeHolderBitmap, loader);
  imageView.setImageDrawable(asyncDrawable);
  </code></pre>
  
  <p>in Loader's listener :</p>
  
  <pre><code>@Override
  public void onLoadComplete(Loader&lt;Bitmap&gt; arg0, Bitmap arg1) {
      ...
      ImageView imageView = imageViewReference.get();
      if (result != null &amp;&amp; imageView != null) {
          imageView.setImageBitmap(result);
      }
  }
  </code></pre>
  
  <p>Basically, it is same as the training code, actually, this way works fine as well. However, I found something different, in this mode the <code>getView()</code> method in adapter was invoked too many times, however, these repeat call to this method always with "position" parameter == 0, it means something invoke g<code>etView(0, X, X)</code> repeatedly. </p>
  
  <pre><code>getView(0)     // measure kid's layout.
  getView(0)
  getView(1)
  getView(2)
  ...    
  getView(0)     // loader completed then imageView.setImageBitmap(result); 
  getView(0)     // same as above
  getView(0)
  getView(0)
  ...
  getView(n)     // when scrolling gridview.
  getView(n+1)
  getView(n+2)
  getView(0)     // loader completed then imageView.setImageBitmap(result); 
  getView(0)     // same as above
  getView(0)
  ...
  getView(n+3)   // scrolling again.
  getView(n+4)
  getView(0)     // loader completed then imageView.setImageBitmap(result); 
  getView(0)     // same as above
  getView(0)
  </code></pre>
  
  <p>It is not good because I am using a loader in <code>getView()</code>. I have checked the source code and found they are originally called by <strong><code>imageView.setImageBitmap(result)</code></strong> in loader's  <code>onLoadComplete</code> method, and in <code>ImageView</code> :</p>
  
  <pre><code> /**
   * Sets a drawable as the content of this ImageView.
   * 
   * @param drawable The drawable to set
   */
  public void setImageDrawable(Drawable drawable) {
          ...
  
          int oldWidth = mDrawableWidth;
          int oldHeight = mDrawableHeight;
  
          updateDrawable(drawable);
  
          if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
              requestLayout();
          }
          invalidate();
      }
  }
  </code></pre>
  
  <p>here, <strong><code>requestLayout()</code></strong> is View's method and always executes in either [Direct Mode] or [Loader Mode],  in View.class :</p>
  
  <pre><code>public void requestLayout() {
      mPrivateFlags |= FORCE_LAYOUT;
      mPrivateFlags |= INVALIDATED;
  
      if (mLayoutParams != null) {
          mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
      }
  
      if (mParent != null &amp;&amp; !mParent.isLayoutRequested()) {
          mParent.requestLayout();
      }
  }
  </code></pre>
  
  <p>however the difference is: in  [Direct Mode], the  <code>mParent.requestLayout()</code> is invoked once, but in [Loader Mode], every time when i call <strong><code>imageView.setImageBitmap(result);</code></strong>, the  <code>mParent.requestLayout()</code> will be invoked as well, it means <code>mParent.isLayoutRequested()</code> return <code>false</code>, and <code>mParent.requestLayout();</code> will cause the <code>GridView</code> measure its kid's layout by calling <code>obtainView()</code> to first kid and then cause <code>getView(0, X, X)</code> :</p>
  
  <pre><code>@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      ...
      mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
      final int count = mItemCount;
      if (count &gt; 0) {
          final View child = obtainView(0, mIsScrap);
      ...
  </code></pre>
  
  <hr>
  
  <p>So, my <strong>question</strong> is: why <code>mParent.isLayoutRequested()</code> return <code>false</code> if I am using [loader mode]? or is it just a normal case ? </p>