我正在尝试在我的应用中实施非页内广告。我使用postDelayed处理程序将插页式广告的显示延迟10秒。
我的小应用使用片段。我有片段1,它包含一个按钮,通过片段替换事务转到片段2。
我遇到的问题是正在制作相同任务的多个实例,导致多于1个插页式广告显示(这不好)。如果你进入片段2,按回然后再次进入片段2,就会发生这种情况。
我想要的是一种只为此runnable允许单个处理程序(1条消息)的方法。防止出现多个广告
我的主要活动
public class MainActivity extends ActionBarActivity {
private ViewGroup container;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null)
{
container = (ViewGroup)findViewById(R.id.container);
if(container != null)
{
Fragment1 fragment1 = new Fragment1();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(container.getId(), fragment1, Fragment1.class.getName());
fragmentTransaction.commit();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
int isAvaiable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(isAvaiable == ConnectionResult.SUCCESS)
{
Log.d("TEST", "GPS IS OK");
}
else if(isAvaiable == ConnectionResult.SERVICE_MISSING ||
isAvaiable == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ||
isAvaiable == ConnectionResult.SERVICE_DISABLED)
{
GooglePlayServicesUtil.getErrorDialog(isAvaiable, this, 10).show();
}
}
}
片段1
public class Fragment1 extends Fragment implements OnClickListener {
private Button bFragmentB;
private ViewGroup container;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_1, container, false);
this.container = container;
bFragmentB = (Button)view.findViewById(R.id.bFragmentB);
bFragmentB.setOnClickListener(this);
return view;
}
@Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
switch(arg0.getId())
{
case R.id.bFragmentB:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(container.getId(),new Fragment2(),Fragment2.class.getName());
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
}
片段2(包含插页式广告)
public class Fragment2 extends Fragment
{
private Handler handler = new Handler();
private InterstitialAd interstitialAd;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_2, container, false);
return view;
}
@Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
interstitialAd = new InterstitialAd(getActivity());
interstitialAd.setAdUnitId(getResources().getString(R.string.banner_ad_unit_id));
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitialAd.loadAd(adRequest);
interstitialAd.setAdListener(new AdListener()
{
@Override
public void onAdLoaded()
{
handler.postDelayed(showInterstitialAd, 10000);
}
});
}
private Runnable showInterstitialAd = new Runnable()
{
@Override
public void run()
{
interstitialAd.show();
}
};
}
以下是我尝试过的但没有效果的摘要
在片段B onDestroy上我有这段代码
@Override
public void onDestroy()
{
super.onDestroy();
handler.removeCallbacks(showInterstitialAd);
}
仍然导致超过1个任务实例(出现2个广告)。如果屏幕仍然旋转也不好,因为任务会因我的理解而被破坏。
对事物的另一种尝试
interstitialAd.setAdListener(new AdListener()
{
@Override
public void onAdLoaded()
{
if(!handler.hasMessages(1))
{
handler.sendEmptyMessage(1);
handler.postDelayed(showInterstitialAd, 10000);
}
//else do nothing
}
});
这个非常愚蠢,考虑到一开始就有一个新的hander对象,所以它不会有一个消息:D。我们的想法是让队列中的消息为1,如果它已经看到1已存在,那么就不要启动另一个处理程序。
答案 0 :(得分:0)
看起来你的旧片段2还没有完全被destryoed / GC'。
由于我们试图掌握我们在旧片段中创建的现有callback
,我们需要保存对它的引用,因此我们可以从处理程序消息队列中删除它。您可以通过将其保存在应用程序级全局中来完成此操作
public class Global extends Application {
public Runnable oldshowInterstitialAd = null;
}
使用
更新您的清单Application
<application android:name=".Global"
在发布新版本之前添加handler.removeCallbacks(oldshowInterstitialAd);
。
public void onAdLoaded()
{
handler.removeCallbacks(((Global)getApplicationContext()).oldshowInterstitialAd);
handler.postDelayed(showInterstitialAd, 10000);
((Global)getApplicationContext()).oldshowInterstitialAd = showInterstitialAd;
}
保存对旧片段成员的引用可能会妨碍其GC,但我们在更新oldshowInterstitialAd
时更新了参考文件。