UPDATE- This post is obsolete, please check
this update post.
I've decided to try using multiple ad agencies, and one of them was
innerActive. I had 2 problems with innerActive: (1) They don't supply an AdWhirl adapter, (2) There's seem to be a bug in their SDK as of version 2.0625
Problem A: The bug
The function
onWindowFocusChanged which runs on the UI thread calls the function
setRefreshInterval which has the keyword synchronized which means it waits for a lock. The lock is taken by the ad request thread. If the
onWindowsFocusChanged will be called during an ad request there will be an ANR exception due to a delay on the UI thread.
Solution:
I wrote a wrapper that seems to fix this issue.
import java.util.concurrent.locks.ReentrantLock;
import android.content.Context;
import android.util.AttributeSet;
import com.innerActive.ads.InnerActiveAdView;
public class InnerActiveAdViewFixed extends InnerActiveAdView {
private ReentrantLock mLock = new ReentrantLock();
public InnerActiveAdViewFixed(Context context) {
super(context);
}
public InnerActiveAdViewFixed(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InnerActiveAdViewFixed(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// Patch
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (mLock.tryLock() == true) {
try {
super.onWindowFocusChanged(hasWindowFocus);
} finally {
mLock.unlock();
}
}
}
@Override
public byte start() {
mLock.lock();
try {
return super.start();
} finally {
mLock.unlock();
}
}
}
Problem B: No AdWhirl adapter
Solution:
I wrote a custom AdWhirl adapter for innerActive.
import android.util.Log;
import android.view.View;
import com.adwhirl.AdWhirlLayout;
import com.adwhirl.AdWhirlLayout.AdWhirlInterface;
import com.innerActive.ads.InnerActiveAdView;
public class InnerActiveCustomEvents implements AdWhirlInterface{
private AdWhirlLayout mAdWhirlLayout;
public InnerActiveCustomEvents(AdWhirlLayout adWhirlLayout) {
super();
this.mAdWhirlLayout = adWhirlLayout;
}
@Override
public void adWhirlGeneric() {
}
public void inneractiveBanner() {
final InnerActiveAdViewFixed banner = new InnerActiveAdViewFixed(mAdWhirlLayout.getContext());
banner.setVisibility(View.VISIBLE);
banner.setRefreshInterval(0);
banner.setScrollContainer(true);
banner.setBgColor(0xFF000000);
banner.setTxtColor(0xFFFFFFFF);
banner.setListener(new InnerActiveAdView.AdEventsListener() {
@Override
public void onReceiveAd(InnerActiveAdView arg0) {
banner.setVisibility(View.VISIBLE);
Log.v("InnerActive Banner Listener", "Received Ad.");
mAdWhirlLayout.handler.post(new AdWhirlLayout.ViewAdRunnable(mAdWhirlLayout, banner));
mAdWhirlLayout.adWhirlManager.resetRollover();
mAdWhirlLayout.rotateThreadedDelayed();
}
@Override
public void onFailedToReceiveAd(InnerActiveAdView arg0) {
Log.v("InnerActive Banner Listener", "Failed To Receive Ad.");
mAdWhirlLayout.rollover();
}
});
}
}
I'm not going to write a step-by-step guide, but here is the key notes:
- Integrate innerActive ads & make sure everything works.
- Remove the ad view from the layout & the appropriate code the the ad view.
- Integrate AdWhirl:
3.1. Create an application in AdWhirl web site & get SDK Key
3.2. Add AdWhirl JAR
3.3. Add the AdWhirl SDK Key to the AndroidManifest.xml
3.4. Add the com.adwhirl.AdWhirlLayout to the application layout
- Add the following code (in the onCreate functions)
AdWhirlLayout adWhirlLayout = (AdWhirlLayout)findViewById(R.id.adwhirl_layout);
adWhirlLayout.setAdWhirlInterface(new InnerActiveCustomEvents(adWhirlLayout));
- Add innerActive to AdWhirl as custom event - name: innerActive, function name: inneractiveBanner
Notes -
- If you're using multiple custom events, they should all be in the same function, so copy only the inneractiveBanner function.
- If you're using ProGaurd make sure you read my previous post & also add the custom events adapter & innerActive ad views to the ProGuard exceptions list.