2012-10-14 17 views
15

Tôi đang sử dụng Google Admob SDK phiên bản 6.1.0 (https://developers.google.com/mobile-ads-sdk/download) và tôi tạo nhanh com.google.ads.AdView theo chương trình (không phải trong XML) và thêm nó vào LinearLayout, động trong Hoạt động của tôi.WebViewCoreThread được sử dụng bởi admob AdView đang sử dụng CPU cao ngay cả khi hoạt động gốc bị tạm dừng

Một trong những người dùng của tôi đã báo cáo rằng khi họ nhấp vào nút Trang chủ trong khi hoạt động của tôi (để nền), họ bắt đầu thấy mức sử dụng CPU cao có nguồn gốc từ ứng dụng của tôi. Tôi đã có thể tái tạo điều này trên một nền tảng Jellybean, và nhận thấy rằng nguồn cho việc sử dụng CPU cao là một WebViewCoreThread.

Hoạt động của tôi không sử dụng bất kỳ WebView nào, nhưng tôi đã có thể thực hiện bước khởi động của Hoạt động của mình và nhận thấy rằng WebViewCoreThread này bắt đầu khi tôi khởi tạo đối tượng AdView AdMob. Là trạng thái trong tài liệu tham khảo của AdMob, tôi gọi hàm destroy() trên AdView này trong phương thức onDestroy() của Activity. Và tôi đã thay đổi mã của mình để gọi AdView.onDestroy() trong phương thức onPause() của tôi. Nhưng dường như không có gì khiến cho WebViewCoreThread ngừng hoạt động. Tôi đoán, tôi không sao nếu sợi chỉ dính quanh. Nhưng nếu tôi bắt đầu hoạt động của tôi nhiều lần hơn và hơn nữa, chủ đề này bắt đầu sử dụng bất cứ nơi nào giữa 8 đến 25% của CPU của tôi, thậm chí hoạt động của tôi không phải là ở phía trước.

Tôi nhận thấy một vài người dùng khác nói rằng bạn phải gọi cho WebView.onPause() như một hành động khắc phục. (http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3) Nhưng điều này không trực tiếp có thể cho tôi, vì chế độ xem web của tôi được tạo bởi AdView của AdMob. Tôi cũng đã thay đổi mã của mình để gọi .removeAllViews() cho đối tượng LinearLayout chứa của đối tượng mt Admob AdView, và sau đó gọi System.gc() để buộc thu gom rác, nhưng không có gì để giết WebViewCoreThread của tôi và cuối cùng nó bắt đầu ăn CPU cho đến khi tôi bắt buộc -quá trình của ứng dụng của tôi.

Bất kỳ manh mối nào tại sao AdMob thực hiện việc này và cách tôi có thể buộc chủ đề này bị giết?

Tôi đang gắn một lớp mà tôi đã tạo để đóng gói việc tạo và hủy của AdView. Tôi gọi phương thức getNewAd() của lớp này trong khởi tạo hoạt động của tôi. Và tôi gọi removeAd của lớp này() trong onPause Hoạt động của tôi() và onDestroy() phương pháp:

package com.shiprack.client; 

import com.google.ads.AdRequest; 
import com.google.ads.AdSize; 
import com.google.ads.AdView; 
import com.mobclix.android.sdk.Mobclix; 
import com.mobclix.android.sdk.MobclixMMABannerXLAdView; 

import android.app.Activity; 
import android.view.Gravity; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.LinearLayout; 

public class AdManager { 
    public AdManager(EventLog logger, LinearLayout container, Activity activity) { 
     _container = container; 
     _activity = activity; 
     _eventLogger = logger; 
    } 

    public void setNetwork(int network) { 
     _network = network; 
    } 

    public void getNewAd() { 
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT); 
     params.gravity = Gravity.CENTER; 
     switch (_network) { 
      case TrackDatabase.AD_NETWORK_ADMOB: { 
       _admobBanner = new AdView(_activity, AdSize.BANNER, "a14dc419375634c"); 
       _container.addView(_admobBanner, params); 
       _admobBanner.loadAd(new AdRequest()); 
       break; 
      } 
      case TrackDatabase.AD_NETWORK_MOBCLIX: { 
       Mobclix.onCreate(_activity); 
       _mobclixBanner = new MobclixMMABannerXLAdView(_activity); 
       _container.addView(_mobclixBanner, params); 
       _mobclixBanner.getAd(); 
       break; 
      } 
     } 
    } 

    public void removeAd() { 
     switch (_network) { 
      case TrackDatabase.AD_NETWORK_ADMOB: { 
       _admobBanner.destroy(); 
       break; 
      } 
      case TrackDatabase.AD_NETWORK_MOBCLIX: { 
       _mobclixBanner.cancelAd(); 
       break; 
      } 
     } 
     _container.removeAllViews(); 
    } 

    private EventLog _eventLogger; 
    private LinearLayout _container; 
    private Activity _activity; 
    private AdView _admobBanner; 
    private MobclixMMABannerXLAdView _mobclixBanner; 
    private int _network; 
} 
+0

tôi nghĩ rằng tôi đã có làm việc này, nhưng tôi không thêm này như là một nguyên nhân gây ra câu trả lời tôi không hoàn toàn thuyết phục được nêu ra. Sau khi gọi tiêu diệt() trên đối tượng AdMob AdView, bây giờ tôi thiết lập các tài liệu tham khảo để null , loại bỏ tất cả các tham chiếu đến AdView, có thể làm cho nó bị thu gom rác, và do đó, tránh bất kỳ WebViewCoreThreads nào chạy vô thời hạn.Tuy nhiên, tôi không thích phương pháp này - công việc dọn dẹp như vậy sẽ được xử lý trong phá hủy AdMob. Hoặc thực sự, tôi thậm chí không nên gọi phá hủy() - nó s thấp xuống hoạt động của tôi onPause. – Shiprack

Trả lời

3

Sau khi gọi tiêu diệt() trên đối tượng AdMob AdView, bây giờ tôi thiết lập các tham chiếu đến null, mà loại bỏ tất cả các tài liệu tham khảo với AdView, có thể làm cho nó bị thu gom rác, và do đó, tránh bất kỳ WebViewCoreThreads nào chạy vô thời hạn. Nói chung, tôi không thích cách tiếp cận này - công việc dọn dẹp như vậy nên được xử lý trong phá hủy AdMob. Hoặc thực sự, tôi thậm chí không cần phải gọi phá hủy() - nó làm chậm hoạt động của tôi onPause.

Mặc dù vậy, nhiều người dùng của tôi phàn nàn chậm khi nhấn nút quay lại hoặc nút trang chủ trong ứng dụng của tôi. Rõ ràng, điều này là do thời gian được sử dụng trong phương thức onPause() trong khi gọi admob destroy(). Giải pháp dài hạn là sử dụng Fragments và ActionBar, và không phải tạo nhiều bản sao của biểu ngữ Admob (một trong mọi hoạt động)

+0

Có thể bắn phá hủy đô đốc trong một chủ đề? – stu

10

Không chắc ai vẫn cần thông tin này, nhưng tôi đã tìm kiếm giải pháp chính điều này. Dường như AdMob vẫn còn thiếu sót.

Vấn đề duy nhất là, điều này sẽ ngăn tất cả WebView chạy từ chế độ nền. Chỉ có một vấn đề nếu ứng dụng của bạn phụ thuộc vào điều này để hoạt động.

Thêm vào onPause():

new WebView(this).pauseTimers(); 

onResume():

new WebView(this).resumeTimers(); 

này xuất thân từ một nhân viên Google đã tuyên bố rằng họ đang xem xét nó: https://groups.google.com/d/msg/google-admob-ads-sdk/Qu4G19NFAuI/wcNkoV0AeDUJ

+0

Cảm ơn bạn! Tôi sẽ thử cái này – Shiprack

+0

Hy vọng điều đó sẽ hữu ích. Nó đã làm việc kỳ diệu đối với tôi, nhưng nó sẽ tốt hơn nếu AdView.pause() làm việc như nó cần. –

+0

Đây là giải pháp phù hợp (và là giải pháp duy nhất làm việc cho tôi) cho phiên bản AdMob mới (có trong các dịch vụ của Google Play). – Szymon

3

PZolee đăng trên chủ đề này và giải pháp được đề xuất trong blog của mình: https://pzoleeblogen.wordpress.com/2014/07/08/android-how-to-solve-adview-cpu-consuming/

tôi điều tra này hơn nữa (trong các ý kiến ​​cho bài viết trên blog được ghi lại cuộc đấu tranh của tôi) và đi đến kết luận sau:

  1. Thật vậy, gọi chỉ adView.pause(); không ngăn thành phần Quảng cáo của Google sử dụng CPU ngay cả khi ứng dụng ở chế độ nền và quảng cáo không hiển thị.
  2. Tìm tất cả các WebViews bên trong một adview của chúng tôi và kêu gọi onPause() và onResume() phương pháp WevView trên chúng không giải quyết được vấn đề tiêu thụ CPU không cần thiết.
  3. Chỉ cuộc gọi đến phương thức tạm dừng WebViewTimers() và resumeTimers() mới làm tác giả của bài đăng ở trên đề xuất sẽ dừng mức tiêu thụ CPU không cần thiết.
  4. Tìm đệ quy tất cả các WebView và gọi pauseTimers() và resumeTimers() trên tất cả chúng là không cần thiết, vì một cuộc gọi như vậy "Pauses (hoặc resumes - g.) Tất cả bố trí, phân tích cú pháp và JavaScript giờ cho tất cả WebViews. (trong một tiến trình - g.) ”- xem tài liệu thành phần WebView.
  5. Nếu bạn sử dụng WebView ở bất kỳ nơi nào khác trong ứng dụng của mình - có thể trong các hoạt động khác, bạn phải tiếp tụcTimers() cho nó, hoặc nó sẽ không hoạt động đúng. Ngoài ra, hãy lưu ý rằng một WevView có thể được xây dựng tạm thời và được sử dụng bởi một số chức năng thư viện mà bạn sử dụng trong dự án của mình, mà bạn không biết rõ về nó. Nó có thể là ví dụ một dấu nhắc để đăng nhập vào một số trang web, mạng xã hội vv Webview như vậy một lần nữa có thể không hoạt động đúng, nếu pauseTimers() được gọi trong quá trình của bạn ở đâu đó và bạn không tiếp tục chúng. SỬ DỤNG THẬN TRỌNG VÀ KIỂM TRA tất cả các bạn có thể.

Thật đáng tiếc, Google và AdMob đã xử lý chúng tôi một bất ngờ khó chịu với thành phần quảng cáo của họ (tiêu thụ CPU liên tục ngay cả khi bạn nền ứng dụng, ẩn thành phần của họ, thậm chí tạm dừng() với cuộc gọi API của riêng họ ...

Các vấn đề liên quan