如何避免Admob阻塞UI线程

12

我发现我的一些活动在启动时被阻止了。因此,我在一个新项目中编写了这段代码:

public class LayoutTestActivity extends Activity {

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

        long now = System.currentTimeMillis();

        new AdView(this, AdSize.BANNER, "MY_ID");

        Log.e("Admob Test","The UI was blocked "+(System.currentTimeMillis()-now)+"ms");
    }
}

结果是第一次创建AdView对象会阻塞UI线程1到2秒钟。

有没有避免这种情况的方法?

谢谢

5个回答

4

我有一个类似的问题。通过延迟1秒钟的广告请求来解决它(这样可以给AdView加载时间,不会阻塞用户界面)。

        new Timer().schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                MainActivity.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        AdRequest adRequest = new AdRequest.Builder()
                                .addTestDevice(AD_TEST_DEVICE)
                                .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                                .build();

                        adView.loadAd(adRequest);
                    }
                });
            }
        }, 1000);

但是在文档中,他们说:“注意:所有对移动广告 SDK 的调用都必须在主线程上进行。” - baderkhane
@baderkhane UI线程是应用程序的主线程...我有另一个解决方案,请看我的答案。 - Ucdemir

1
这是我的解决方案:
  public class YHYBackgroundThread extends AsyncTask<Object, Object, Object> {
        private YHYBackgroundListener mListener;
        private Context context;
    
        public YHYBackgroundThread(Context context) {
    
            this.context= context;
    
        }
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
    
    
    
        }
    
        @Override
        protected Object doInBackground(Object... params) {
    
            if(mListener != null){
                return  mListener.onBackground(params);
            }
    
            return null;
        }
    
        @Override
        protected void onPostExecute(Object t) {
            if (mListener != null) {
    
    
                mListener.onPostExecute(t);
                
            }
        }
    
        public YHYBackgroundThread setListener(YHYBackgroundListener mListener){
    
            this.mListener = mListener;
    
            return this;
        }
    
    }

YHYBackgroundListener
public interface YHYBackgroundListener {

    Object onBackground(Object... params);
    void onPostExecute(Object list);
}

在需要展示广告时调用此函数

   new YHYBackgroundThread(context).setListener(


                    new YHYBackgroundListener() {
                        @Override
                        public Object onBackground(Object... params) {

                            AdRequest request = new AdRequest.Builder().build();


                            return request;
                        }

                        @Override
                        public void onPostExecute(Object list) {

                            AdRequest request = (AdRequest) list;
                            adView.loadAd(request);
                        }
                    }
            ).execute();

1
使用线程:
public class LayoutTestActivity extends Activity {

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

    long now = System.currentTimeMillis();

    new Thread(new Runnable() {

        public void run() {
            new AdView(this, AdSize.BANNER, "MY_ID");               
        }
    }).start();

    Log.e("Admob Test","The UI was blocked "+(System.currentTimeMillis()-now)+"ms");
}

你的代码需要一个Looper准备,但是这确实是更简单的解决方案。无论如何,谷歌产品阻塞UI的时间太长了,这很奇怪。 - Addev

0

您正在UI线程中创建AdView,这就是被阻塞的原因。当AdView初始化时,该线程将不会执行任何其他操作。

您可以尝试在另一个线程中加载AdView,或者可以使用AsyncTask以UI安全的方式加载它。

有关Android中AsyncTask和线程的更多信息,请查看此处。

http://developer.android.com/reference/android/os/AsyncTask.html


9
您不能在 AsyncTask 中调用 loadAd。 - Dũng Trần Trung

0
在我的情况下,我在一个请求中请求了太多的广告项。堆已经超载并且GC开始执行,阻塞了我的主线程。建议尝试避免在一个请求中请求太多的广告。
adLoader.loadAds(AdRequest.Builder().build(), 1)

AdLoader似乎只适用于原生广告。请参考以下链接:https://developers.google.com/android/reference/com/google/android/gms/ads/AdLoader - Ucdemir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接