My app makes use of various heavy libraries and data files, that need to be loaded / synchronized with local storage on start-up. As this operation takes some time, I was thinking of creating a dedicated activity for this purpose. This activity would be the entry point of the application and would do the following:
Display a background image and progress bar
Process necessary data (and updating the progress bar accordingly)
On completion, launch a new activity
Here is a couple of questions:
My initialization activity needs to pass a reference to the data to its child activity. Ordinarily I would do this with setSerializable, but here I am using 3rd-party non-serializable classes.
So I was thinking of simply making the data static. Is this a good solution? Any chance the static reference might break when switching activities or during the application life-cycle?
public class LibraryInitializer {
private static Some3rdPartyClass myLib;
public static void initialize(){ // Called by initialization activity
myLib = Some3rdPartyClass.create();
}
public static Some3rdPartyClass getMyLib(){ // Called by child activity
return myLib;
}
}
I need the initialization activity to be called only once. How to prevent that it is shown again when a user clicks on the back button?
More generally, is this approach okay, or would you suggest a better one? (I also considered using one single activity, but adding/removing the progress-bar and background dynamically)
Long running code really ought to be done using Android services. I would recommend doing your complicated logic in a service that your various "Activity" classes (which correspond to the views of your application) simply consume. Services can outlive the UI of the application and can also be started / initialized in response to various other events (like system boot), even when the user is not interacting with the application whereas an Activity is very tightly intertwined with the presentation.
In terms of loading / syncing data, I would strongly recommend against putting this logic in your activity code... instead, use a SyncAdapter or one of the other scheduling mechanisms for syncing. This will ensure that syncing activity is batched with other uses of the networking chip, which minimizes overall battery usage, and also allows you to have synced before the user is actively using your application, so that you aren't keeping the user waiting when they open your app.
When you start a new Activity from the loading Activity call the finish() method to close that activity and it will be deleted from the applications activity stack. like below:
startActivity(intent);
finish();
For the question for passing data through activities, extend the Android Application class, where you can define the global state and variables of your application.
Related
Let's say a service 'MyService' is already running, doing some work like copying a file in background, before an activity, 'MyActivity' is launched. Then user launches the activity. How can I retrieve what file is being copied in MyService when MyActivity starts so that I can show it in UI?
I haven't attached a code because I want a generic answer to this. The task could be anything, like downloading a file. I'm learning coding and experimenting with services. So, I'm just copying a bunch of big files in a service.
If needed, I'll post the code.
A possible solution to this is to have the service expose a RxJava bus (or similar) where it pushes updates on what it is doing. Then the Activity will subscribe to this bus in onResume and unsubscribe in onPause and will display info based on what is being pushed on the bus.
You could have a single bus, where the event itself carries data (like the percentage of copy), or you could have multiple buses, for instance one for state (idle, copying, ...) and another one for details on the state (like a bus for percentage of copy done).
A possible implementation for the states would be
sealed class State {
object Idle : State()
class Copying(val percent: Float): State()
}
then in your Service you would have
val stateBus = BehaviorSubject.create<State>()
then
stateBus.onNext(Copying(.5f))
I am learning Android app development from Udacity.com by Google engineers and they said,
"It is not a good idea to use 'AsyncTask' as it is not attached to an activity life cycle. The virtual machine will hold on to the activity object as long as the Asynctask is running, even after Android has called onDestroy( ) method for the activity and expect it to be discarded.
If you rotate your phone, the behavior is to destroy the current activity and instantiate a new one. The naive AsyncTask implementation now has two threads trying to do the same update. So it is not the best pattern for a potentially very long running background operation , such as fetching from web services. If you leave the app, the asyncTask will run as long as as the process is kept alive , but will run at a lower priority, and your process will be the first thing to be killed if the device needs more resources. "
1) If using AsyncTask is disadvantageous why was it created? What would have been the design philosophy or the cause to create it in spite of having services(or something similar to achieve same kind of functionality)?
2) What are the situations where Asynctask should be used for betterment compared to Services/similar options available in Android?
3) What are the situations/places Asynctask should never be used?
Please do not downvote this question. I searched Stackoverflow and I couldn't find a similar question.
Advantages of AsyncTask
Provides generic solution for all network calls
Publish progress to UI while executing.
Run Asynchronously
Easy to maintain and read.
Problems in AysncTask
When you rotate your screen, Activity gets destroyed, so AsyncTask will not have a valid reference to publish data from onPostExecute(). In order to retain it, you need to usesetRetainState(true) if calling from fragment or onConfigChanges() if calling from activity method of an activity.
If activity gets finished, AsyncTask execution will not cancelled automatically, you need to cancel them else they will keep on running in the background.
If any exception occurs while performing network task, you need to handle them manually.
Whereas AsycTask, Services, IntentService, Threads all run on different threads and all serve different purpose.
please read more detail here.
So you need to decide when to use which component while performing non UI operations.
i know that this question was asked before but i had tried all the solution and get Error
i have two activity on android studio ...
the first called 'MainActivity' and contain a method ' deleteFromArrayList() '
the secound on called 'DeletButtonActivity' and contain a method ' delete(View v) '
i want to invoke 'deleteFromArrayList ()' wihtout creating another class or make the method static .... becouse i have an ArrayList inside deleteFromArrayList()
note : i send value of index i want to delete from array list using Intent ..the code in DeleteButtonActivity is
public void delete(View v) {
try {
Intent i = new Intent(DeleteButton.this, MainActivity.class);
i.putExtra("index", (int) spinner2.getSelectedItemId());
(new MainActivity()).DeletButtonActivity();
Toast.makeText(getApplicationContext(), "it was deleted", Toast.LENGTH_SHORT).show();
}
catch(Exception e){
Toast.makeText(getApplicationContext(), e+"", Toast.LENGTH_SHORT).show();
}
}
and the code in MainActivity
public void deleteFromArrayList (){
this.arrayList.remove(getIntent().getIntExtra("index",-1));
}
when i run the app i got an Error NullPointerException,,,
can anyone help me ..please
hope that i describe the problem very well
Activities in Android are no just a simple class but they also have a Lifecycle:
An activity has essentially four states:
If an activity is in the foreground of the screen (at the top of the
stack), it is active or running. If an activity has lost focus but is
still visible (that is, a new non-full-sized or transparent activity
has focus on top of your activity), it is paused.
A paused activity is
completely alive (it maintains all state and member information and
remains attached to the window manager), but can be killed by the
system in extreme low memory situations.
If an activity is completely
obscured by another activity, it is stopped. It still retains all
state and member information, however, it is no longer visible to the
user so its window is hidden and it will often be killed by the system
when memory is needed elsewhere.
If an activity is paused or stopped,
the system can drop the activity from memory by either asking it to
finish, or simply killing its process. When it is displayed again to
the user, it must be completely restarted and restored to its previous
state.
So the problem with your code is that when you want to access the array in a stopped activity, the instance you have been using before might not be alive anymore.
How to solve your problem
A very simple approach is to use parameter passing before you do the transition from one activity to the other, for this you'd pass your Array as an intent extra and then you "get the result back" when you finish the second activity by using onActivityResult() callback.
A second approach could be to use a Service that is something similar to an Activity but it has no UI and it has its own lifecycle. Being able to be alive even when you app it is not. Using a Service, you'll keep the Array inside the service and you'll communicate with the array to do the usual operations.
A third approach could be to use an EventBus. A very simple communication mechanism between Activities, Fragments, Threads, Services. There's a great talk titled Android Application Architecture on Android Dev Summit 2015 that uses EventBus as a communication mechanism and to implement a MVC architecture pattern on a REST Android App.
Back to your question. If you just need to 'share' an array between two activities, use the first approach. The second and third are just examples of different alternatives for the case you need a lot more than that.
You must not do this. There are mechanism to communicate between activities or fragments.
On can be, using startActivityForResult, this is Activity A calls Activity B, then in B you do something, and communicate the result back to Activity A.
You can have another workaround to what you want. If you can access the data in both of your activities, you can modified in ether one of them, when the activity starts, it will show the updated data.
Please first read well about an Activity here, and also provides more context of your question.
I'm developing an android application, and would like to know the difference between a service started with startService() and a singleton class performing the same code I put in startService().
So, for example if I have a VideoRecordingService service set to record a video from the camera on it's start, and a CameraRecorderClass singleton class which have a StartRecording() method that also records a video from the camera, how do they differ?
They both non-related to any activity lifecycle, and they both use the main thread to do it's work.
Thanks
Service is mainly used when you want to do some background operation. For eg:- Playing music in your application. So, if you don't have any Activity running you can play music using Service.
While your Singleton instance would not be working if you close your application/activity if unless you are performing it in some background task. Also, Service will restart automatically if you return START_STICKY from onStartCommand when your Service is killed due to some reason.
So, in your case if you really want to do some long background running operation then its better to use Service instead of your Singleton instance.
When using startService it creates a new instance of that class, it can have a context and do a wide range of things that the Service class inherits. You can create this anywhere in your application where you have a context, and you can start and stop it multiple times (using startService and stopSelf)
With a singleton class, well, its a static object that you can only have once instance of (unless you want to create more I guess?). The static object can isn't much different, however it doesn't have a context and all that nice android stuff that comes with a class (unless you pass it a context or what ever you may need).
A service can also be run without needing to invoke it by using a activity, or showing a UI, it can run in the background with no UI, and can be started using a broadcast listener without interrupting the user, as long as the service is running then the service shouldn't be automatically closed by the system, rather then if you started an async task in the singleton and then closed the activity and the activity was destroyed.
There may be more to it. But you would have to look into dalvik..
I've searched everywhere a manner to have the equivalent of a main() function (yes function not method) inside a Android application but failed...
Typically what I would want to do is:
void main()
{
// do some really nice initialisations stuff here
// ... let the app does his life, I really don't care
// do some final stuff here before leaving
}
The nearest approach I've seen so far is to use a SplashScreen and override the OnCreate() method. The problem is that is not acceptable from my point of view.
Why? Because a SplashScreen is nothing than an Activity tagged as a LAUNCHER.
That makes it to appear in the apps list, thing I don't want when I develop an app widget.
Furthermore, where to place my code just before the app destroy? In the onDestroy() method?
No, once again, this is not reliable. Android can decide to delete my instance whereas the application is still running.
Well, in fact, I take for principle that every components of my app are running in the same process since I don't mention explicitely in the Manifest that I wan't a component to run in its own process.
In the case of an app widget, I've placed my init code on the first call of onUpdate() method. I think it's a good bet. Then this app widget (AppWidgetProvider more precisely) is in charge to launch any activity as its will.
The "DataBase" for all the app is defined in a separate Singleton like this:
public class MyDataBase {
public static MyDataBase getInstance() {
if (instance_ == null)
instance_ = new DataBase();
return instance_;
}
public void load();
public void save();
static MyDataBase instance_ = null;
public int myInt;
public String myString;
public Object myObject;
etc..
}
With this Singleton I'm sure at least, its lifecycle is the same as the entire app itself.
To back with that AppWidgetProvider, I have to trick a little. Indeed, Android can decide to delete its instance whereas some other activities are still on place and the process is still running. So for example, systematically loading my DataBase in the first call of the OnUpdate() is unnecessary and overkill. What I do is having a static boolean value that indicates if the DataBase have been loaded for the lifecycle of this process or not.
Thus, the AppWidgetProvider can be instanciated tons of time, as long as the Singleton DataBase persists (so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
About the cleanup code of the app, I thought to override the finalize() method of my DataBase Singleton, but well, I'm really not sure it's a good idea since the moment of the call of this method is totally unpredictable. I suppose it would be called if you suddently power off your Android, but well I'm not sure of anything here, thus so far, I didn't found a solution for that part.
Any comment or something less tricky that what I currently do is welcome.
Thanks.
onResume() is the function that will be invariably reached before starting you app, so you could either put the 'main' code in the onCreate() method or the onResume().
onPause() is ALWAYS called before destroying the app, either by the user or the OS.
There is great explanation regarding the lifecycle in the Android documentation:
http://developer.android.com/training/basics/activity-lifecycle/starting.html
For the initialisation you can over-ride the onCreate method of the Application class:
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created. Implementations should be as quick as possible (for example using lazy initialization of state) since the time spent in this function directly impacts the performance of starting the first activity, service, or receiver in a process. If you override this method, be sure to call super.onCreate()
Termination is harder to deal with. You'll probably have to monitor each component of your application separately. If you are targeting API level 14 or later you can use Application.registerActivityLifecycleCallbacks to help with this.
The nearest approach I've seen so far is to use a SplashScreen and
override the OnCreate() method. The problem is that is not acceptable
from my point of view. Why? Because a SplashScreen is nothing than an
Activity tagged as a LAUNCHER.
It's because Android is formed with several activities and those activities have life cycles. So every activities start from onCreate() then finishes at onDestroy().
http://developer.android.com/training/basics/activity-lifecycle/starting.html
That makes it to appear in the apps list, thing I don't want when I
develop an app widget. Furthermore, where to place my code just before
the app destroy? In the onDestroy() method? No, once again, this is
not reliable. Android can decide to delete my instance whereas the
application is still running.
In a scenario that user presses home button to exit from your app, your current activity is more likely to invoke onPause() method (only when the activity has no other processes to finish). However, when user force closes (terminates) your whole application by ending process. Then you don't have to worry about invoking any methods or what so ever because Android itself will close anything related to your application automatically.
To back with that AppWidgetProvider, I have to trick a little. Indeed,
Android can decide to delete its instance whereas some other
activities are still on place and the process is still running. So for
example, systematically loading my DataBase in the first call of the
OnUpdate() is unnecessary and overkill. What I do is having a static
boolean value that indicates if the DataBase have been loaded for the
lifecycle of this process or not. Thus, the AppWidgetProvider can be
instanciated tons of time, as long as the Singleton DataBase persists
(so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
The example you have posted for singleton database connection is not bad I think, but there are better ways to get the job done cleanly and more effectively. For example hibernate framework connection pooling