0

So basically, I can't shake the fact that this seems like a bad idea, but I can't really determine why.

I have Activity A and Activity B in Package 1 and Activity A makes a Volley call and creates a list of models Model X that contains some simple data (Strings and primitives). For a very simple example, let Model X represents a news article (so the list of models is a list of news articles) which contains a news article's title and body. Activity A contains a list that displays the title of the articles. When you click on an item in the list, Activity B is called and the title of the article is shown at the top and the body of the article is shown below. Activity B can't be called from anywhere but Activity A and only after A has retrieved Model X Now let's say we have a large number of these models that all contain a large number of simple types and you aren't exactly sure what data from the model Activity B needs, you just know that it needs Model X that was retrieved in Activity A.

The "correct" step, it seems, would be to have the models implement Parcelable and pass the model in a bundle to the activity. The thing about that is that I have a lot of models with a lot of data and if I can save time it would be great. I was trying to implement some sort of generic parceler and that was getting to be a mess. So here is what I thought:

Could Activity A not save the model selected in onItemClick() as a protected static variable that Activity B can use without having to pass it in a parceled bundle since, once the model is made, it will be the only instance of the model and the model will not be altered in any way so the state of the model can't be disrupted by the static call?

Something like this

Activity A

public class A extends Activity implements OnItemClickListener{
    private List<X> mModels;
    protected static X mModel;
    private SimpleListAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState){
         super.onCreate(savedInstanceState);
         // code

         if(mModels == null)
             requestModels();
         else
             buildInitialList();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View child, int position, long id){
        mModel = mAdapter.getItem(position);   // <-- returns Model X in list of models
        startActivity(new Intent(this, B.class));
    }

    /*
       Some irrelevant code, including requestModels() network call (I have a
       NetworkManager class that does that, but again it isn't important how it 
       does that, just important how I get my data) as well as building my list.
    */

    // Listener attached to Volley call for response
    private Listener<ArrayList<Model>> getVolleyListener(){
        return new Listener<ArrayList<Model>>(){

            @Override
            public void onResponse(ArrayList<Model> models) {
                if(models != null){
                    mModels = models;
                    buildInitialList();
                }
                else
                    closeOnEmptyList(); 
            }

        };
    }
}

Activity B

public class B extends Activity{
    private X mModel;

    @Override
    public void onCreate(Bundle savedInstanceState){
         super.onCreate(savedInstanceState);
         //code

         this.mModel = A.mModel;
         doSomethingWithModel();
    }

    private void doSomethingWithModel(){
         String title = mModel.title;
         String body = mModel.body;
         // do something
    }
}

The Model class X will never be used outside of Activity A and Activity B, and every Activity that needs to use a Model of the same type is placed in the same Package. I have a number of classes that do similar things (news articles, popular questions and answers, law details, just other generic String data for the most part). I can parcel everything that isn't an issue, I just can't seem to put my finger on what is wrong with this even though it seems flawed. None of the data needs any security and none of the models are large enough to cause an issue with static heap memory.

EDIT

My case isn't exactly unique, but is somewhat uncommon. I am ok with my data having to be repulled at the restart of the application. This means (to the best of my knowledge) that if I store the Model statically of the protected type in Activity A, there is no way that the Model could be null in Activity B as either the static variable is still persistent in the application from the still paused Activity A or the application has restarted and the user will have to go through Activity A rebuilding our volley Model so that Activity B can use it as well. (Possible error in logic check needed here)

I do realize that volley has a cache, but I am fairly certain it requires the correct cache headers (that give a response code of something like 304) which I am not getting. Any input on this is also appreciated. And again, I realize that using statics isn't exactly ideal, but I am really trying to figure out why they shouldn't be used in this case, or if this is actually one of the uses for them.

zgc7009
  • 3,371
  • 5
  • 22
  • 34
  • Where do you load the data from in activity A? – Simas Aug 24 '14 at 18:35
  • @user3249477 I have a network call that gets made, it is returned in the listener. I will add the listener just to kind of show where it is coming from. – zgc7009 Aug 24 '14 at 18:36
  • Ah nevermind. I thought if the data is static, you could just save it in a database. Then each activity could get the items it needs from the DB. – Simas Aug 24 '14 at 18:38
  • @user3249477 yea I know, and thanks for your input. I am just wondering what, if anything, is wrong with this code. It just seems like there has to be a hole in it I just can't find it, and honestly hope there isn't one cause it would make my life loads easier haha. – zgc7009 Aug 24 '14 at 18:44
  • The model of your application _should_ actually be stored statically, but separated from the UI code, according to the [MVC pattern](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). This will ensure data persistence in spite of UI changes, such as the `Activity` being recreated due to configuration changes. Then you can simply pass an id reference to the specific model to the details `Activity`, and it can fetch it from the static data. I believe Volley already implement a static cache, so you may be able to just requery it and retrieve the desired model from the response. – corsair992 Aug 24 '14 at 21:43
  • @corsair992 Thanks for the reply. I was looking into the volley cache but it requires proper headers (I think I am looking for a 304?) and my get's don't seem to be giving me the proper cache headers. Any recommendations for where to look as I start to dig deeper, including any the MVC pattern as it pertains to Android? – zgc7009 Aug 24 '14 at 21:51

1 Answers1

1

Here is a good blog explaining the details, but if you did want to store some data in a static variable, your best bet would be to have that variable in the aplication class, but there are pitfalls even to that. For example it's possible for your activity to be paused and then resumed with a new instance of the app, and your data would be gone (so calling a method on some object might give you a NPE. I think it safer to either use a parsable, or save it to sharedperferences in one activity and load it in the next.

Here is the blog, I mentioned, and probably explains the reason you feel something might be wrong if you proceeded with storing data in a static variable to pass between activities.

http://www.developerphil.com/dont-store-data-in-the-application-object/

nPn
  • 16,254
  • 9
  • 35
  • 58
  • Based on my question this is a completely acceptable answer. I have come to the conclusion that my situation is so unique that, in this case, it might be possible to use the static variable though not ideal. Based on the fact that the data I pull is changed so often and so randomly, I am able to do a simple check in onResume() like `if(data == null) repullData();` but again, this isn't ideal. The real kicker is that I don't really want persistent data (just long enough for some quick app browsing or screen orientation change), which is uncommon at best. I think I will go with parcelables, sigh – zgc7009 Aug 24 '14 at 21:01
  • Thank you for the answer, it is a good link. I am going to edit my question, but this is still a good answer and a good read regardless. – zgc7009 Aug 24 '14 at 21:48