I'm working with a 3rd party SDK in a Flutter plugin (Kotlin), and need to instantiate a particular class once, so I can share the state with various different instances of Method- and Event Channels.
I have several classes that expose 'features' as event channels, and they all use the same instance of a callback from the SDK.
For visual reference:
com.company.example
-- Feature1StreamHandler
-- Feature2StreamHandler
-- Feature3MethodHandler
-- Featuer4MethodHandler
Each one of these handler implementations, require a scan instance, which needs to be configured once, when the application starts up and then dispose of it, when the application closes.
Coming from C#, I'd implement a contract, create a concrete implementation and initialise the class during the application bootstrap stage, startup, however, a similar 'pattern' in Android does not seem to work, as I kind of expect the bootstrap to be the MainActivity, however, data is then not passed on to the Flutter plugin portion.
I'm hoping my explanation makes sense...
Something like this:
In MainActivity, construct SDKScan object.
In the Flutter plugin, for argument sake, MyPlugin, I want that instance of SDKScan created in MainActivity.
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.
I am going through Xposed framework in Android. Specifically reading blog - http://d3adend.org/blog/?p=589 for potential countermeasures and have couple of question on those line.
So when we hook a method using Xposed , framework makes that method as native and executes the code it wants to hook. So how is that in stacktrace original method is called?
com.example.hookdetection.DoStuff->getSecret //This one
de.robv.android.xposed.XposedBridge->invokeOriginalMethodNative
de.robv.android.xposed.XposedBridge->handleHookedMethod
com.example.hookdetection.DoStuff->getSecret //This one again
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
de.robv.android.xposed.XposedBridge->main
dalvik.system.NativeStart->main
Also why does it come twice in the stacktrace. I want to understand the order in which they are executed.
Is the actual method even run? Since the hooked method code executes it would not ideally execute the original method code. So how can we possible add a stracktrace detection mechanism in the same method knowing it would be replaced.
Xposed inner workings aren't easy to understand if you aren't comfortable with low level code and android kernel. To make it short, when you open an app on your Android device, there is a master process called Zygote that will spawn it as its child process.
The purpose of Xposed is to be able to control Zygote and detect whenever a process is about to be spawned, so that someone is able to hook methods by replacing their definitions before any calls are made to them.
You have a lot of control by using Xposed, you can replace the entire method body, so the original code never get called or you can use beforeCall and afterCall hooks which is basically an usage of the trampoline technique (A C++ example below)
As you can see when a method is called it doesn't directly go to the original code but to an injected code block where someone can do anything he wants (Dump, Change parameters, etc) then it will jump back to the genuine code. You can also do this after the genuine code, so you get the method output. Xposed implements this by using beforeHookedMethod and afterHookedMethod.
Adding a stacktrace detection mechanism won't help at all. You will call Java methods to get the actual stacktrace. It can be defeated easily by hooking the getStacktrace method, saving a valid genuine stacktrace, then when ever getStackTrace is called and contains Xposed methods, return the previously saved genuine stacktrace.
Your best bet is to rely on Native code to detect it, but even then any determined and experimented hacker with full device control can manage to defeat it eventually.
To add to above points when you call XposedHelpers.findAndHookMethod the callback can either be -
XC_MethodHook : Callback class for method hooks. Usually, anonymous subclasses of this class are created which override beforeHookedMethod(XC_MethodHook.MethodHookParam) and/or afterHookedMethod(XC_MethodHook.MethodHookParam).
XC_MethodReplacement : A special case of XC_MethodHook which completely replaces the original method.
1st one just provides you the hooks to execute methods before and after original method where as 2nd one replaces it completely. Eg - Xposed example on github
Couple of posts I have written -
Creating a new Xposed module in Android
Installing Xposed Framework on Android devices
There are many examples of taking a screenshot using a reference to the current activity. However, in my case, I need to take a screenshot of an activity which comes from an external SDK (but still within my app). For obvious reasons I don't have a reference to that activity object within my code. I saw solutions using Instrumentation and UiDevice, but they seem to work only when implementing a testing application using the TestCase framework, while I need it to work in a normal application.
Is there another way?
Well, if anyone finds this question useful, here's the answer I found:
In your activity or service, call getApplication().registerActivityLifecycleCallbacks(), passing it an object that implements the Application.ActivityLifecycleCallbacks interface. That object will get a callback on every activity's onCreate/onStart etc. with a reference to the Activity object, from which you can get the view and take a screenshot. You can identify that it's an activity from an external SDK by its package name.
NOTE: Application.ActivityLifecycleCallbacks is only available since API level 14 (a.k.a. ICS).
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().