Say I have a very simple Android app that has just one activity - the activity displays a plain screen. Lets say I have overridden the onCreate() method of the activity and it simply sets the screen as described in activity_main.xml and then returns as shown below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//boolean BT_success = turnBluetoothOn();
}
In a desktop Java (or C or Python) program, execution starts at the "main" method/function and the program finishes executing when main has finished executing (and once all the functions called by main have returned). In this simple app described above, when the common set of callback functions like onCreate(), onStart() and onResume() are finished executing, is there any part of my code that is executing?
In this sense, there is no "main" method, like in the case of desktop Java, C or Python, right? Even if we had a couple of buttons in this main screen, we would have callback functions for those buttons.
So is it fair to say that the Android API callback based in the sense that an app developer has to implement certain callback functions (and those can in turn call other functions)?
Not in the way Win32 is. For one thing, the Android flavor of Java doesn't readily accommodate the notion of a canned function; it has neither delegates (C#) nor functors (C++, Python) nor function pointers (C, C++).
The Android API is still event driven, like most GUI systems are; but the primary ways for you to provide hooks into your code to the framework are:
inheriting from library classes and then overriding functions that were meant to be overridden;
implementing abstract interfaces in your classes (possibly anonymous) and providing those objects to the framework.
This is, generally, the Java way.
EDIT: depends on your definition of callback :) Normally, when people say that, they mean a function. In this sense, it's not callback-based. But if you mean "the framework calls you whenever something interesting takes place", then yes, it is. Event-driven, like I said.
EDIT2: Preamble: C has function pointers. It's a datatype that you can initialize with a function name, pass around like a primitive value, and then call with arguments at some point down the road. The call will be received by the function that the pointer was initialized with originally.
Windows, like Android, is an event-driven GUI system. The event-driven nature of Windows is implemented mainly via said function pointers - you pass a pointer to your function to the framework, the framework calls it back when something interesting occurs. This was designed in mid-1980's, before the advent of object oriented languages.
Now, those functions that are meant to be called by the framework are referred to as "callback functions" or simply "callbacks". I come from the Windows background, so for me, "callback" primarily means "callback function". As opposed to Android-style callback objects (is that even a term?).
This is not dissimilar to the way any GUI application/framework is designed. Even Java Swing works in a similar fashion. You implement the "callbacks" that are hooked to UI control events, and your "main" function usually only serves to kick off the main event loop and exit. Note that here, when main() exits, the program itself does not exit.
To simply answer your question, yes it is based on callbacks. You specify which activity should be the starting point for your application in your androidmanifest.xml. This activity's onCreate() is called to initialize the layout. Every interaction that you perform on the screen triggers a callback (which you will override to implement what you need). But just because the main activity exits does not mean that the application will exit.
This is where you go into the activity lifecycle. All activities sit on the main thread in a stack like manner. When one activity is killed, you go to the next activity in the thread and so on. The application itself exits when all it's activities in this stack have been killed or Android decides to terminate it. Keep in mind that you might normally expect onDestroy() to be called when Android terminates the application but this is not the case - Android may or may not call onDestroy(). In this case, there was no callback for the exit.
I would say the Android API is heavily based on Extension. You almost always have to extend their Classes and override their methods.
super.onCreate(savedInstanceState);
Is a call to the Super Class method that would normally be hidden by you override. You are, however, free to call back to classes that provide the logic you need but you are not forced to. I recommend that you do, and that you put those Classes under UnitTest.
Related
I have a problem getting access to an object that controls audio output and that was created in another activity. Here's the case:
I have a class that implements Runnable so that I can run it in its own thread:
public class PulseGenerator implements Runnable {...}
In my main activity I instantiate this class, pass the instance to a Thread object and start the thread:
noise = new PulseGenerator();
noiseThread = new Thread(noise);
noiseThread.start();
I have a few controls in my main activity screen to control internals of 'noise': switch audio on and off, select a waveform, change pulse width and the like. This all works just fine.
Now I want to move a few of these existing and working controls to another screen that I've called 'Settings'. (In order to make room for other additional controls on the main activity screen.) I followed the typical Android approach by creating a new activity for the new Settings screen:
public class Settings extends Activity implements OnItemSelectedListener, View.OnClickListener { ... }
This all sounds simple enough. The problem I have now is that I don't know how to get access to the 'noise' object from the new Settings screen/activity/class. When I run the app on the emulator and press a button to switch to the Settings activity, the app crashes ("Unfortunately, xxxxx has stopped.") and in Android Studio's 'Run' view, I get:
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException
with a reference to the line number in Settings where I try to access the 'noise' object for the first time. Which makes perfect sense to me, because I have declared, but not initialized the 'noise' object. Because I don't know how, which is the core of this question.
Putting the question more generally, how do I access an object instantiated in one activity and running in its own thread, from another activity?
I am a beginning java and Android programmer and this is my first post, please don't be too brief when answering. Actually I hope it's a 'stupid' beginner's question about multi-activity app programming with an easy answer, so I can move on with my project. I appreciate any help.
PS:
- Standard methods for passing objects between activities don't apply because an object running in its own thread is not serializable. (If I understood correctly.)
- I know of workarounds that use multiple screens per activity (one of them using setVisibility(View.GONE)) and that I could probably get to work. But these solutions lack generality and that's why I don't want to use them.
There are some possibilities:
A simple solution would be stopping the thread when an Activity is about to finish and restart it in the next Activity. Of course, it depends on what the thread does and whether it is possible at all.
Wrap the noise thread in a singleton, so you can access the thread from any Activity.
Create a Service and manage the noise thread in there. Maybe you can also reimplement the thread functionality as a Service. From https://developer.android.com/guide/components/services.html:
A Service is an application component that can perform long-running operations in the background, and it does not provide a user interface.
A long-running Service lifecycle is not bound to the lifecycle of an Activity, so even if an Activity finishes, your thread would keep running and would be accessible via the Service that controls it. Mind two things: although a Service doesn't provide UI, it runs on the main UI thread, and a Service might be finished by the operating system, but it can be restarted right after.
I'm trying to embed v8 in an Android application using NDK.
I have a JNI module that looks something like this (JNI mapping code not shown):
#include <jni.h>
#include <android/log.h>
#include <v8.h>
using namespace v8;
static jlong getMagicNumber() {
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
Handle<String> source = String::New("40 + 2");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
context.Dispose();
return result->NumberValue();
}
The first time I run getMagicNumber, it correctly runs and returns 42. The second time I try to run it, it crashes.
Specifically, this ASSERT seen in v8's isolate.h fails:
// Returns the isolate inside which the current thread is running.
INLINE(static Isolate* Current()) {
Isolate* isolate = reinterpret_cast<Isolate*>(
Thread::GetExistingThreadLocal(isolate_key_));
ASSERT(isolate != NULL);
return isolate;
}
It sounds a lot like this problem, which suggests using v8::Locker to obtain "exclusive access to the isolate".
By adding a simple Locker l; to the top of getMagicNumber, the crash no longer occurs. Problems that fix themselves that easily tend to break themselves when I'm not paying attention.
I only have the most tenuous understanding of why this fixes my problem, and I'm getting compiler warnings that I'm using v8::Locker in a deprecated fashion. The recommended method is to provide it with a v8::Isolate as an argument to v8::Locker's constructor, but I have no idea how I'm supposed to "obtain" an isolate.
Ultimately: What is the proper way to solve this problem according to the current state of v8, and why?
As I understand it, a V8 isolate is an instance of the V8 runtime, complete with a heap, a garbage collector, and zero or more V8 contexts. Isolates are not thread-safe and must be protected via v8::Locker.
In general, to use V8 you must first create an isolate:
v8::Isolate* isolate = v8::Isolate::New();
Then, to use the isolate from any thread:
v8::Locker locker(isolate);
v8::Isolate::Scope isolateScope(isolate);
At this point the thread owns the isolate and is free to create contexts, execute scripts, etc.
Now, for the benefit of very simple applications, V8 provides a default isolate and relaxes the locking requirement, but you can only use these crutches if you always access V8 from the same thread. My guess is that your application failed because the second call was made from a different thread.
I am just learning V8 now, but I think you need to call:
v8::Locker locker(isolate);
This will create a stack allocated Locker object which will block the Isolate from being used on another thread. When the current function returns this stack object's destructor will be called automatically causing the Isolate to be unlocked.
The you need to call:
v8::Isolate::Scope isolateScope(isolate);
This sets the current thread to run this Isolate. Isolates can only be used on one thread. The Locker enforces this, but the Isolate itself needs to be configured for the current thread. This creates a stack allocated object which specifies which Isolate is associated with the current thread. Just like the Locker, when this variable goes out of scope (when the current function returns) the Scope destructor gets called to un-set the Isolate as the default. I believe this is needed because many of the V8 API calls need a reference to an Isolate, but don't take one as a parameter. Therefore they need one they can access directly (probably through per-thread variables).
All the Isolate::Scope class does is call isolate::Enter() in the constructor and isolate::Exit() in the destructor. Therefore if you want more control you can call Enter()/Exit() yourself.
I can't seem to find any documentation on the details of an Activity's run loop for Android.
Apple documents the "anatomy of a run loop", and that's pretty much what I'm looking for. The Android documentation just says "Activity Is Running" in its life cycle state diagram. Obviously that's backed up by some sort of run loop.
Anyone have some insight (aka Documentation) into the internals of an Activity's run loop?
edit - I should clarify that I presume the run loop is actually owned and run by the main UI thread. The current Activity's functionality is likely injected into this runloop at a certain point. I'm interested in the overall UI thread run loop, as well as what role the Activity takes in it.
The short answer is, "don't worry about it, it's done for you."
Activities and other constructs sit on top of android.os.Looper, communicating with it through instances of android.os.Handler. A Looper manages your "run loop," dispatching messages from a queue and blocking the thread when it's empty. Handlers communicate with a thread's Looper and provide a mechanism for working with the message queue.
Most of the time you won't need to work with either one directly. Lifecycle events for your major application components like Activities and Services will be dispatched to your code. If you're curious as to what's under the hood, sources for both are available:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Looper.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Handler.java
Updated:
There's really nothing specific being referred to by "Activity is running." The Activity is simply displaying its UI, handling input, executing any necessary functions, and starting another Activity.
If you're interested in what implications multi-threading would have on the run-loop, there isn't really a concrete relationship. Your threads can just do their work, and the Activity's state will function independently and automatically update its UI (provided you call postInvalidate() correctly).
Original:
Take a look at the first diagram on this page: http://developer.android.com/reference/android/app/Activity.html
It specifies the "lifetime" of each Activity and what states it can be in, if that's what you're looking for.
Normally in a C or C++ program there's a main loop/function, usually int main (). Is there a similar function that I can use in android Java development?
As far as an Android program is concerned there is no main().
There is a UI loop that the OS runs that makes calls to methods you define or override in your program. These methods are likely called from/defined in onCreate(), onStart(), onResume(), onReStart(), onPause(), onStop(), or onDestroy(). All these methods may be overriden in your program.
The fundamental issue is that the OS is designed to run in a resource constrained environment. Your program needs to be prepared to be halted and even completely stopped whenever the OS needs more memory (this is a multitasking OS). In order to handle that your program needs to have some of all of the functions listed above.
The Activity lifecycle describes this best (your program is one or more Activities, think of an Activity as a screen).
Bottom line: Your program 'starts' at onCreate() through onResume() but the OS is running the loop. Your program provides callbacks to the OS to handle whatever the OS sends to it. If you put a long loop at any point in your program it will appear to freeze because the OS (specifically the UI thread) is unable to get a slice of time. Use a thread for long loops.
In Android environment, there is no main(). The OS relies on the manifest file to find out the entry point, an activity in most case, into your application.
You should read http://developer.android.com/guide/topics/fundamentals.html for more detail.
According to:
http://developer.android.com/guide/tutorials/hello-world.html
The application class must support a method for each activity that the Application
supports. In the general case, the onCreate is probably equivalent to the main/top
function for your needs.
Maybe it's possible by creating a timer and execute custom functions at every tick, reset the timer when it's at a specific time
The above answers provide a "why" as to there's no "main loop" on Android (which is important to understand). I'll offer a solution to the implied question, instead, as many visitors here will be looking for exactly that.
I believe the appropriate thing to do, here, would be to create an AsyncTask which operates as your "main loop". Or better yet, design your main loop to run as a java.util.concurrent future, which can be started and ended during lifecycle events (like rotation!), using signaling (keep your data separate). The AsyncTask API is deprecated, because it was complex, and handling it properly amounted to writing code that would, effectively, operate as an AsyncTask which cleaned up when the next problematic lifecycle event transpired.
Keep in mind that this will be a separate thread from the UI, and, as such, will be required to respond in short order to UI thread events, like "onPause" and "onDestroy". If your app does not respond within a certain period of time (~5 secs, iirc) to these events, or user input events, it will be killed by the OS. It's really prudent, for a real-time app, to be able to fully respond to these events in under 1 sec, even on the lowest-end device. You can use synchronization primitives to notify other threads that their response is pending, and they can use them to signal when they are finished (or simply end, in the case of a future).
I'm developing a java swing application that will have several subsystems. For all intents and purposes, let's assume that I am making an internet chat program with a random additional piece of functionality. That functionality will be... a scheduler where you can set a time and get a reminder at that time, as well as notify everyone on your friend list that you got a reminder.
It makes sense to organize this functionality into three classes: a GUI, a ChatManager, and a Scheduler. These classes would do the following:
GUI - Define all of the swing components and events
ChatManager - Create a chat connection, send and receive messages, manage friend list
Scheduler - Monitor system time, send notifications, store a file to remember events between sessions
For the program to work, each of these classes must be capable of communicating with the other two. The GUI needs to tell the ChatManager when to send a message and tell the Scheduler when to start monitoring. The ChatManager needs to display messages on the GUI when they're received, and finally, the Scheduler needs to both notify the GUI when it's finished, and send a status update or whatever to the ChatManager.
Of course, the classes as described here are all pretty simple, and it might not be a bad idea to just let them communicate with each other directly. However, for the sake of this question, let's assume the interactions are much more complex.
For example, let's say we can register a particular event with the scheduler instead of a particular time. When sending a message, I went to send it to the user, store it in a log file, create an event object and pass it to the scheduler, and handle any exceptions that might be thrown along the way.
When communication becomes this complex, it becomes difficult to maintain your code if communication with these classes can be happening in many different places. If I were to refactor the ChatManager, for example, I might also need to make significant chaneges to both the GUI and Scheduler (and whatever else, if I introduce something new). This makes the code difficult to maintain and makes us sleep-deprived programmers more likely to introduce bugs when making changes.
The solution that initially seemed to make the most sense is to use the mediator design pattern. The idea is that none of these three main classes are directly aware of each other, and instead, each is aware of a mediator class. The mediator class, in turn, defines methods that handle communication between the three classes. So, for example, the GUI would call the sendMessage() method in the mediator class, and the mediator would handle everything that needed to happen. Ultimately, this decouples the three main classes, and any changes to one of them would likely only result in changes to the mediator.
However, this introduces two main problems, which ultimately resulted in me coming here to seek feedback. They are as follows:
Problems
Many tasks will need to update the GUI, but the Mediator isn't aware of the components. - Suppose the user starts the program and enters their username/password and clicks login to login to the chat server. While logging in, you want to report the login process by displaying text on the login screen, such as "Connecting...", "Logging in...", or "Error". If you define the login method in the Mediator class, the only way to display these notifications is to create a public method in the GUI class that updates the correct JLabel. Eventually, the GUI class would need a very large amount of methods for updating its components, such as displaying a message from a particular user, updating your friend list when a user logs on/off, and so on. Also, you'd have to expect that these GUI updates could randomly happen at any time. Is that okay?
The Swing Event Dispatch Thread. You'll mostly be calling mediator methods from component ActionListeners, which execute on the EDT. However, you don't want to send messages or read/write files on the EDT or your GUI will become unresponsive. Thus, would it be a good idea to have a SingleThreadExecutor available in the mediator object, with every method in the mediator object defining a new runnable that it can submit to the executor thread? Also, updating GUI components has to occur on the EDT, but that Executor thread will be calling the methods to update the GUI components. Ergo, every public method in the GUI class would have to submit itself to the EDT for execution. Is that necessary?
To me, it seems like a lot of work to have a method in the GUI class to update every component that somehow communicates with the outside, with each of those methods having the additional overheard of checking if it's on the EDT, and adding itself to the EDT otherwise. In addition, every public method in the Mediator class would have to do something similar, either adding Runnable code to the Mediator thread or launching a worker thread.
Overall, it seems like it is almost as much work to maintain the application with the Mediator pattern than to maintain the application without it. So, in this example, what would you do different, if anything?
Your GUI classes will end up with many methods to keep it up to date and that is fine. If it worries you there is always the option of breaking up the GUI into sub GUIs each with a different functionality or a small set of related functionality. The number of methods will obviously not change, but it will be more organised, coherent and decoupled.
Instead of having every method in your GUI create a Runnable and use SwingUtilities.invokeLater to put that update on the EDT I'd advise you to try out another solution. For my personal projects I use The Swing Application Framework (JSR296) which has some convenient Task classes for launching background jobs and then the succeed method is automatically on the EDT thread. If you cannot use this you should try and create your own similar framework for background jobs.
Here, a partial answer to you design questions...
It looks like you want to have loose coupling between your components.
In your case, I would use the mediator as a message dispatcher to the GUI.
The ChatManager and the Scheduler would generate UpdateUIMessage.
And I would write my GUI that way
public class MyView {
public void handleUpdateMessage(final UpdateUIMessage msg){
Runnable doRun = new Runnable(){
public void run(){
handleMessageOnEventDispatcherThread(msg);
}
};
if(SwingUtilities.isEventDispatcherThread()){
doRun.run();
} else {
SwingUtilities.invokeLater(doRun);
}
}
}
So you have only one public method on your GUI, which handles all the EdT stuff.
If you want to have a loose coupling between the GUI and the other components (meaning : you do not want the GUI to know all the API of the other components), the GuiController could also publish ActionMessage (on a specific Thread?), which would be dispatched by the mediator to the other components.
Hope it helps.
Well, I will change the world you are working with. You have 3 classes and each of them is just observer of the chat-world. The MVC is the way how to deal with your problem. You had to create Model for your world, in this case chat program. This model will store data, chat queue, friend list and keep eye on consistency and notify everybody interested about changes. Also, there will be several observers which are interested in state of world and are reflecting its state to user and server. The GUI is bringing visualization to friends-list and message queue and reacts on their changes. The Scheduler is looking about changes in scheduled tasks and update model with their results. The ChatManager will be better doing its job in several classes like SessionManager, MessageDispatcher, MessageAcceptor etc. You have 3 classes with empty center. Create center and connect them together using this center and Observer Pattern. Then each class will deal only with one class and only with interesting events. One GUI class is bad idea. Divide to more subclasses representing logical group (view of model). This is the way how to conquer your UI.
You might want to look at a project that originally started as a MVC framework for Flex development. PureMVC has been ported to many programming languages meanwhile, including Java. Though it is only in a alpha status as of writing this!