如何解决在Recycler View中成功实施Native Advanced Ads之后,应用在少数情况下仍然崩溃
在Native Advanced
中成功实施RecyclerView
广告之后,应用仍然在少数情况下崩溃。
此处的源代码:Codelabs Developers Google - Native Advanced Feed
附带的屏幕截图来自Android设备-型号:Redmi 7A,Android版本:9.0
主要问题:在实施本机高级Feed后,应用程序崩溃急剧增加,从而增加了该应用程序的卸载次数。
我尝试过的事情:
在8台设备上进行的Firebase Robo测试全部通过。
没有来自Google网上论坛线程的帮助:
- Google Admob Ads Sdk
- App freezes when Native Unified ads are loaded
- NativeAdView.setNativeAd is slow and blocking the main thread
这是Firebase Crashlytics
堆栈跟踪
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at androidx.fragment.app.FragmentManager.checkStateLoss(FragmentManager.java:11)
at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:26)
at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:70)
at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:1)
at in.careerdost.quiznew.recycler_activity.recycler_archived.loadMenu(recycler_archived.java:23)
at in.careerdost.quiznew.recycler_activity.recycler_archived.access$100(recycler_archived.java)
at in.careerdost.quiznew.recycler_activity.recycler_archived$1.onAdFailedToLoad(recycler_archived.java:24)
at com.google.android.gms.internal.ads.zzvc.zzc(zzvc.java:6)
at com.google.android.gms.internal.ads.zzws.zza(zzws.java:13)
at com.google.android.gms.internal.ads.zzgt.onTransact(zzgt.java:22)
at android.os.Binder.transact(Binder.java:914)
at fw.b(fw.java:2)
at com.google.android.gms.ads.internal.client.ai.a(ai.java:3)
at com.google.android.gms.ads.nonagon.shim.m.a(m.java:4)
at com.google.android.gms.ads.nonagon.shim.listeners.a.a(a.java)
at com.google.android.gms.ads.nonagon.shim.loaders.g.run(g.java)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at qh.a(qh.java)
at com.google.android.gms.ads.internal.util.f.a(f.java:1)
at qh.dispatchMessage(qh.java)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7814)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
更新:onAdFailedToLoad
和loadMenu
方法
private void loadNativeAds() {
AdLoader.Builder builder = new AdLoader.Builder(this,getString(R.string.ad_unit_id_native_advanced));
adLoader = builder.forUnifiedNativeAd(
unifiedNativeAd -> {
mNativeAds.add(unifiedNativeAd);
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
loadMenu();
}
}).withAdListener(
new AdListener() {
@Override
//public void onAdFailedToLoad(int errorCode) {
public void onAdFailedToLoad(LoadAdError adError) {
Log.e("RecyclerPdf","The previous native ad failed to load. Attempting to load another.");
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
loadMenu();
}
}
}).build();
adLoader.loadAds(new AdRequest.Builder().build(),NUMBER_OF_ADS);
}
private void insertAdsInMenuItems() {
if (mNativeAds.size() <= 0) {
return;
}
int offset = (mRecyclerViewItems.size() / mNativeAds.size()) + 1;
int index = 0;
for (UnifiedNativeAd ad : mNativeAds) {
mRecyclerViewItems.add(index,ad);
index = index + offset;
}
//loadMenu();
}
private void loadMenu() {
Fragment newFragment = new recycler_view_fragment_pdf();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container_pdf,newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
用于在片段中调用Activity:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
recycler_pdf activity = (recycler_pdf) getActivity();
assert activity != null;
mRecyclerViewItems = activity.getRecyclerViewItems();
}
我的结论:我认为有时是由于连接缓慢,但不确定如何在此处实现。
任何帮助将不胜感激!谢谢!
解决方法
这里的问题是AdListener
是一个独立的回调,它不了解Activity的生命周期。这里发生的是在某些情况下,当AdListener
回调返回时,Activity
已被销毁(也许用户只是按下了后退按钮),因此您在此Activity的Context上执行的任何操作都将崩溃,因为它现在无效。
AsyncTask
也有同样的问题。
要避免这种情况,请在调用任何进一步的东西之前检查“活动是否有效”。可以通过:-
public void onAdFailedToLoad(LoadAdError adError) {
if (!adLoader.isLoading() && !isFinishing()) {
insertAdsInMenuItems();
loadMenu();
}
}
对于活动,您可以使用isFinishing()
进行检查。在片段中,您可以检查getActivity()
或isAdded()
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。