I'm falling into a bit of a dilemma. As I learn more and more about Android and Java, the more confused I am about the state of the building blocks of Android apps. (i.e. Activity, Service, Broadcast Recievers, Content Providers)
Since all of those building blocks are just Java classes, it's tough for me to wrap my head around them because there can be multiple instances of them. As of late the biggest challenge is with tracking which instance of the Activity is actually being created, started, resumed, etc;. I started playing around with Intent flags, and that just threw another wrench (or ten) into the equation.
Being able to tell their state would be indispensable and even better would be to see the current task stack/process id that the activity is associated with. At this point I'm just guessing whether or not FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP are working properly.
Surely there is a solution. Is there any debugging tool that I can use to get an inside view of my app/process to see which components (specifically Activities) are in existence?
Some notes/thoughts I've had:
Should I create a unique static auto-increment int for each class to try and track it myself?
Is this what I want Get current visible activity to user?
Does this application manually keep track or is it really peaking inside of the process? https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode
There has to be a debugging tool for this... -__-
Not sure if this will solve your understanding of the topic completely, but these guys did a nice app to try and visually see the main launch modes available for Activities > https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode&hl=en_GB
Hope this helps in some way to explain things! :-)
Related
I'm planning to create an app that basically asks a lot of questions (for the purpose of study). I haven't started it yet, I'm still planning how I will carry it out.
I'm thinking of creating a class called Question and then storing multiple objects of that class in different arrays. I could end up having thousands of Question objects. I would do this in my onCreate() method, so as to have all the questions ready by the time the app starts.
Would doing so much in the onCreate() method slow down/cripple my program?
What makes this worse is that if the user exits the app and then reopens it, the questions would be added again.
Is there a better way of having large amount of objects in my app?
As someone fairly new to android development and programming in general, I appreciate any help.
It would be better to do the loading on a background thread (using an AsyncTask or other threading library) and to display some sort of loading progress bar to the user while it loads. In the onPostExecute method of your AsyncTask (or similar) then you can turn off the progress bar and turn on the relevant UI elements.
If you want the questions to persist between different activities, you could store the data in a singleton so it persists during the app session at least.
It's becoming increasingly frustrating trying to get NetworkInfo working. I posted a question, but I guess people haven't seen it. Anyway, I really need a solution based on my flow below. I need to know when my network changes so I can determine what kind of network it is and then make decisions based off that answer. I thought, OK, maybe I'll try JobService, but I am not having a lot of luck trying to puzzle out how to use it for my needs. My app is reactive and happens all behind the scenes and only shows a notification when the user needs to do something. So, I guess I'm looking for direction. How to use JobService to get the granular information I need * and * to use to replace BroadcastReceiver for both Network Changes and Alarms. I'll need to be able to cancel/modify alarms as IPs change while people roam around.
I'm confused regarding with some basic android development concepts, my question is not pointing at a particular code, thats why I dont include any.
Let's say that I have an activity inside of which I have a container in which I load a couple fragments (they are multiple instances of the same fragment), now the activity is populated, and inside one fragment I press a button that opens a new activity, it doesn't matter what may happen in that activity, the thing is that when I press a button it should take me back to the previos activity, I know that pressing the back button or using .finish(); will take me back to my already-populated activity, but I want to know, if that is the correct thing to do, or should I finish the activity as soon as i leave to the next one and when I want to go back create a new instance and repopulate it, if so, where should i store the variables?
Let's say that the fragments that I mentioned are "alarms" for an alarm application, and when I create it I call AlarmFragment newAlarm = new AlarmFragment(); and then I add that alarm to an arrayList in my alarms activity (java class) getListOfAlarms().add(getAlarmsAmount(), frag); which remains on the activity that has the fragment container, the question is, are these variables created in the right place? Because I am leaving them inside the activity itself right? What could happen if the activity is destroyed? I've been told that I should create an SQL database for storing those variables. I am not talking about long term saving but variables that I will be using at runtime
Can someone explain me these concepts a little bit? A link to a place where it is explained will be great too.
Your question seems like it has many parts.
In Part 1, this is what I think you are talking about:
1) how you decide to allow the user to get back to the first activity is really up to you. And 2) what you leave in the Back Stack is also up to you and what you want to define for the users' capabilities within your app. For example, if you want them to only be able to use a button that you define inside Activity 2 container, that is fine. However, you are not required to provide a button in Activity 2, and you are certainly allowed to use the Up Action in the App Bar for navigation. If I were you, I would read more about the Tasks and the Back Stack http://developer.android.com/guide/components/tasks-and-back-stack.html
You also mention this idea of having to "finish an Activity" with .finish(). I don't think that is usually necessary, but it is available to you if you want to use it based on what you decide for your app's logic (and what the user should and shouldn't be able to do).
With the Back button, Activity 1 will appear as if just initialized when you get back from Activity 2. Try it out. Also run some Log statements based on the simple diagram I provided and the Lifecycle "callbacks" (put these methods in your Activities and throw a Log statement in each to get a better sense of where you are in the Lifecycle) http://developer.android.com/guide/components/activities.html#Lifecycle
As for Part 2 of your question, I would try/set-up some of the above first, then start to experiment with a single variable to see what happens to it between Activities. There are a lot of "what ifs" to your question. You don't necessarily have to create a DB to store your variables, but that could certainly be an option. Take a look at the Developer Guide for most of the Data Storage options: http://developer.android.com/guide/topics/data/data-storage.html
If you are concerned about losing data when the Activity is destroyed, I might consider creating a database. Read the following for more info on recreating an Activity when you have gone elsewhere and are returning: http://developer.android.com/training/basics/activity-lifecycle/recreating.html In particular Saving Your Activity State: http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
There's also an SO post on this: Saving Android Activity state using Save Instance State
This is a question of good practice and a smart solution, I need an advice.
I have an app that (and as far as I can read here in Stackoverflow and by Google search):
The app handles kind of documents and I like it possible to
handle more than one document at the same time. (I am used to Win32 where there is a program segment and one segment of data for each instance but that is obviously not the case in Android/Java.)
I see one instance starting the app from the app storage (the tablet) another opening a Gmail or email with an appended document file, a third instance by opening a file from a File handling app like ES file explorer. And I like them all be possible to be flipped in between. The user might like to read more than one document at a time. (correct me if I use the word instance wrong in the Android/Java environment)
The app is built in a JNI section that contains all the data and logics and a Java Android user interface. (The JNI section is designed to be OS independent for implementations in different OS, has a glue c-file.)
The Android section recreates every time the screen is flipped or instances are flipped between
There is only one JNI instance and that is kept even when the Android Java part is recreated and all Java data is wiped out, right now it shows the last read file in all cases flipping in-between pushing the running app button
There are no problems making different instances within the JNI section as long as it is possible to bind them to each Java instance, with an identity or something that I can use as a parameter in the interchange with the JNI section, but how?
I can't save for instance the FilePathName in each instance to identify the instance in the Java section because it will be wiped when the Java section is recreated.
First question is if I am right in my observations reading Stackoverflow and Googled articles?
Second question, any good suggestions in solving the issue? I need an advice
Is there a possibility to identify the instance in all situations as long it is alive?
Any other possible paths, both to the general issue of separating data for each instance or identifying the instances for the JNI to handle the data for each instance?
Jan
We have similar problems with JNI objects in our application. The problem is that JNI link isn't work as ordinary Java object and has to be relesed explicitly. At the same time we have activity that can be destroyed at any moment by Android.
Our current solution is to store JNI objects on Application level with posibility to manage refereces and drop objects as soon as reference is zero. And also destroyed JNI reference if activity is going to be destroyed forever. So this is similar like you did in previous post.
However if you would like to have your application scalable after some time you might understand that this solution isn't ideal.
The first thing that Android system sometimes temprorary destroys activity to save memory. In your case all JNI objects with documents will still consume memory. So the best solution here is to be able documents on JNI level saves its state to bundle. This is especually important if your documents can be changed by user. In that case by saving state of JNI object in onSaveInstanceState you can destroy your JNI object and recreate in onCreate. However here it is important to analize how much time is required to destroy/create JNI object with saved to bundle document as we have to support quickly activity recreation in some case (portrait/landscape mode for example) with some limited bundle (not more 1Mb). In case of long process this solution might be not good.
Also as you would like to have one task - one document system. You should consider case when you have several activities in one task.
The second item that Android isn't call onDestroy() always. And if you do some save operation here data might be lost sometimes.
Hope this information helps you.
I made something working but I don't know if it is good practice?
I am getting an int-instance-tag from JNI and tagging it on the intent by
public void onCreate(Bundle savedInstanceState) {
....
if (savedInstanceState == null) {
// Creating the JNI task and get the JNI task ID
int iInstance = initProgram(...);
// and store the JNI task ID in the intent
getIntent().putExtra(Intent.EXTRA_TEXT, iInstance);
...
}
...
public void onResume() {
super.onResume();
if (JniManagement.resumeInstance(iTask)) {
...
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
iTask =
savedInstanceState.getInt(AndroidApp.STATE_TASK_ID);
}
Then we are talking about the lifespan of a task, the user is flip/flopping between windows/tasks with the home button. The issue is to synchronise the JNI data with the task of Java.
Re-appearing in th else section of if (savedInstanceState == null) { we get the JNI task ID from the intent and synchronise the JNI task with it.
And onDestroy() with if(isFinishing()) freeing the instance set of memory in the JNI.
#Override
public void onDestroy() {
super.onDestroy(); // Always call the superclass
if(isFinishing())
Commands.destroyInstance(getIntent().getExtras().getInt(Intent.EXTRA_TEXT, 0));
// Extinguishing the JNI task started during onCreate()
}
The JNI-side
In the JNI-side all memory used by an instance will be put together in a structure. This structure could be pointed at, in an array of pointers to get the right set of data for the right instance integer. The pointer array is realloced when new instances are created and can go on as long there is memory left for a new instance.
This works actually pretty good, always getting the right data to the right activity/instance. And using a File Manager app starting one activity after another by calling work data files, there will be a stack of activities/instances. When the user is leaving them with the end button are pealed off one by one and its memory is extinguished real smooth. Open a file in a Gmail works fine too the same way, however appears as a different activity by the activity button.
As an old Win32 C-fox I love my pointers and set them in all the methods/functions this feels a bit clumsy (only handle the active window screen data). But the Android OS do not have active overlapping windows.
So just synchronising the JNI this way to the right Java activity/instance is simply working real smooth.
But is it good practice? Are there any other smooth and good looking solutions?
When a single activity crashes, all the activities in flow crashes.
As all activities crash, each generates its own error dialog, so can we have a single dialog for all crashes?
Try catch is already implemented.
You use a singleton static final object to handle all your diablog boxes across all your activities. One such singleton object is the application object, see http://developer.android.com/reference/android/app/Application.html, but you don't have to use that one if you don't want to.
Also, you have to make sure that try/catch is implemented absolutely everywhere, wherever the android operating system makes calls into your app code. I'll find that I've got try/catch in most places in my code, but somehow when I'm trying to develop quickly I accidentally miss a few places and of course they're the ones that end up causing me a problem!