Disclaimer: this is my first ever Android test project with Robotium.
I'm facing a catch-22 situation with ActiveAndroid and Robotium. Here's my setup:
I want to test an activity that expects a long array extra. This array contains DB ids of ActiveAndroid objects.
To get the ActiveAndroid objects ids', I need to initialize ActiveAndroid first, calling ActiveAndroid.initialize(this.getActivity()) from my ActivityInstrumentationTestCase2 class.
The call to getActivity() fails since I didn't pass the long array extra. I can't create the long array extra because I haven't initialized ActiveAndroid, hence the catch-22.
Is there another way I can get a context in a test class? An application-wide context perhaps?
I found the solution:
ActiveAndroid.initialize(this.getInstrumentation().getTargetContext());
That way you can get the target's context before initializing the activity.
Related
Currently, I have a database manager class that handles all operations to the database like this:
class DatabaseManager(val context: Context) {
private val db = Firebase.firestore
//Other functions, etc.
}
It makes use of the context passed in by different activities to perform functions to the database. The thing is, every single activity that requires database functions have to instantiate this manager class first, then call the functions. I would like to make use of the Singelton design pattern to make it such that all the activities will only use a single instance of the class. I believe kotlin's objects can do this, however I also need to be able to pass in the context of the activities into this manager class. Any assistance is appreciated, thank you!
I would recommend not doing that. The problem with Singletons is that they make code hard to test, you can't fake out the database. And for a database this is a particularly bad problem, as setting up all the right fake data can be painful. Instead, take a look at injection. It can do the same thing (make a single instance shared between everyone who needs it), but it manages that global state rather than having the classes themselves manage it via a static reference, passing it in (generally via the constructor) to whoever needs it. This makes it easy to provide an alternative or mock database when needed for testing. Injection used to be a bit painful to set up, but Hilt makes it a lot easier these days.
I am building an application in Android with multiple activities. I have a list of an object of type TodoItem that I get from a collection in Firestore database, and I need to access the list from more than one activity to make changes and updates to the list.
To do that, I thought about saving the list in the Application scope (is it a good idea?). For this reason, I created a class MyApplication extends Application (and added it to the Manifest file).
Instead of just adding the list as a class field of MyApplication I thought that maybe I should create a class named DataManager that will hold application-wide information such as my list of TodoItems (and here I ask again: is it a good idea? or maybe there is a better solution?).
At this point I am trying to decide what is a better approach to create and save the DataManager class:
One idea is to make DataManager a Singleton class and save it as a class field of MyApplication. This way, the activities will be able to get the instance of the class using DataManager.getInstance() without the need to get it from the application class with a getter method. In this approach, I will have to create the instance of DataManager and init the field of the application with it in the OnCreate() method of the application.
The second idea is to make it a non-singleton, add DataManager field to MyApplication, and create a getter named getDataManager() in the application class. The getter will check if the field is null (i.e. already initialized or not) and will create a new instance correspondingly. This way, the activities will get the instance using ((MyApplication) getApplication()).getDataManager().
I would like to hear what do you think about my approaches to solve the problem, and if you have any other suggestions or other ways to improve my suggested design.
A nice way when your data source is simple. You can create a singleton class to hold and manage data, including read and write from the singleton.
When you want to use complex data, you can store it to your device disk rather than memory. Android application support you to store your data with file, database, or key-value preference. As for your case, you can use database to store your todolist. Android support sqlite for these work, and we have official orm library called room.
raw sqlite: https://developer.android.com/training/data-storage/sqlite
room library: https://developer.android.com/topic/libraries/architecture/room
I just wonder what method can be use to send String from one to another activity besides by using intent.putExtra(), and getIntent.getExtra().
Cause my project getting unexpected result when using putExtra(), just want to another for send String.
Any suggestion and examples? Thanks.
you can also send by following ways
How do I pass data between Activities/Services within a single application?
Non-Persistent Objects
For sharing complex non-persistent user-defined objects for short duration, the following approaches are recommended:
Singleton class - Ref Here:
A public static field/method
A HashMap of WeakReferences to Objects
In my application rather than following the regular hierarchy of the ActiveAndorid,
I'm explicitly calling with the .initialize() method by passing the getApplicationContext.
However, the TableInfo returned doesnt have any Tables from the model class that I'm creating.
I tried debug their code and it seems an issue with the classloader they are using.
My code is:
ActiveAndroid.initialize(getApplicationContext());
TestModel model=new TestModel();
model.value="hello";
model.save();
You should not use getApplicationContext. It might not return the context of your application. The naming of getApplicationContext is misleading.
More info here: getApplication() vs. getApplicationContext()
I need to use getString() from most of the modules in my application.
But for some strange reason, it is tied to Application or Context, so that means I need to pass to each and every class in my application, the Application reference as a parameter.
This clearly violates one of the most basic principles of object oriented design.
Is there a way around this?
The 'strange reason' is that since the string resources are tied to your application, there is no way to access them without some sort of handle to it (the Context). If most of your classes that are not activities need to access string resources, you might want to rethink your design a bit. A simple way to not depend on a Context is to load the strings and pass them to your classes in the constructor.
Yes, there is a workaround - if you happen to (or can) pass a View (any View-derived class) to the constructor, and you assign it to a data member, then you can access the string resources from anywhere in your class:
String str_via_res = yourView.getContext().getString(R.string.str_via_res);
Otherwise, you will have to pass a Context to every class that needs access to these string resources.
you can extend android.app.Application class to create a static method to pass on the context across all classes in your application.
Refer : PhoneApp.java