Is it okay to use/invoke new Handler() in a loop? - java

I am using new Handler().postDelayed to set a delay when reloading an ad when the previous request of the ad has failed in the requestNewInterstitial method. I am wondering if invoking/creating many new Handlers would be okay as in my loop the new Handler line of code could be run up to 5 times. My question is, if later I have to clear the handler in the Activity onDestroy method so that there are no memory leaks, should I clear it only once or should I clean all the new Handlers I have created (the number of times that the loop is run). Also, how could I implement to clear the Handler OnDestroy method?
This is my code:
#Override
protected void onResume() {
super.onResume();
requestNewInterstitial(5);
}
private void requestNewInterstitial(int maxRetry) {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Activityone.this, getString(R.string.interid),
adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
if (maxRetry>0){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mInterstitialAd = null;
requestNewInterstitial(maxRetry-1);
}
}, 1000);
}
});
}
}
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mInterstitialAd != null) {
mInterstitialAd.show(Activityone.this);
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
}
});
Thanks for the help.

If the delay in postDelay extends beyound the activity lifetime, the runnable will execute after the activity has been destryed and will lead app crash. You should use a common handler. To clear the handler, you can call handler.removeCallbacksAndMessages(null); in on destroy or wherever else you want to clear them.
Handler handler;
#Override
public void onCreate(#Nullable Bundle savedInstanceState, #Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
handler = new Handler();
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mInterstitialAd != null) {
mInterstitialAd.show(Activityone.this);
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
}
});
}
}
});
}
#Override
protected void onResume() {
super.onResume();
requestNewInterstitial(5);
}
#Override
protected void onDestroy() {
handler.removeCallbacksAndMessages(null)
super.onDestroy();
}
private void requestNewInterstitial(int maxRetry) {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Activityone.this, getString(R.string.interid), adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
if (maxRetry > 0) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
mInterstitialAd = null;
requestNewInterstitial(maxRetry - 1);
}
}, 1000);
}
}
});
}

Related

Interstitial advertising (admob) only works once

These days I am doing a test, the objective is to click on a button to go to activity2 and show the interstitial advertising. For now this is the result thanks to information from: link
The problem:
Upon returning to the main page (MainActivity), I pressed the button to re-enter activity2 and it is no longer displayed. Only if I close the application and open the application and press the activity button 2 the advertising is displayed.
MainActivity code
public class MainActivity extends Activity {
private InterstitialAd mInterstitialAd;
private static final String TAG = "InfoApp";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//***** Initialize the Mobile Ads SDK.*********** -//
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
}
});
//**********************************************************//
adrequest_interstitial = new AdRequest.Builder().build();
InterstitialAd.load(this,ConfigPubli.Ads_interstitial, adrequest_interstitial,
new InterstitialAdLoadCallback()
{
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd)
{
mInterstitialAd = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError)
{
// Handle the error
Log.i(TAG, loadAdError.getMessage());
mInterstitialAd = null;
}
});
}
public void adstot(Intent i){
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
mInterstitialAd = null;
startActivity(i);
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
mInterstitialAd = null;
startActivity(i);
}
});
}
public void page2(View view){ //button
Intent i = new Intent (this, Activity2.class);
i.putExtra("valor","page2");
int randomAd = (int)(Math.random()*10);
if (mInterstitialAd != null && randomAd<=1) {
adstot(i);
mInterstitialAd.show(this);
}
else{
startActivity(i);
}
}
}
Thanks for the answers
Whenever InterstitialAd has been shown, the variable mInterstitialAd was set to null. So, how mInterstitialAd can be shown twice?
You should make a new request to get an interstitial just after mInterstitialAd = null;
Try like below:
public class MainActivity extends Activity {
private InterstitialAd mInterstitialAd;
private static final String TAG = "InfoApp";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//***** Initialize the Mobile Ads SDK.*********** -//
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
// Initialization complete
// You are now free to make an ad request
loadAnInterstitial();
}
});
//**********************************************************//
}
private void loadAnInterstitial(){
adrequest_interstitial = new AdRequest.Builder().build();
InterstitialAd.load(this,ConfigPubli.Ads_interstitial, adrequest_interstitial,
new InterstitialAdLoadCallback()
{
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd)
{
mInterstitialAd = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError)
{
// Handle the error
Log.i(TAG, loadAdError.getMessage());
mInterstitialAd = null;
}
});
}
public void adstot(Intent i){
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
mInterstitialAd = null;
startActivity(i);
// make a new ad request here
loadAnInterstitial();
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
mInterstitialAd = null;
startActivity(i);
// make a new ad request here
loadAnInterstitial();
}
});
}
public void page2(View view){ //button
Intent i = new Intent (this, Activity2.class);
i.putExtra("valor","page2");
int randomAd = (int)(Math.random()*10);
if (mInterstitialAd != null && randomAd<=1) {
adstot(i);
mInterstitialAd.show(this);
}
else{
startActivity(i);
// make a new ad request here
loadAnInterstitial();
}
}
}
That's all. Hope it will help.
Updated code (another version):
I have added an (if), after 6 clicks of the button it will load a new ad.
public void page2(View view){ //button
Intent i = new Intent (this, Activity2.class);
i.putExtra("valor","page2");
int randomAd = (int)(Math.random()*10);
if (mInterstitialAd != null && randomAd<=1) {
adstot(i);
mInterstitialAd.show(this);
}
else{
startActivity(i);
if(countclick==6)
{
loadAnInterstitial();
}else{
countclick=countclick+1;
}
}
}
It works!, I hope that google admob does not consider that it is poorly implemented.

Why onAdDismissedFullScreenContent is being called lately?

I have created a function to show interstitial ad before showing another activity.
It's working but onAdDismissedFullScreenContent is being called 2-3 sec lately after closing the ad. It causes previous screen to stand-by.
There's a chance to re-click the button to show the wanted Activity.
I really don't understand how to resolve this issue.
Here is my code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AdManager.showInterstitial(MainActivity.this, () -> {
Intent i = new Intent(MainActivity.this, MainActivity2.class);
startActivity(i);
});
}
});
AdManager.loadInterstitial(this);
}
}
And this is Application Class:
public class App extends Application {
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
AdManager.Init(this);
}
public static Context getContext() {
return mContext;
}
}
AdManager Class:
public class AdManager {
private static InterstitialAd mInterstitialAd;
private static boolean loading, showing;
public static void Init(Context context) {
MobileAds.initialize(context, initializationStatus -> {
loadInterstitial(context);
});
}
public static void loadInterstitial(Context context) {
if (context == null)
context = App.getContext();
Context finalContext = context;
if (mInterstitialAd != null) {
Toast.makeText(context,"already loaded",Toast.LENGTH_LONG).show();
return;
}
if (loading) {
Toast.makeText(context,"already another request is processing",Toast.LENGTH_LONG).show();
return;
}
Toast.makeText(context,"requesting interstitial",Toast.LENGTH_LONG).show();
loading = true;
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(context, "Interstial Ad Unit ID", adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
Toast.makeText(finalContext,"ad loaded",Toast.LENGTH_LONG).show();
loading = false;
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
mInterstitialAd = null;
loading = false;
Toast.makeText(finalContext,"ad failed to load",Toast.LENGTH_LONG).show();
}
});
}
public static void showInterstitial(Activity activity, #NonNull AdListener listener) {
if (showing) {
Toast.makeText(activity,"already showing",Toast.LENGTH_LONG).show();
listener.onCompleted();
return;
}
if (mInterstitialAd != null) {
showNow(activity, listener);
} else {
Toast.makeText(activity,"mInterstitialAd is null",Toast.LENGTH_LONG).show();
listener.onCompleted();
loadInterstitial(activity.getApplicationContext());
}
}
private static void showNow(Activity activity, AdListener listener) {
if (mInterstitialAd != null && !showing) {
showing = true;
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
Toast.makeText(activity,"Ad dismissed",Toast.LENGTH_LONG).show();
mInterstitialAd = null;
listener.onCompleted();
showing = false;
// times to load an new interstitial ad content
loadInterstitial(activity.getApplicationContext());
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
Toast.makeText(activity,"AdFailedToShowFullScreenContent",Toast.LENGTH_LONG).show();
mInterstitialAd = null;
listener.onCompleted();
showing = false;
// times to load an new interstitial ad content
loadInterstitial(activity.getApplicationContext());
}
});
// Now show the ad
Toast.makeText(activity,"call to show ad",Toast.LENGTH_LONG).show();
mInterstitialAd.show(activity);
} else {
Toast.makeText(activity,"either mInterstitialAd is null or ad already is showing",Toast.LENGTH_LONG).show();
listener.onCompleted();
}
}
public interface AdListener {
void onCompleted();
}
}
Please help.
The delay problem
You can't really help it. The problem is from the admob. This will happen. But, to know more about it, we can post an issue abt that on the Google Issue Tracker.
The button problem
I dont think this is any hard task. Just follow the steps:
Create a ProgressBar in your xml layout on top of the button and set its visibility to gone
When the button is click and the ad is shown, you can set the button to invisible and the progress bar can be set to invisible.
Then after a delay, the other activity opens without any harm to the activity from NullPointerException

The method must not be replaced by the superclass

I am trying to add Facebook Ads(sdk 6.3.0) in my Android App
The documentation on which I base myself
https://developers.facebook.com/docs/audience-network/reference/android/com/facebook/ads/interstitialad.html/?version=v6.3.0
https://developers.facebook.com/docs/audience-network/setting-up/ad-setup/android/interstitial/
I want when the person clicks on a button it shows an ad and then a new activity when the ad end
I also use a return which directly shows the activity if no ads are available
Here are the errors I am getting
The onInterstitialDisplayed method must not be replaced by the superclass
The onInterstitialDismissed method must not be replaced by the superclass
The onError method must not be replaced by the superclass
The onAdLoaded method must not be replaced by the superclass
The onAdClicked method must not be replaced by the superclass
The onAdLoaded method must not be replaced by the superclass
What I have done
private InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AudienceNetworkAds.initialize(this);
loadAd();
clickListener();
}
private void clickListener() {
dailyCheck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showInterstitialAd(1);
}
});
rewardCheck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showInterstitialAd(2);
}
});
}
private void loadAd(){
mInterstitialAd = new InterstitialAd(this, "750944672287722_755093405206182");
}
private void showInterstitialAd(final int i) {
if (mInterstitialAd.isAdLoaded()) {
mInterstitialAd.show();
mInterstitialAd.loadAd(new InterstitialAd.InterstitialLoadAdConfig() {
#Override
public void onInterstitialDisplayed(Ad ad) {
}
#Override
public void onInterstitialDismissed(Ad ad) {
if (i == 1)
{
dailyCheck();
}
if (i == 2)
{
startActivity(new Intent(MainActivity.this, RewardActivity.class));
}
}
#Override
public void onError(Ad ad, AdError adError) {
}
#Override
public void onAdLoaded(Ad ad) {
}
#Override
public void onAdClicked(Ad ad) {
}
#Override
public void onLoggingImpression(Ad ad) {
}
});
return;
}
if (i == 1)
{
dailyCheck();
}
if (i == 2)
{
startActivity(new Intent(MainActivity.this, RewardActivity.class));
}
}
Any help is good to take!
Thank you

Connecting from android wear to phone

i am trying to get connection between android wear and an android device. i can get the phone log responding but i cannot get the watch log to communicate back. the phone connects but i need to watch to connect and communicate back.
Here are my classes
Moblie
public class MainActivity extends AppCompatActivity {
// for broad communication
GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).addConnectionCallbacks(mConnectionCallbacks).build();
mGoogleApiClient.connect();
}
GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new
GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Wearable.MessageApi.addListener(mGoogleApiClient, mMessageListener);
Log.d("TAG::::", "IN onConnected");
}
#Override
public void onConnectionSuspended(int i) {
}
};
MessageApi.MessageListener mMessageListener = new MessageApi.MessageListener() {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
ByteBuffer byteBuffer = ByteBuffer.wrap(messageEvent.getData());
final int value = byteBuffer.getInt();
Log.d("TAG::::", "received good") ;
}
};
}
Wear
public class MainActivity extends Activity implements SensorEventListener {
private TextView mTextView;
GoogleApiClient mGoogleApiClient; // for broad communication
Node mNode;
float [] values;
Sensor acceler;
SensorManager sm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(mConnectionCallbacks)
.build();
mGoogleApiClient.connect();
}
GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient
.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
new Thread(new Runnable() {
#Override
public void run() {
NodeApi.GetConnectedNodesResult result = Wearable.NodeApi
.getConnectedNodes(mGoogleApiClient).await();
List<Node> nodes = result.getNodes();
if (nodes.size() > 0) {
mNode = nodes.get(0);
}
}
}).start();
}
#Override
public void onConnectionSuspended(int i) {
}
};
#Override
public void onSensorChanged(SensorEvent event) {
values[0] = event.values[0];
sendToPhone(8);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void sendToPhone(final int value) {
new Thread(new Runnable() {
#Override
public void run() {
byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
Log.d("TAG:::", "JIMMMMMMMMy");
Wearable.MessageApi.sendMessage(mGoogleApiClient, mNode.getId(),
"/newgolf", bytes).await();
}
}).start();
}
}

My onEvent() part of the File Observer method doesn't work

I have already scanned all of the related questons&answers here, but I still couldn't find the solution.
the service class file:
public class otser extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override public IBinder onBind(Intent intent) {
return null;
}
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
FileObserver observer = new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() + "/Pictures/Screenshots") {
#Override
public void onEvent(int event, String file) {
event &= FileObserver.ALL_EVENTS;
if(event == FileObserver.CREATE){
Toast.makeText(getApplicationContext(), "screenshot taken",
Toast.LENGTH_LONG).show();
}
}
};
observer.startWatching(); // start the observer
Toast.makeText(getApplicationContext(), "service: OK",
Toast.LENGTH_SHORT).show();
}}
According to other posts, I double checked the path, via creating a file programatically, it does exist, and correct.
The Activity class:
public class Home extends Activity {
Button showChatHead;
Button stopService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
showChatHead = (Button) findViewById(R.id.gomb);
stopService= (Button) findViewById(R.id.gomb2);
showChatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), ChatHeadService.class);
startService(i);
}
});
stopService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), ChatHeadService.class);
stopService(i);
}
});
}}
The service class linked well, the last Toast message pops up, as a conclusion only the observer is being skipped.
Any ideas?
Thanks in advance!
newer release:
FileObserver fileObserver = new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() + "/Pictures/Screenshots") {
#Override
public void onEvent(int event, String path) {
Toast.makeText(getApplicationContext(), "method entered", Toast.LENGTH_SHORT).show();
if (event == FileObserver.CREATE) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "File created", Toast.LENGTH_SHORT).show();
}
});
}
}
};
fileObserver.startWatching();
The onEvent method is not entered, the "method entered" Toast didn't appear.
in documentation of the onEvent-Method is mentioned, that it will run at another thread and you should consider this. using a handler, the Toast message should appear, like this:
private Handler handler = new Handler();
#Override
public void onCreate() {
fileObserver = new FileObserver("path") {
#Override
public void onEvent(int event, String path) {
if (event == FileObserver.CREATE) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(FileWatcher.this, "File created", Toast.LENGTH_SHORT).show();
}
});
}
}
};
fileObserver.startWatching();

Categories