14

I want to reuse the same view object (not the view class, or the xml file, I mean the object in the memory) in different Activities.

I almost had this done. The thing is, of course, the context.

I tried with the application context. It almost worked, but then when I click on the view I am transmitting between different activities, and try to start another application from it (or link) it crashed. (I don't remember the exact crash, but I'll dig it, if you need it).

I tried with some activity, that I didn't mind leaking once, and giving it as a Context. It worked, actually everything worked, until I began to get weird exceptions in ViewFlipper.

My question is, is this reusing really possible, and how to do it stable? Have you got any experience with that?

Thanks A LOT in advance, Dan

Danail
  • 10,443
  • 12
  • 54
  • 76
  • why you need this? view is valid in given context, valid context for view is activity, if you create new activity you should create new view – Selvin Jan 09 '12 at 15:27
  • 1
    Is it possible? Might be. Is it stable? Quite likely not so easy to achieve. Is there a good reason for having such a goal in the first place? – harism Jan 09 '12 at 15:30
  • I think I have a good reason. I'm talking about ad views, that are third party, and I do not want to load them with each new activity. – Danail Jan 09 '12 at 16:52
  • It is against the terms of service to forcibly avoid reloading adviews in this way. You could end up getting no money out of them if you do this. Having done some research into ads it is better to get clicks over views so my preferred way of displaying ads is a periodic pop up (1 a week) that shows an ad and requests that you click or click the skip button below. This gives much better click through rates and so much more money. – Michael Allen Jan 13 '12 at 10:03
  • 2
    This is not my situation at all. And I'm not talking about interstitial ads. I'm talking about ad banners. I'm reloading ads every 60 seconds. At least this is my intention. Reality is, that I'm reloading the ads much more often, because of changing activities, and having to reload the ad views again. This lowers the click through rate below the real values. – Danail Jan 13 '12 at 11:27

5 Answers5

6

I'm keeping in mind that you can afford to leak 1 activity, as this is the only solution I know: Declare a static view, say myAdView in your 1st activity (in which you are requesting ad). Now you can ad and remove this myAdView in every activity transation. Ofcource you will have to maintain seperate LinearLayouts for ur ads in seperate activities, where we will add/remove the myAdView eg. Suppose you are going from activity A to B, then in A's onPause remove myAdView:

private LinearLayout layoutAd;
layoutAd = (LinearLayout) findViewById(R.id.layout_ad); // from A's xml
protected void onPause() {
    super.onPause();
    layoutAd.removeView(FirstActivity.adBannerView);
}

and in B's onResume add the same (FirstActivity's) myAdView:

private LinearLayout layoutAd;
layoutAd = (LinearLayout) findViewById(R.id.layout_ad);  // from B's xml
protected void onResume() {
      super.onResume();
      layoutAd.addView(FirstActivity.adBannerView);
}

Hope this solves your problem to some extent.

Saurabh Verma
  • 6,328
  • 12
  • 52
  • 84
  • Yes, this is what I've been doing, hence the ViewFlipper exception problems. ( I think this is the cause, since it started to happen after I implemented similar solution ) – Danail Jan 13 '12 at 12:12
  • You dont need to implement ViewFlipper for this !! And I've been doing this in my games without getting any crash. – Saurabh Verma Jan 13 '12 at 13:31
  • I haven't implement ViewFlipper. It is an exception I started to receive after implementing similar solution. A question - how many activities are there in your games opened/closed in a session? Is it under 10 or more - 30-40 in a session? Thank you. – Danail Jan 13 '12 at 13:46
  • by the way, there are some differences between mine and yours implementation. This may be the key to this exception. I'll try your exact proposal and will tell you the results. – Danail Jan 13 '12 at 13:48
  • Okay. Well, depending on the users' play there may be more than 10 activities getting open/closed in a session. This is the market link of that game: https://market.android.com/details?id=com.apostek.apps.pocketbingo&feature=search_result – Saurabh Verma Jan 13 '12 at 14:11
1

Why don't you use Fragments?

http://developer.android.com/guide/topics/fundamentals/fragments.html

I think your use case is perfect for this.

neteinstein
  • 17,529
  • 11
  • 93
  • 123
  • from the documentation: A stopped fragment is still alive (all state and member information is retained by the system). However, it is no longer visible to the user and will be killed if the activity is killed. – Danail Jan 18 '12 at 10:38
0

I'm in the same case as Danail. The thing is not about to hack de Ad provider, but that if you want to show a banner through different activities it's a best practice in advertising not to reload it every time you change the activity, because you do more impressions so you CTR (Click Through Ratio) will decrease. You'd rather reload the banner at the time rate you fix, independently of activity changes.

I think the right way to do that would be, as NeTeInStEiN says, using fragments. You could have a unique activity composed by different fragments. In one of the fragments, for example at the bottom, you'd have the banner and you'd load it actually once. Then on the bigger area on the top (let's say we are on a handset) you'd place different fragments, one at a time, that would correspond to your existing activities. When you'd normally "change" the activity, now you'd just change the "main" fragment, but the banner fragment will stay there unchanged.

The main and BIG problem about this approach is that you need to design you app this way from the beginning, because changing the app model from several activities to one activity with several fragments is quite a big code change... :.(

So I understand that, for implementation costs, one could try to "carry" the view from one activity to another. But as I saw in other responses, it's really not recommended and a troublesome way...

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Pek Ifly
  • 89
  • 3
0

This isn't really possible in the form you are asking. The views in an activity must be inflated at load time, copying/referencing them in-memory is unlikely to work how you want it to.

Instead, you should look to building the view in each activity you need it, and transferring just the data you need to populate it instead.

If you are trying to improve the performance of your app, I would recommend looking for ways to simplify your view, rather than violating the activity lifecycle.

Update:

Since you've revealed the purpose behind this question (intercepting served ads from a third-party library), I suggest you first contact the company and check the terms of use. If they permit the use of their service while bypassing the View code, then they might be able to provide you with a lower-level API for displaying the ads as you see fit.

If such use is not permitted, consider the fact that they might block your account (and withhold payment) for mis-use.

If you still want to go ahead: DON'T hack away at the Android UI patterns to make this work. Extract the ad images from the third-party library server-side (i.e. building a simple hosted Java webapp with cache store and a REST API) and serve the ads to your Android app from this "man-in-the middle" service. I certainly do not endorse this method, however.

I accept you are seeking some penultimate technical solution for your approach, but I genuinely think it is the approach itself that is the problem here. If I was in your position, I would start to look for other Ad serving solutions that better fit my requirements, as well as contacting the third-party to see if I can pay for more customised integration. Anything involving transferring inflated Views between activities is doomed to constant maintenance problems, if it works at all.

seanhodges
  • 17,426
  • 15
  • 71
  • 93
  • Yes, refactoring is best and using the data would be superb, if possible. Unfortunately, the views that I want to move to another activity, are third party, and not really possible to extract data from them. – Danail Jan 09 '12 at 16:51
  • Since it is not in my power to decide what ad networks I have to integrate, I have to find a solution of the current situation. And, believe me, if I can make such server for 10+ ad networks, I will dive in the ad business at once. Also, I very much doubt this is misuse, since it is well integrated in the iPhone app. Our intention is to request ads every 60 seconds, but in the Android it happens much more often, because of the problem. I can see your answer is "this is not possible", thank you for that. – Danail Jan 13 '12 at 12:00
  • No problem Danail. I understand this is not the answer you seek, I hope you find one that works for you. – seanhodges Jan 13 '12 at 12:04
  • If the ads are not interactive (or the interaction is easy to mimic), perhaps you could consider taking a screenshot, cropping the image to just the ad view, and displaying the resulting image between the 60 second intervals? That would adhere to the Android platform and solve your traffic problem... – seanhodges Jan 13 '12 at 12:16
-1

If you want a variable to be used within multiple activities then best practice for it is to put them in a separate class (can be named as Constants or MyVars) as static variable and use them in any activity you want as like Constants.SavedVar or MyVars.SavedVar as below is code example.

public class MyStaticVars {

public static Context myContext;
}

// First Activity where you want to save a specific context

MyStaticVars.myContext = ContextToBeSaved;

// Any Other Activity where you want to reuse that context

priviousContext = MyStaticVars.myContext;
Umar Qureshi
  • 5,985
  • 2
  • 30
  • 40
  • you have no idea what you talking about ... Context will be activity ... if activity is destroyed is no longer valid. – Selvin Jan 09 '12 at 15:24
  • `Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)` from http://developer.android.com/resources/articles/avoiding-memory-leaks.html so no, **this is absolutely not a best practice** – Selvin Jan 09 '12 at 15:39
  • actually, I can afford to leak one activity, just for using it as a context for all my static views (view variables, that I want to put in different activities). The problems, I'm fighting right now, are much worse. – Danail Jan 09 '12 at 16:59