为Runnable允许一个处理程序?

时间:2014-10-05 18:45:48

标签: android admob android-handler

我正在尝试在我的应用中实施非页内广告。我使用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已存在,那么就不要启动另一个处理程序。

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时更新了参考文件。