Android, for JNI should System.loadLibrary be called in an InputMethodService? - android

When sub-classing InputMethodService where native code is used, Android will kill the service when the input method is dismissed.
Later, Android will restart the service and JNI is not present causing Java unable to find the native functions and an exception thrown.
I had previously thought that only one System.loadLibrary in MainActivity was required. Should this be added to services too?

There is no extra cost in putting LoadLibrary in all relevant classes, so go for it. Use it in static constructors of each Java class, or companion object of Kotlin class
MainActivity is not the best choice to begin with, because every time you later add another activity or service that can be started independently, you must not forget to duplicate your LoadLibrary.

Related

Calling methods on activity events

I am writing a simple Android library. I have a couple of methods that I would like executed when certain activity events happen - like after activity got loaded or when the activity gets paused.
One way I could think of was to create a class that extends activity, and write my methods there, and then have "target" activities extend that class. This was all methods get called
But if the end user is extending some other activity already, this method won't work. Is there a better alternative?
If you need only provide support back to API 14 or higher, you might be able to make use of the application level activity lifecycle callbacks - see the Application.ActivityLifecycleCallbacks interface for details.
To make use of this you need to register an instance of this interface with an Application instance, using the registerActivityLifecycleCallbacks method. One way to get that would be to have the developer using your library initialise your library by passing their Application instance to it. This is what I do in an SDK that I maintain, and it seems to work nicely.

Android IBeacon Library: How to not directly use an activity

The premise is I am writing a library that in itself uses and implements the IBeacon SDK.
My code has to implement that SDK, does things and if someone uses my library they dont have to interact with this SDK at all, so I'm making a higher level codebase you could say.
Now my code cannot use any activities by itself, its just a library, another user will then implements my code. So my code needs to consume the IBeacon events and do something with it without being an activity by itself.
So I would implement IBeaconConsumer myself and then the person using my library would just give me an activity / context and I would pass it to the IBeacon SDK.
Doing so results in the following problem (with proper mainfest code):
The activity binds its iBeaconManager object however onIBeaconServiceConnect never gets called.
See this stackoverflow question: Android IBeaconManager not connecting from activity
My vague assumption is this: the class implementing IBeaconConsumer is not an activity and its not the same class as the one I am binding the IBeacon service to and that might create the problem.
Its just very hard to debug since it all works, no errors, just no ibeacon activity - same behavior as if you forget to add the part in the manifest
If you want your IBeaconConsumer implementation to not be an instance of Activity or a Service, then you simply need to chain the bindService and unbindService methods to a valid ApplicationContext instance, and return that valid instance from the getApplicationContext method. This is not needed when you are implementing this interface with an Activity, because an Activity implements these three methods for you.
You can see an example of this in a related question here.

Call to JNI crashes after android service is restarted?

I have an android service that uses a native library via NDK/JNI. The native library is statically loaded/initialized as suggested...
static {
System.loadLibrary("mylibrary");
if (!nativeClassInit())
throw new RuntimeException("native init failed");
}
Everything works fine until the service is stopped (e.g., from a UI activity where the service may be started/stopped). The problem is when the service is stopped the task has not yet been killed by android and if the user restarts the service the native libraries are not reloaded and a call to a native function causes a crash in the native code?
I tried calling the nativeClassInit() method again after a restart but this doesn't help?
Also, I seen in other posts that unloading the native library is not allowed in Android.
I found by making the service run in its own private process and having the service kill itself in its onDestroy() method via android.os.Process.killProcess() solved my problem. Not sure if this is the most correct way but I would be happy to hear any suggestions.
Concerning the above comments...
What is the native code trying to do when it crashes, and what is the error?
The native code crashed as soon as an internal native library function was called just before the crash an __android_log_print was done displaying the correct parameter values passed in. Its hard to say what exactly happened from the dump.
Do you preserve some JNI pointers (JniENV, jobject-s, etc.) on native side between Service restarts?
Yes, I preserve the JVM in the Onload method and also JNI class IDs & method IDs in my static initialization method. I tried recalling the static initialization method but the same crash occurred.

How can Android source code not have a main method and still run?

I've seen this in a few tutorials now... but how in the world can Android source code not have a main method and still run.
For example (from http://developer.android.com/guide/tutorials/hello-world.html):
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
That runs but there is no main!!!
I've also thought that using things like onCreate (or formLoad, etc.) was bad becuase a constructor should do that work and such built-in methods can be smelly sometimes. But onCreate is an entry point? Even without a main?
What if there is more than one activity... is there a hierarchy to these built in event handlers? OnCreate trumps everything else? Otherwise, how would the app know what to run or where to enter the program?
Thanks!
Each application will be having it's own Virtual Machine. To run an app, within it's space (VM), must have a main method.
Activities are not the actual classes to be invoked for start of application. There is a class called Application, which will be the root class for an application to be launched.
If there is no main method, how can a VM recognize how to start an app?
Framework has classes called Process, VMRuntime which are responsible for starting an application. Which indeed deal with main method.
For better understanding, study the Zygote service of Android. deals with Applicationmanager Service, ActivityStack Activity Threadds etc.
That runs but there is no main!!!
Of course. Many things that you might think of as a Java "application" do not have their own main() method. For example, IIRC, servlets, WARs, and the like do not have main() methods -- the main() method, if there is one, is in the container.
But onCreate is an entry point?
onCreate() is a method.
What if there is more than one activity... is there a hierarchy to these built in event handlers?
Not really.
OnCreate trumps everything else?
Not really.
Otherwise, how would the app know what to run or where to enter the program?
An app does not "know what to run or where to enter the program".
An Android application is a basket of components. Some components may be tied to icons in a home screen launcher. Some components may be tied to scheduled timers, like cron jobs or Windows scheduled tasks. Some components may be tied to system events, such as when the device is placed into or removed from a car dock. Those components will be automatically created and used when appropriate (e.g., when a user taps the icon in the home screen launcher). Yet other components are only created and used when your code specifically asks for them.
Thinking of an Android application as if it were a monolithic console-mode Java program will cause you no end of trouble.
You tell it which one to run on startup in the manifest file. There isn't a main() because there doesn't have to be, main may be a convention used for "regular" java apps, but it isn't for things like browser applets. The system creates the activity object and calls methods within it, which may or may not be called main. In this case, it's not.
onCreate is different from a main, and from a constructor, in that it can be called twice on a single activity, such as if the process is killed and the user navigates back to the activity. See http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Actually, this type of pattern is not peculiar of Android, but happens whenever you have some framework in the middle. Some basic examples are java Applets and Servlets. Some of the answers already provide give the correct response, but I will try to elaborate a bit.
When you launch a Java app, you start a JVM and then you need to load something into it: so you need a static method (the main) because there are no objects (yet) living in the JVM that you can refer to.
If you have some sort of framework in the middle, it is the framework that will start the JVM and will start populating it with its own service objects: writing your code then means writing your own objects (which will be subclasses of given "template"). Your objects can then be injected (loaded) by the framework. The framework service objects manage the lifecycle of the injected objects by calling the lifecycle methods defined in the "template" superclass.
So for instance when you provide an applet to a browser, you do not launch a static main method: you rather only provide a subclass of java.applet.Applet that implements some instance methods which act as callback to manage the lifecycle (init, paint, stop...). It is the browser that will launch the JVM, instantiate what's needed for the launching an applet, load your applet and call it.
Similarly, with servlets you subclass the javax.servlet.http.HttpServlet class and implement some instance (non static) methods (doGet, doPost...). The Web container (e.g. Tomcat) will be in charge to launch the JVM, instantiate what's needed for launching a servlet, load your servlet and call it.
The pattern in Android is pretty much the same: what do you do is to create a subclass of android.app.Activity. When you launch an app, the system looks in the manifest to find out which activity should be started, then the "framework" loads it and calls its instance methods (onCreate, onPause, onResume...).
In Java programs we need a main() method, because while executing the byte code the JVM will search for the main() method in the class and start executing there.
In Android, the Dalvik Virtual Machine is designed to find a class which is a subclass of Activity and which is set to start the execution of the application from its onCreate() method, so there is no need of a main() method.
The order in which Dalvik Virtual Machine calls methods is based on order of priorities called android life cycle for more information on android life cycle check the link below
Android Life Cycle: https://developer.android.com/guide/components/activities/activity-lifecycle.html
While there is no specific main entry point, intent filters describe which activity is started when the application is launched.
They are controlled in AndroidManifest.xml as described here:
http://developer.android.com/guide/topics/intents/intents-filters.html
where a note pad application example is described:
This filter declares the main entry point into the Note Pad application. The standard MAIN action is an entry point that does not require any other information in the Intent (no data specification, for example), and the LAUNCHER category says that this entry point should be listed in the application launcher.
An android programmer should learn this like the back of their hands it simply explains everything and would help in the future when creating activities.
http://developer.android.com/reference/android/app/Activity.html
There is a main of sorts, it just happens to be out of your hands. After all, there's nothing special about a main function in any language. It's just the entry point where your code starts executing. The Android operating system expects applications to have a certain structure and it calls your code based on the conventions you follow.
I found this particularly useful...
http://developer.android.com/guide/topics/fundamentals.html#appcomp
Applets don't have main() methods either. It just depends on how your code is packaged.
The Android UI frame encapsulate some Java common details, you can study the source code of the android UI framework
I think that Jonathon's answer is going in the right direction. He says the OS expects a certain structure. There's a name for that structure which is a "state machine". In this case Android calls it the "activity lifecycle". Rob gives a link to the documentation which contains an important diagram of that state machine though the text is a bit dry. A quick search also found me the following link that explains it fairly clearly: http://www.android-app-market.com/android-activity-lifecycle.html
In Java, there is a main even if it isn't listed as main(). The page you get after the icon click, whatever its name, is the main().

Android Application Initialization

I have an application that is driven by a configuration XML: various
app properties are loaded at the app start-time by parsing the XML and
initializing static variables of some class. The data read from this
XML drives different Activities of the application. Presently, I have
called the "parsing and the properties-initialization" from the
onCreate() of my Main Activity.
I have a few questions as regards this case/approach:
Should I invoke the app initialization method from the Application
Object or is the current approach correct? What advantages/
disadvantages do/would we get/have if I choose to invoke it from the
Application object?
Do we really need a static class to store app properties? Or can we have all the properties as a static Collection variable in the application object?
Parsing a XML(~200 nodes) at app load time might take some time(not
sure how long tho); How can I avoid the dreaded ANRs? I am using a
Pull Parser.
Please help me find answers to these questions.
Thank you.
It depends on what you're initializing. Application's onCreate() should be used when you're doing things that need to be done before any part of your app works correctly and only needs to be done once, whereas Activity/Service/etc's onCreate() should be used for things that are needed for that component alone and needs to be done multiple times.
The main concern I have for putting all your initialization into a component is that it will make extending your application more difficult later on. Suppose you want to make some Activity in your application accessible by outside intents - now you've got to either move the initialization code to Application or you have to duplicate initialization code in the non-launcher Activity.
It sounds like you should check out SharedPreferences, especially PreferenceManager.getDefaultSharedPreferences(). The preferences will be stored between sessions and it gives you easy access to simple properties from any Context.
Threading. I find AsyncTask to be the easiest way to accomplish this task; there's a good write-up on it at Google. Alternatively, you could fire up a Service to do this in the background while having a foreground Activity inform the user that you're booting up the app.
The Application object is used for sharing non-persistent state across the application. I don't think you'll need to use an Application class at all. You can do your initialisation in the onCreate() method of the Activity that is called first. To quote the documentation:
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
You don't need to create your own class to store application properties. This is done for you by SharedPreferences.
You should also have a look at the setDefaultValues() method in the PreferenceManager
class as this will set preferences from the data in an XML file. What's nice about this method is that use the readAgain parameter so that the XML is only parsed once - the first time you start up your application - rather than every time.

Categories

Resources