简体   繁体   中英

Handling common code between different activities, fragments, tasks, etc

I have quite some (not too much, but quite some) experience with Java and object-oriented programming in other languages, but am fairly new to Android and my understanding of all its different classes is at best described as limited (more realistic would be confused ).

I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every day on some arbitrary moment, so there's no need to fetch this data every time you start the app or look at the widget.

My problem is that I'd like to have one method to fetch the data and store it in shared preferences, together with the update time (so that it's only updated once a day). This method has to be accessible from the widget and the activity.

Normally I would simply create some class with a static method to do this. However, to access the shared preferences you need a Context . I can come up with two ways:

Option 1: static method, Context as parameter

public class MyClass {
    public static String fetchData(Context context) {
        return // ...
    }
}

Option 2: singleton

public class MyClass {
    private static MyClass instance = null;
    private Context context;

    public MyClass(Context context) {
        this.context = context;
    }

    public String fetchData() {
        return ...;
    }

    public static MyClass getInstance(Context context) {
        if (instance == null)
            instance = new MyClass(context);
        return instance;
    }

    public static MyClass getInstance() {
        return instance;
    }
}

Now I would call it with MyClass.getInstance(getActivity()).fetchData() the first time, and after that MyClass.getInstance().fetchData() .

My question

Is either of these preferred over the other, and if so, why? Or is there another, better, way to do this kind of thing? Or does it depend on the situation (and in that case, on what precisely?)?

Later, I may have more of these methods. Since the Context is something that normally doesn't change, I thought a singleton may be useful here because after the first instantiation you don't need to give a context anymore.

Option 1 is ok to use almost all the time. Option 2 is dangerous because you are keeping a reference to a Context . if the Context is of type Activity you can have memory leaks - your Referenced Activity will not be GC

If you are using option 2 make sure you are using Application Context .

To init the singleton do something like:

getInstance(myActivity.getApplicationContext()) 

option 1 is much better if the method is a utility method - does something and does not need to change it's state after the method has returned.

first of all you are not keeping a reference to Context . also you don't need to hold a singleton in the memory. Last Static methods are efficient .

Use option 2 if you are using the Singleton all the time and recreating objects during the process ( Picasso , RetroFit are good examples for the need of Singleton)

A good example of when to use a Singleton is Android Volley library . It's also relevant to fetching data from remote so have a look

In essence, neither of your approaches are required for what you initially describe...

I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every midnight, so there's no need to fetch this data every time you start the app or look at the widget.

So what exactly is going to be responsible for the daily download and how is it going to be triggered? Neither an Activity nor an App Widget is suitable.

Add a few bits and pieces - use AlarmManager to create a repeating alarm set for around midnight (it won't be exact but normally within a few seconds). Have the alarm trigger a broadcast which is received by a BroadcastReceiver and then have the receiver start an IntentService to download and save what's needed.

It's a win-win scenario. The alarm will be fired regardless of whether your app is 'running' or not (or whether the phone is asleep or not). The receiver will be triggered and the IntentService uses its own worker thread so no need to worry about any problems with running network code on the main/UI thread. Also, an IntentService has a Context which can be used to access SharedPreferences and will shut itself down after it has done its work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM