问题
I want to build an utility class. It should read values from an database an providing typical UI or interaction features e.g. setting the title of the application, setting a background picture, playing background music.
Because of asking a other question How to use UI functions in non UI methods? i realized that i have a bunch of different ways to do that. I tested different ways for setting the titel every, every way worked. But which is the cleanest / correct / confident way, and why?
In the examples the calling class is a kotlin class, but this is indifferent.
Way one! Everything Activity related is done in the calling activity. Context is passed through constructor, could alternatively invoked with every function call. In my opinion we do have here not so much dependencies but the utility user has to do a lot himself.
calling class:
frameworkFeatures(applicationContext);
setTitle(frameworkFeatures.frameworkSetTitlesStaticContext());
called class:
private static Context frameworkContext;
public frameworkFeatures(Context context) {
frameworkContext = context;
}
public static String frameworkSetTitlesStaticContext(){
TestMainDatabase.getDatabase(frameworkContext);
TestMainDatabase db = RoomAsset.databaseBuilder(frameworkContext, TestMainDatabase.class, "TestMainDatabase.db").allowMainThreadQueries().build();
return db.featuresDao().findByName("title").getFeatureValue().toString();
}
Way two. Hiding as much as possible. Everything has to be passed to utility class. How to handle this when used by more Activity. Would it still be possible with a static Activity declaration in the utilitie class?
calling class:
frameworkFeatures(applicationContext,this)
frameworkFeatures.frameworkSetTitleEverythingisStatic()
called class:
private static Context frameworkContext;
private static Activity frameworkActivity;
private static TestMainDatabase frameworkTestMainDatabase;
public frameworkFeatures(Context context, Activity activity){
frameworkContext = context;
frameworkActivity = activity;
TestMainDatabase.getDatabase(context);
frameworkTestMainDatabase = RoomAsset.databaseBuilder(frameworkContext,TestMainDatabase.class, "TestMainDatabase.db").allowMainThreadQueries().build();
}
public static void frameworkSetTitleEverythingisStatic(){
frameworkActivity.setTitle(frameworkTestMainDatabase.featuresDao().findByName("title").getFeatureValue().toString());
}
回答1:
If you need to have valid context/activity you could instead provide initialize API that should be called in Application
onCreate()
. Something like :
Framework.initialize(appContext);
Inside of which you could register your own Application.ActivityLifecycleCallbacks
that would track currently visible/active activity:
public static void initialize(Application context) {
appContext.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
...
@Override
public void onActivityResumed(Activity activity) {
sGlobalContext = activity;
}
@Override
public void onActivityPaused(Activity activity) {
sGlobalContext = null;
}
....
...
}
And then your framework shouldn't worry about activity/context anymore. For User all will be transparent.
来源:https://stackoverflow.com/questions/45525953/best-way-to-build-an-ui-utility-class