How can I generate and compile Java files in Android at Runtime - java

I know with javax.tools.* it is possible, but since this is not included in the Android API, I'm desperately wondering, is this possible?
Right now, my goal is to create a drag-and-drop tool to allow users to create their own layouts (as not everyone wants to learn Mobile Development, as it requires a lot of time, dedication and practice) similar to how Android Studio does it's own. However, of course the most important thing is to implement functionality via onClickListener and onTouchListeners. I've begun remedying this by creating my own DSL (Domain-Specific-Language) with a GUI front-end allowing users to choose what they want via PopupMenu and SubMenus. For example...
Statements
{ if, for, while }
Statements must be followed immediately by a reference and then a conditional (obtained from that reference), like a "if(Object.conditional())" statement.
References
{ Object1, Object2, Object3 }
The objects are references to other Views (I.E, Buttons, Layouts, WebView, etc.).
Conditionals|Actions|Getters|Setters
{ isSomething(), doSomething(), getSomething(), setSomething() }
Each Reference's methods, wrapped so that each wrapper keeps track of it's method's attributes and description (hence documentation).
It would go something like such...
IF ImageView1.isVisible()
ImageView1.setVisible(false)
ELSE
ImageView1.setVisible(true)
Of course, the method setVisible(boolean) is a wrapped version of setVisiblity(int).None of this is typed, it is obtained from a simple PopupMenu which shows them the applicable selections based on current context.
How I plan on transcribing this to compiling code was to convert the statement into Java code, inserting references on the fly as they are needed (I.E, ImageView1 would be defined in java as private ImageView ImageView1;), generate methods somewhat similar to how ButterKnife generates it's extra classes for it's onClick and onTouch annotations, etc.
Then, after planning all of this (been working on it for 2 weeks now), I find out that Android does not have support for compiling code like this. Please tell me something like this is possible. It's something I 100% wanted to do. Is this possible with any third party libraries?
If not, is there some possible way to mimic doing so? I could do it the long and slow way, of preparing every such possible way, keeping track of the references myself through a map, and when it is about to be called, directly call the implemented method for the View associated with that key, which theoretically COULD work. In fact, that'd be my second go-to if I can't. It'd be messy though.
Sorry if this is too long, I just want to get this to work.
TL;DR: Is there a way to compile a generated Java file created at Runtime in Android (since javax.tools.* does not exist), and if not what would be the best way to do so?

Related

Why use enums when it creates dependency across teams?

I know enums are used when we are expecting only a set of values to be passed. We don't want the caller to pass anything other than the well defined set.
And this works very well inside a project. Because you know what you've to pass.
But consider 2 projects, I am using the models of 1st project in 2nd.
Second project has a method like this.
public void updateRefundMode(RefundMode refundMode)
enum RefundMode("CASH","CARD","GIFT_VOUCHER")
Now, I realise RefundMode can be PHONEPE also, So If I start passing this to 1st project, it would fail at their end (Unable to desirialize enum PHONEPE). Although I've added this enum at my end.
Which is fine, because If my first project doesn't know about the "PHONEPE", then it doesn't know how to handle it, so he has to update the models too.
But my problem is, Let's imagine a complex Object am trying to pass, which also takes this RefundMode, when I pass a new RefundMode just this field should be become null or ignored at their end right ? Rather than not accepting the whole object, and breaking the entire flow/request.
Is there a way I can specify jackson (jsonproperties) to just ignore that field if an unknown value is being passed. Curious to know.. (Although In that case, I am breaking the rule of ENUM) So, why not keep a String which solves all the problem ?
It's all about contracts.
When you are in a client/server situation, being a mobile app and a web server, or a Java library (jar) and another Java project, you have to keep the contracts in mind.
As you observed, a change in contracts need to be propagated to both parties: the client and the server (supplier).
One way of working with this is to use versioning. You may say: "Version 1: those are the refund modes.". Then the mobile app may call the web server by specifying the contract version in the URL: /api/v1/refund?mode=CASH
When the contract needs to be changed, you need to consider what to do with the clients. In the case of mobile apps, the users might not have updated their app to the latest version, so their app may still be calling /api/v1 (and not supporting new refund modes). In that case, you may want to support both /api/v1 and /api/v2 (with the new refund mode) in your web server.
As your example shows, it is not always possible to transparently adapt one contract version to another (in your example, there is no good equivalent to PHONEPE in the original enum). If you have to deal with contract updates, I suggest explicitly writing code to them (you can use dedicated JSON schemas, classes and services) instead of trying to bridge the gaps. Think of what would happen with a third, fourth version.
Edit: to answer your last question, you can ignore unknown fields in JSON by following this answer (with the caveats explained above): https://stackoverflow.com/a/59307683/2223027
Edit 2: in general, using Enums is a form of strong typing. Sure, you could use Strings, or even bits, but then it would be easier to make mistakes, like using GiftVoucher instead of GIFT_VOUCHER.

Android Programming and Java syntax

This is a question regarding the syntax used in Eclipse SDK while programming some JAVA code for an Android App.
I am an embedded microcontroller engineer that's mainly used to programming in Assembler (a long time ago) and C. I am a newbie when it comes C++ and JAVA and to help me write my code I have been using a mix of the developer.android.com for background info and stackoverflow.com for real world examples and have found them very useful.
So, I have no problem writing code to do what I want to do because I've always done it, but I am finding it very difficult getting my head around the syntax used in writing Android Apps.
For example to access the GPS one of my lines of code read thus:
LocationManager locationManager = (LocationManager)
this.getSystemService(Context.LOCATION_SERVICE);
but can be shortened to this:
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
I prefer the second version, but why were some examples written like the first example? Both seem to work fine. I've seen other examples that look even more complicated using "Class".
Secondly, is this not a complicated way to do a really simple thing:
Toast.makeText(getBaseContext(),"Hello World",Toast.LENGTH_SHORT).show();
Why not:
Toast("Hello world");
It now takes me four times as long as it use to write code.
The line break after the cast there is just to keep the lines from getting too long.
On this:
Toast.makeText(getBaseContext(),"Hello World",Toast.LENGTH_SHORT).show();
... it would be simple to write it as you say, aexcept that doesn't do the same things. Basically, that line is
Finding the outermost enclosing place to put graphics
Setting the text you want to show, and setting some formatting or some such
and then showing it.
You want to split those up because you don't always write to the outermost world, and you may want to, for example, make several different chunks of text and show90 or hide() them later. (Think an error message and a success message, for example. You like to build them once and then show/hide the ones you don't need.)
Now, if you can define what context you want and never want to mess with the visibillty, you can make a function that does just that.
It is kind of beginner OOP-ish style to put this everywhere. It is implied in your second example, and the second example is the more common style.
Now this one has to do with a bit of engineering. Yes, your second short example could have been implemented (except that Toast is a class, not a function, but a similar thing would work), but it would preclude a lot of important things you may want to do. A Toast may not be all that lightweight of an object; you may want to cache it. That's why you first get an instance with makeText and only then call show on it. The Toast instance will also have a complete lifecycle that you need to control, but won't be able to with your simple example. The instance can probably undergo further configuration, etc. etc. In short, there's a reason for it which is not obvious from a Hello, world piece of code.
Welcome to the world of Android and Java programming. Since you come from an assembly language background, my advice is: Get used to more typing. :)
Regarding the first code fragment: First, the qualifier this. on the call to getSystemService() is redundant; you can just drop it. Secondly, you can eliminate the qualifier on LOCATION_SERVICE by statically importing the name. Add something like this to the imports for the compilation unit:
import static android.content.Context.LOCATION_SERVICE;
or, if you don't mind the namespace pollution:
import static android.content.Context.*;
Regarding the second fragment: for architectural reasons, Toast eventually needs to associate the popup window to some application context. The first argument to the factory method makeToast is what makes this possible. (By the way, you just need getContext(), not getBaseContext(). You could also stash the context in a field.) As far as the third argument to makeText—arguably, a version of the factory method could have been provided that has a default display time, but Android doesn't provide that, so you're stuck with the third argument as well. You can again avoid the qualifier by statically importing LENGTH_SHORT. Finally, the factory method just returns a Toast object. You aren't required to show() it just yet; it could be stashed and shown at a future time. It's good design to separate creating the Toast object from the action of putting it on the screen.
I will try to explain the things in the easiest way and to the best of my ability.
1. ".this" refers to the current object in Java. ".this" specifically points to the current object accessing its own instance variable members of that class.
2. Using "this" is just being more specific.
3. Now in the case of Toast, It requires the "context" parameter to point to the Activity
where it will display the Toast.(ie on which activity)
4. You can use "this" if you are not inside an Anonymous class, or if you are in an Anonymouse class then use "Your_Activity_Name.this" in place of context.
5. getBaseContext, getApplicationContext are like global access to the parts of the Application.
6. I always prefer Your_Activity_Name.this in context place. Context means the Activity, on which the Toast is going to be displayed. And yes there is No Toast(String s) method in activity.

Writing a custom eclipse debugger

EDIT: There must be some way I can approach this without writing a whole new debugger. I'm currently looking into ways to build on top of the existing java debugger. If anyone has any ideas on how to grab information the Java debugger already has (about stack frames, variables, raw data etc.), that would be really helpful.
--
What I'm trying to do is I have this framework/API built on Java, and I would like to write an eclipse plugin debugger that is customized to my framework. Here is a simple example:
I have two classes, one called scope and one called variable. The scope holds a map of variables. The code is all in java, but I'm using this scope-variable relationship almost like a new language, and would like a variable debug tab that gives me a list of currently active scopes with the variables that are currently stored inside. Here is some code:
import java.util.Hashtable;
public class Scope {
private Hashtable<String, Variable> variableList = new Hashtable<String, Variable>();
// constructor
public Scope(){
}
public void put(String key, Variable v){
variableList.put(key, v);
}
public Variable get(String key){
return variableList.get(key);
}
}
public class Variable {
private String value;
private String name;
public Variable(String aName, String aValue){
name = aName;
value = aValue;
}
public String getValue(){
return value;
}
public String getName(){
return name;
}
public void setValue(String aValue){
value = aValue;
}
}
This is obviously an extremely simple example, but I would like to accomplish something similar to this where I can get a variables window, set a breakpoint, and have a "debugger" list out my active scope objects and the variable objects inside.
I've been trying to read and understand: http://www.eclipse.org/articles/Article-Debugger/how-to.html
and its pretty dense (as well as extremely outdated), but I will try to take some time to understand it. I just wanted to see if anyone had any high level recommendations on how to approach this type of problem, as I have little experience developing plugins in eclipse or making debuggers.
Thanks!
Not an easy task. That article is still the main reference, I think. Old, but not outdated. Try to digest it, and preferably to make it work. Before it, you should have a minimal experience developing Eclipse plugins.
There are many pieces in the picture, but the first thing you must understand is that when Eclipse is debugging something (assuming we are using the standard debug model), we have two separate "worlds": the Eclipse side, and the interpreter side (or, if you prefer, the "local" and "remote" sides).
Int the Eclipse side, the programming involves a cooperation between some Eclipse core classes and some classes of your own, which extend or implement some Eclipse classes/interfaces:
A "launchConfigurationType" (extension point in your plugin.xml) which causes the apparition of a new custom configuration when you click "Debug As -> New Configuration); this goes togetther with some "launchConfigurationTabGroups" definition that defines the "Tabs" dialogs that will appear in your custom launch configuration (eg) (each Tab will have its own class typically).
The launchConfigurationType is typically associated to a LaunchDelegate class, which is sort of your bootstrap class: it has the responsability of creating and starting a running/debugging instance, both on the Eclipse side and on the "interpreter" (or "remote") side.
On the Eclipse side, the running/debugging instance is represented by a IDebugTarget object and its children (the implementation is your responsability); this is created by the LaunchDelegate and "attached" to the remotely running process at launching time.
The remote side, the interpreter or program you are actually debugging, can be anything: a binary executable, a perl script, some app running in a some site (perhaps also a local Java program; but, even in this case, this would probably run in its own JVM, not in the debugging Eclipse JVM!). Your IDebugTarget object must know how to communicate to the "remote interpreter" (eg, by TCP) and perform the typical debugger tasks (place breakpoints, step, run, ask for variables, etc) - but the protocol here is up to you, it's entirely arbitrary.
What is not arbitrary is the hierarchy of your custom classes that the running Eclipse debugger will use: these should have a IDebugTarget as root, and should implement "The debug model" (see figure in article). As said above, the IDebugTarget object is who understands how to make the translation between the EClipse side and the remote side (see this image)
having worked on the eclipse edc debugger, it sounds like writing a whole debugger is not so much what you want.
it sounds like while running the debugger, you will have access to the objects that have the variables and scopes you are interested in.
you can use toString() in the classes themselves or use detail formatters to display a variation on the information you want. the toString() call can get quite detailed and nest into calls, show whole arrays, etc. detail formatters can also be quite complex.
see http://www.robertwloch.net/2012/01/eclipse-tips-tricks-detail-formatter/ . it's the best of several URLs (i have no association with the author).
once you are happy with the output of the Variable and Scope objects, you should be able to add watch expressions that will always show them in your expressions window (thus you don't have to rely on local variables in the stack frame you may be in).
this should then give you the list of Variables and Scopes from your framework that you are tracking … hopefully without having to write an entire eclipse debugger plugin to do so.
ok, i'm going to add a second answer here … i guess i'm not familiar enough with the state of your environment to know why custom detail formatters would not do the trick. for most cases, i think they'll provide you what you're looking for.
but if you're really interested in creating another view holding these items, then you could check out the eclipse jdt project . it's entirely possible that the extension points it provides will give you access to the internal variables and stack-frame information that you're looking to add, and also perhaps some UI that will make your job easier.
in other words, you might not have to write an entirely new debugger plugin, but perhaps a plug-in that can work together with jdt.
the site has pointers to the project plan, source repositories, the bugzilla issue tracking database (used for both bug-tracking and new feature discussion). perhaps some of those who are experts on jdt can help weigh in with their opinions about what will best suit your needs.

Creating code template that evaluates newly created var

I am writing a lot of unit tests these days. And I want to minimize the amount of typing I have to do.
So I have created several Eclipse coding templates.
Most of them work fine. But, recently I want to do a bit more advanced stuff.
I use EasyMock and when writing expectations , I find myself writing stuff over and over again. I want a code template that is context-aware of the objects, and once selected, i want it to present me with the methods of this object.
So far, I have this template, and it works fine (it shows me all objects that are in my test):
EasyMock.expect(${a:var}.${cursor});
It will write me the EasyMock.expect part, and then present me with a list of objects I can select. Once selected, I get a dot and the cursor at the right, so all I need to do is press CTRL-SPACE in order to see the methods of this object.
What I want is to be presented with this list of methods.
Is this possible? And if yes, how? I can't find any solution. Perhaps there is no such template variable yet?
EasyMock.expect(${a:var}${cursor});
And then type a dot after selecting it (instead of pressing ctrl-space), which will automatically trigger content-assist

Correct way to use Actions to create menus, toolbars, and other components in Java

The naive way of writing building a menu in a Java Swing app is to do something like:
JMenu fileMenu = new JMenu("File");
JMenuItem openItem = new JMenuItem("Open...");
openItem.addActionListener(new ActionListener() { /* action listener stuff */ } )
fileMenu.addMenuItem(openItem);
A more experienced developer will recognize that actions can be accessed through a variety of mechanisms - menus, toolbar buttons, maybe even other workflows in the system. That person is more likely to write:
Action openAction = new AbstractAction();
openAction.setName("Open...");
openAction.addActionListener(new ActionListener() { /* action listener stuff */ } )
...
JMenuItem openItem = new JMenuItem(openAction);
My question is, what is the best way to manage these Action objects so they can be used across menus, toolbars, etc?
Create a factory class that returns specific actions?
Declare all of the actions as private static final Action in some utility class?
Take advantage of a Java application framework?
Something else?
Applications that I have developed that need to use that same actions across menus, toolbars, and other buttons have been done using Swing Application Framework.
Swing Application Framework
This framework will allow you to have a resource file where you can define all menu text, tooltips, and ICONS. I think the icons are the key, you do not have to load them yourself. Also, if you have any actions that you need to enable/disable you can override the method to control its state.
The website is worth the read.
You can group all your abstractAction using the dedicated Map javax.swing.actionmap .
See http://java.sun.com/javase/6/docs/api/javax/swing/ActionMap.html
Moreover each JComponent has an internal actionMap (getActionMap()).
class MyComponent
extends JPanel
{
public static final String ACTION_NAME1="my.action.1";
public MyComponent()
{
AbstractAction action= new AbstractAction() { ... }
getActionMap().put(ACTION_NAME1,action);
...
menu.add(getActionMap().get(ACTION_NAME1));
}
}
Hope it helps
Action is a bad abstraction - an ActionListener welded to a poor man's Map.
Certainly do not assign them to a static as they are mutable and also need some context to operate usefully.
My general advice for GUI programming is to note that it is actually much the same as any other area of programming. Follow the usual good practices. Notably, layering, separation of concerns, use (implementation) inheritance rarely and don't write a big ball of mud.
Also see this question, which is pretty much the same as what you're asking.
Create a base action for your application; this will help you IMMENSELY later on
Do create actions as you have in your code, instead favor subclasses of your base action
To organize them, it will depend on what you are doing with them, and you may have some actions organized one way and others created a different way. It will all depend.
What you want is to have a consistent way to locate/create an action in your code.
Depending on your UI, you may need to differentiate between "static" actions (i.e. stuff that's always available in your app, such as the menu system) and dynamic actions that are created only on certain screens or in certain locations.
In any case, using concrete subclasses of your specialized base action will help you keep these things organized. What you don't want is to be specifying things like labels, mnemonics, and icons all over the place in your code.
Edit: I got the feeling people didn't believe this was possible or easy, so I did it--took about an hour from scratch--would have taken 40 mins if I'd just used a single method as a target instead of reflecting it out to separate methods for each menu item.
Here's the Tested source code. It works, but is one big method and ugly--refactor it if you use it. I may fix it up a little over the next few days, I've always wanted to have a copy of this to keep around to reuse.
--- original post
First of all, remember to separate your code from data. That means you should NEVER type:
new Menu("File...");
The string "File..." is data. If you start thinking this way, you will find that your question answers itself.
First you need to build up some data. You need to get "File..." and "Save" into menus. I generally start off with a string array (which you can easily move to a file)
new String[]{"File...","+Save","Load"...}
This is one of the simpler patterns I've started out with. Then you can parse out the + sign and use it to mean "Drop down a level in the menu when you add this one"
This is just a silly convention, invent your own if you don't like it.
The next step is binding that to code to run. You could have them all call the same method, but what a pain in the ass (Giant switch statement). One possibility is to use reflection to bind a method name while you are reading in the data. Here's one solution (again it might not fit your tastes)
new String[]{"File...[fileMenu]","+Save[saveMenu]","Load[loadMenu]"...}
Then you parse out the thing in square braces, reflectively hook it up to a method in your current class and you are set.
There is a temptation I ALWAYS have at this point, and I've learned to fight it because it NEVER works out. The temptation is to use the first set of data ("File...") and manipulate it to fit some pattern and auomatically bind to your code (in this case, remove all non-alpha chars, make the first letter lower case and append "Menu" to get the correct method name). Feel free to try this, it's very attractive and seems slick, but be ready to abandon it when it doesn't meet some need (such as two menu items with the exact same name in different sub-menus).
Another way would be if your language supports closures, then you could actually create the file name and closure in the same place..
Anyway, once you start coding like this, you'll find that ALL your menu construction is in a single 10 line method and you can alter it to suit your needs. I had a case where I had to change a set of menus to a button hierarchy and I did it in 2 minutes.
In the end, you can use this pattern to set up the action objects easily and change how they are used easily (in a single location, single line of code), so you experiment with them. There are many ways to use them, but if you don't do what I'm recommending here, you will end up having to re-implement across every menu item for every change, which is really annoying--after a single change you will have wasted more time than if you had just implemented a data-driven solution in the first place.
This really isn't hard code, should take like an hour or two then you never have to write new Menu("... again. Trust me, this kind of tooling is just about always worth it.
edit:
I just about always code data-driven these days. Usually I'll prototype a few things the normal way, recognize the pattern and refactor--and if you are refactoring correctly, the data just about always factors out and what you're left with is beautiful, tight and maintainable.
I could do what I suggested above in less than 1/2 an hour (maybe an hour to do the reflective version). This is almost always just as long as it would do to use the unfactored version, and from then on, your savings multiply for every change.
This is very similar to what people like about ruby, except with ruby they seem to insert even more data into their code (which makes it awfully hard to extract your data from the code completely, which is always a nice goal for internationalization).
Hmm, did I mention that if you're good at extracting your data like this, i18n is virtually free?
I suggest you just give it a try sometime and see what you think. Embedding the control in the strings is unnecessary if it makes you uncomfortable. I tend to use string/object arrays just because they are really easy to enter, are still in the file while you are coding and are trivial to externalize later, but if you like YML or XML or properties files, use whatever you're comfortable with--just abstract your data from your code!

Categories

Resources