Background -
I have an app that currently has a lot of methods in MainActivity to pull and upload data to firebase. It's quite a mess with the other app logic in there..
Problem -
I would like a separate class filled with server (firebase) access methods that can be called from any activity or fragment and run asynchronously. The class also needs access to context and be able to initialise and store variables.
PS. I'm using kotlin if that helps at all
Edit:
Have done more researching to find terms like "utility" and "static" classes which seems like an accurate way to go... If I create a static utility class with Async methods, will that achieve what I'm after? Also, can you initialise and hold variables in a static class?
Thanks :)
Solved
After more research and testing, I created an object that holds my methods and variables and just need to pass context into the relevant methods. Then just simply call objectname.methodname()
Related
I have an application with 100+ static variables and methods in its Application class will it affect the performance of the app? if so how to handle it?
As I see, your only question is if using static methods and variables inside your application class is wrong or not. As far as I know, it will not affect your application performance or anything else, but putting them inside application class is a wrong design. It's like you put all your code inside one single method and it will not be good.
So, I suggest you to put your static methods inside a Helper class and since they don't need to be instantiated, they need to be static, not a singleton. Also for your variables, for example for your Strings, I suggest to create another class and put them into it so your application maintenance be possible.
I'm a beginner in Java programming and I'm currently working on an app with more complex class structure and a GUI. This might be a stupid questions, but it is very hard to google, so I'm asking here.
I have a main class, looking like this:
package app;
public class App {
private FirstClass fc;
private SecondClass sc;
public App () {
fc = new FirstClass ();
sc = new SecondClass ();
// ... code continues ...
}
}
Say the SecondClass is defined outside of this .java file (like GUI forms are). Is there a way for me to access the "fc" instance (or other member variables of the App instance) from the "sc" instance (without passing the "this" pointer)? Something like:
class SecondClass {
public void someMethod() {
getWhoeverCreatedThisInstance().fc.getSomeData();
// ... code continues ...
}
}
And if not, what am I doing wrong? Should I design this differently? Maybe setting the "fc" as static? But what if I want more of my app's classes to communicate with each other, should I make them all static? What would be the point of having something non-static then? I could pass the "this" pointer of "App" or "fc" instance in the constructor of "SecondClass", but that solution just seems non-elegant when the number of classes that need this behavior rises.
Any ideas? Thanks in advance!
My suggestion is to implement a callback system with interfaces. Each of your classes communicating with each other should implement these.
The classes should Register to the creating class.
Then they can call a method in the creating class which invokes the interface method of each registered class and passed the data this way.
This SO answer might help
https://stackoverflow.com/a/18279545
If you want to develop GUI applications, you should really get into the basic concepts. This can be very time-consuming, but it is necessary, otherwise you will encouter strange behaviour. I will just give you a basic understanding to answer your question.
You think of simple console applications, where you usually have a single thread and passing around objects is valid. With multiple threads, this is fatal, even with static variables. Each variable or object can be modified concurrently and the other thread may not be able to 'see' the changes in time. This is a complex matter, since there are also caches and separate stacks for each thread. In short, fc may not always be synchronized in App and sc, therefore reads and writes may be inconsistent.
What to do now? Learn the concepts of GUI programming. Often you do not even have to share objects for simple things. If a GUI control triggers an action, use a Listener, look here. If you want to access a database for example, then just make a new connection object for each request or button click, whatever. This is simple to start, add complexity later.
A simple variant to share objects is to use the synchronized keyword, which ensures that a method or a field is only accessed by one thread at a time. Here is an example. Also look at thread-safe data structures provided by Java (java.util.concurrent).
For advanced purposes you would have a separate thread and you would connect them with Sockets to pass messages or data.
Many times when I have been developing android apps, in order to access some important variables such as getApplicationContext() or other variables such as Buttons or Edittexts, which are normally not accessible outside MainActivity but required in some other class in the same project, I have been using this technique, that is
Within MainActivity (for getApplicationContext() case):
private static Context context = null;
and inside the onCreate method, I do :
context = getApplicationContext();
and I then access the context ( to display a toast message , for example) by using:
Toast.makeText(MainActivity.context,"Message",Toast.LENGTH_LONG).show();
in my other class. Similarly to get or set the text in an EditText variable and so on.
My questions are:
1)Is this the best method for my problem definition?
2)If no, is there a better way?
3)if no, what are the disadvantages of this technique?
3)Can the same technique be extended to functions in the Mainctivity?
EDIT: I do not require another Activity here, rather I am just splitting the task of the app into separate classes (or objects).
My questions are:
1)Is this the best method for my problem definition?
no this is not the best way of solving this.
2)If no, is there a better way?
yes to save static information you should be using something like a headless fragment so that the android framework can handle the garbage collection on unused classes and data
3)if no, what are the disadvantages of this technique?
disadvantages are many :) firstly memory leaking cause that static var cant be garbage collected at all so it stays in memory.
secondly you should not use edit texts from the main activity somewhere else cause there is no garantee that the mainactivity will still be there cause if you move away from it android might kill it to save memory.
all screens should be selfcontained and data must be transfered with intents and Bundles()
3)Can the same technique be extended to functions in the Mainctivity?
create seperate helper classes that sit within a static class like helpers. MainActivity is not a static class and shouldn't be a static class
I'm starting with Android and wonder if background Task like DB reading and saving are always encapsulated in private classes?
I mean, at the moment I have:
private class SaveToDB extends AsyncTask..
private class ReadFromDB extends AsyncTask..
public void onButtonClick(View v) {
new SaveToDB().execute();
}
And so on. This way, I always have to create a new object if I want to execute background tasks. Is that the correct way?
What I wonder is that all my private classes are "actions" itself, not really objects. As they are named eg save or read which naming normally applies to methods by convention, not to classes.
Moreover, in case I'm doing it right: is it good practice to neast the private classes inside MyApplication Activity? Or should I refacter them out into own separate classes?
You could write a service to handle all the background content management. So, when you want to save, you just message the service and tell it to write data. This is much more complicated. For simple things, you can do it exactly as you are currently.
EDIT:
Also, as Ian pointed out, take a look at the new database interfacing classes post 3.0.
If you are firing of async tasks to interact with a sqlite database, then its not the best way to do things these days, you should check out cursor loaders instead.
http://developer.android.com/guide/topics/fundamentals/loaders.html
http://developer.android.com/reference/android/content/CursorLoader.html
Once you got your head around them they are much easier than firing off async tasks, infact they build on top of async tasks to address some of the issues you describe and are tolerant to configuration changes.
I highly recommend to move away from AsyncTask (for db access) and use the Loader API instead.
Its backported in the compatibility package so you can use them in older versions prior to Honeycomb.
Not always.
For example, if you've got a task that is to be used by different activities (I'm not talking about sharing the same instance), you will want a public class so you don't write it several times.
If you only use that (class of) task in one place, private class might help keeping your code cleaner.
It is a correct way for using AsyncTask, which isntance you can execute once.
Class Name can be DbSaver isntead of SaveToDb for instance which is more readable.
If that class is used only one Activity you can nest them, why not. But if you have task which is executed within different Activities, it is a good idea to create his own file.
It is good design to loosely couple your database access from your UI code. One way to avoid having to create a new object every time would be to make the database access classes a singleton and just return the instance of the class whenever you need to make a transaction.
To your last question it is a better idea to move the database management to its own class so that it can be accessed across several activities. If you do it all in a private class then what happens when you have a new activity that need s database access?
I am developing an application in Blackberry. I have to write a code or a method that runs only once. The method does an action on creating the database. Something similar to Oncreate method in Android. Help of any sort is appreciated.
A Y.
Create a singleton class and call the method from singleton class private constructor, or maintain a global flag and check that flag on method call.
There are many other ways but calling of a method is on you, and you can do any way for this.
If you want to run that code in single time of application life then,
use persistent store and add one flag, change the flag value after successfully running that code .
Both BlackBerry and Android provide the Persistent storage.