I have an Android lifecycle question that I can't find answered anywhere else.
(This is not a question about making the activity class a global ref)
I'm using the standard JNI->Native Init() and Tick() calls to run the game on the native side. Very similar to the San Angeles demo.
I pass both of these calls a instance of the Java Activity object. This is so I can call back
to Java in order to (for example, turn adverts off, interact with the Java Twitter, etc).
Q1 : When I call Tick() to call my native calls, does this create a new thread, if so, why don't I have to call DetachCurrentThread from the native side?
Q2: I've tried caching the Activity instance on my Native Init() function and storing this in a static. This works on some devices, but on pre-android 5.0 device I get a stale reference JNI error when I use the instance in the Tick() function. Will making this a global 'reference' like I do for the activity 'class' in my OnLoad() function sort this?
Q3: When the user closes the interstitial adverts, I get a callback on the Java side, which I pass to the native side (eg, to restart the music). Does this create a new Native thread? Will my previously cached Activity instance still be valid?
Many thanks,
Steve.
Ok found my own answers.
1.No.
2.Yes, do the GlobalReference thing.
3.No, but the the Java side a a new thread.
Related
I am writing an SDK that allows a user of the SDK to request data and have it returned to them asynchronously.
To access the SDK I decided to use a Singleton pattern. I do this because they may want to use the SDK from several different activities or fragments and I want each component that uses it to have the same instance. So the user will call MyClass.getInstance() which will return an instance of MyClass to them. Then they can call myClass.doAsynchronousOp(), etc...
One issues I am having is that when a user calls a method on the SDK it will do a bunch of work and I don't want to block the caller's thread. So, the solution I came up with was to create an instance of a HandlerThread when the class is first instantiated. Then when the user calls a method on the singleton class that is supposed to be asynchronous I create a Runnable and run it using the HandlerThread. This seems to work pretty well, but I have a few questions:
1) Let's say the user gets an instance of my singleton and calls one of the asynchronous methods. Now the class is holding a running HandlerThread. When the activity is destroyed is it imperative that I call .quit() on my HandlerThread? If so, I pretty much need to make the user call a method like myClass.unregister() in the onDestroy() method of they're activity which is ok, but I'd rather be able to do it automatically for them. Is it bad practice to not call .quit() on my HandlerThread when the application component holding it gets destroyed?
2) Since this is a singleton I'm noticing that even if the Activity that is holding it is destroyed, the instance can remain in memory. So if the Activity is destroyed and then recreated (device rotation) then my constructor of the singleton doesn't get run again. This is problematic because I setup my HandlerThread in the constructor. If I call .quit() on the HandlerThread when the Activity gets destroyed and then the activity gets recreated, the HandlerThread still exists in the singleton object, but now it's in the Terminated state and I can't use it. Is there a good way around this?
Maybe a more general question: How can I provide asynchronous access to my SDK without running into thread lifecycle vs. android component lifecycle issues?
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
see
i have mainActivity which calls tempActivity
Now inside tempActivity i call some native method and malloc some data .. so now when user
1> come back from tempActivity to mainActivity or
2> exit from whole application
i need to call one clean up function which free all data malloc in native method so how can i implement such things?
Does android framework has any method to handle such clean up function?
Ok, i think the question is about how to free the memory that is being allocated using malloc() inside native code.
I had the same requirement in one of my Projects. I did it in the following way.
Inside onStop() or onDestroy(), I did a native call, which I have used to free() the allocated memory. This I think is the best and simplest way to do that. I am not sure if android is providing some API,s for this. It would be informatory to know if something like this exists. Thanks.
See the diagram taken from here.
Basically the Activity class is defining several methods that can be of use to you:
onPause which is called every time your activity is paused: that is your screen locks, you go to other activity
onDestroy and onStop called when you go to other activity.
Maybe some of these methods will be useful for you.
For the transition from tempActivity to mainActivity, put a call to the clean up function in tempActivity's onDestroy method.
For the case where the entire application is exited: that is much more messy. There is no global function that tells when an app exits, so you'll need to use some other means of tracking that the application is exiting.
I'd recommend using a Service with the onStartCommand function set to use START_NOT_STICKY and then in the onDestroy method of the Service call the clean up function. If you do this and you have all Activitys use the service then you can do it all in there.
The recommended technique is to allocate whatever you need in onResume and clean up in onPause. This way you allocate when your activity is about to be shown and clean up when your activity has become partially or fully obscured by some other activity.
I'm writing a Java program that uses a hardware driver written in c. This hardware driver starts a callback thread, and you can register callback functions to be called when stuff happens. How can I attach this thread to the jvm so that it can call the Java methods for these callbacks? I only have the thread id returned from the start_callbacks() function, returned as an int, but it is the pthread_t used in the call to pthread_create().
One way I found is to use pthread_once on the start of every callback function and attach the thread there. But then there is no way to detach it. I tried to use pthread_cleanup_push/pop, but they need to be called as a pair so that didn't work.
It seems to me that my only option to do this right is to attach and detach the thread at every callback call. Or rewrite the driver somewhat, which I really don't want to do.
Is there something I missed?
That's exactly what the JNI calls AttachCurrentThread() and DetachCurrentThread() are for.
The solution to you problem can be resolved with thread_local storage (C++ 11 and higher). This allows you to attach to an arbitrary thread, and then it will automatically detach when the thread exist (even when you didn't create the thread and have no control over it's life cycle).
A sample example of how to implement that in C++ can be found in my answer here:
https://stackoverflow.com/a/59934966/8367574
I have a small Android app that I have been working on that logs GPS data to my SD card in a GPX file. I currently have a main Activity that starts a Service to do all the background work. The service is kept in the foreground in the notification bar to make it the least likely thing to be killed by the OS. Currently I am requesting location updates from the service at the maximum frequency to get the most accurate route. The problem I am having is my User Interface is acting slow/strange. Correct me if I am wrong, but what I have concluded is that I have too much going on in the main thread of the app. My next thought is to try and move the service performing the acquiring and logging of data to a separate thread. I am new to Java/Android so the whole topic of interacting with separate threads is hard for me to wrap my head around. Initially in research I came across IntentServices, which are supposed to make threading easier, but from what I read these don’t seem to mix well with the Android location package because they don’t run long enough. I feel like I am running in circles with internet searches on this topic. I desperately need some guidance on how to achieve the following features for my programs service:
Separate thread from Main Thread
Fetching and storing of data must be the least likely thing to be killed by the OS and run indefinitely once started (don’t worry about battery I will have the device plugged in to power while running the app)
Eventually I will need the ability to interact with the User Interface
Thanks for any help you can offer!
this is a common problem that i have accomplished a lot on
in the launcher or main() ( what Android is calling an Activity ) you do as little as possible ( which amounts to saving the the refs they give you and maybe setting a few other things as long as you are there ) and do ^not^ drop in to a long-running activity
A Service is exactly what you need but instead of trying to pump it into a "hold on to it" state what you do is implement checks for nulls and handle as needed -- trying to "fix" a machine to make it run the way you want here actually involves rescinding you hold on the main thread and letting it go as fast as consistent with the Applicaton's general constraints.
To do this you can simply write a Service - reading everything available - then extend that service and implement Runnable then you run the constructor on that code from the Activity Constructor and do new Thead(yourClass).start(); in the onCreate() checking for Thread.isRunning() before starting it again ...
Service will have an onCompletion() call in it somewhere - it will go through an interface
All this is done in Android in something like start activity for result then you just to the UI stuff in that call or sorta figure out a way for the GUI to get called somehow at some time then check to see if Service is done an so report in the gui