I have recently written my first Android app which was roughly 8,000-10,000 lines of code. One thing that continuously hindered my use of normal design patterns was android's heavy use of asynchronous calls (opening dialogs, activities, etc). Due to this, my code very quickly began looking "spaghetti" like, and I eventually started to dislike looking at certain classes.
Are there specific design patterns or programming methodologies which are for systems such as these that anyone would recommend? Are there any suggestions for writing manageable asynchronous code?
Use global variables
If you do not want to mess up your code with simple Intent.putExtra() calls and manage this things for each unique Activity you'll have to use global variables within the application. Extend Application and store data that you need as long your application is alive. To actually implement it, use this excellent answer. This will make dependencies between activities disappear. For example, say that you need a "username" for your application during the application's life cycle - this is an excellent tool for just that. No need for dirty Intent.putExtra() calls.
Use styles
One common mistake when making the first Android application is that one usually just start writing the XML views. The XML files will (without problem and very fast) go up to very many lines of code. Here you can have a solution where you just use the style attribute to implement a specific behaviour. For example, consider this piece of code:
values/styles.xml:
<style name="TitleText">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:textSize">18sp</item>
<item name="android:textColor">#000</item>
<item name="android:textStyle">bold</item>
</style>
layout/main.xml:
Now, if you have, let's say, two TextViews and both of them should have the same behaviour, make them use the TitleText style. Sample code:
<!--- ... -->
<TextView
android:id="#+id/textview_one"
style="#style/TitleText"
/>
<TextView
android:id="#+id/textview_two"
style="#style/TitleText"
/>
<!--- ... -->
Simple and you don't need to duplicate code. If you really want to look further on this particular subject, please look at Layout Tricks: Creating Reusable UI Components.
Use strings
This point is short but I think it is important to mention it. Another mistake that developers might do is to skip the strings.xml and just write UI messages (and attribute names) inside the code (where he will need it). To make your application easier to maintain; just define messages and attributes in the strings.xml file.
Create and use a global tool class
When I wrote my first application I just wrote (and duplicated) methods where I needed it. The result? A lot of methods that had the same behaviour between various activities. What I have learned is to make a tool class. For example, let's say you have to make web requests in all of your activities. In that case, skip defining them inside the actual Activity and make a static method for it. Sample code:
public final class Tools {
private Tools() {
}
public static final void sendData(String url,
String user, String pass) {
// URLConnections, HttpClients, etc...
}
}
Now, you can just use this code below in your Activity that needs to send data towards a server:
Tools.sendData("www.www.www", "user", "pass");
However, you get the point. Use this "pattern" where you need it, it will keep you from messing up your code.
Let custom classes define the behaviour where the user needs to interact with your application
This is probably the most useful point. To just define "where the user needs to interact with your application" let's say you have a Menu, which behaviour is very long in terms of lines, why do we keep the Menu's calculations in the same class? Every little item will make your Activity class a painful piece of code longer - your code look like "spaghetti". For example, instead of having something like this:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item;
item = menu.findItem(R.id.menu_id_one);
if (aBooleanVariable) {
item.setEnabled(true);
} else {
item.setEnabled(false);
}
// More code...
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem i) {
// Code, calculations...
// ...
// ...
return super.onOptionsItemSelected(i);
}
redesign it to something like this:
private MyCustomMenuInstance mMenuInstance;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMenuInstance = new MyCustomMenuInstance();
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
mMenuInstance.onPrepareOptionsMenu(menu);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem i) {
mMenuInstance.onOptionsItemSelected(i);
return super.onOptionsItemSelected(i);
}
For example, MyCustomMenuInstance:
public class MyCustomMenuInstance {
// Member fields..
public MyCustomMenuInstance() {
// Init stuff.
}
public void onPrepareOptionsMenu(Menu menu) {
// Do things..
// Maybe you want to modify a variable in the Activity
// class? Well, pass an instance as an argument and create
// a method for it in your Activity class.
}
public void onOptionsItemSelected(MenuItem i) {
// Do things..
// Maybe you want to modify a variable in the Activity
// class? Well, pass an instance as an argument and create
// a method for it in your Activity class.
}
}
You see where this is going. You can apply this to many things, e.g. onClick, onClickListener, onCreateOptionsMenu, the list is long. To learn more "best practices" you can see some sample applications from Google here. Look for how they've implemented things in a nice and correct way.
Last word; keep your code clean, name your variables and methods in a logical manner and especially in a correct way. Always, always understand where you are in your code - that is very important.
From an amateur perspective, I don't expect my first attempt to be a clean, production-ready app. I end up with spaghetti, fettucini and even ravioli code sometimes. At that point, I try to rethink what is what I dislike the most from the code, and search for a better alternative:
Rethink your classes to better describe your objects,
keep the code in each method to a minimum,
avoid dependencies to static variables anywhere you can,
use threads for expensive tasks, don't use them for quick procedures,
separate the UI from the app logic (keep it in your classes instead),
keep private fields anywhere you can: it will be helpful when you want to change your class,
iterate through these until you like the code
One of the most common errors I've seen in asynchronous methods is to use a static variable inside a loop that creates one or more threads, without considering that the value may change in another thread. Avoid statics!
As OceanBlue points out, it may not be clear from this that final static variables do not create any danger, but public static variables that can change. It is not a problem with the statics themselves, but with the notion that they will have a value and then find out that the value changed. It may be difficult to spot where the problem was. Typical examples would be a clicks counter or a timer value, when there could be more than one view clicked or more than one timer.
Hopefully you will receive suggestions from people with much more experience than me. Good luck!
If handling the the UI is your biggest concern, then you'll want to master event-driven coding. The ideas behind event-driven coding are behind all modern UI systems, and are useful in all kinds of things (not just UI).
The easiest way for me to think of it when learning was simply to treat each component and event as if it's self-contained. All you need to worry about is the event object passed into your event method. If you're used to writing applications that run basically from beginning to end, it's a bit of a mind shift, but practice will get you there pretty quickly.
What about using the Model View Controller pattern?
At least you have to isolate in the "model" (object or set of objects)
all the state and its logical management, and have in
a separate class (maybe the Activity class)
all the stuff related to the views, listeners,callbacks, ...)
Related
(I'm a beginner)
What is the recommended/cleanest/most efficient way of implementing features that can be toggled on/off by users?
I'm planning to add some features to my app that the user can toggle on or off in a Settings page. E.g., haptic feedback when tapping certain Views. In my code, this View has a onClickListener that executes the haptic feedback and some other methods. In the Settings page for my app, I'll put something like "Enable haptic feedback" with a Switch. Example
The first idea that comes to mind is just putting if wherever the vibrate method is called. Something like...
myView.setOnClickListener(new View.OnClickListener) {
if (hapticsSwitch.isEnabled) {
vibrate(10) //10 ms feedback
}
//more methods...
}
However, this if would need to be repeated whenever I call any toggleable feature in my app. So perhaps a cleaner way would be putting this if inside those features' methods. E.g.
public void vibrate(Long duration) {
if (hapticsSwitch.isEnabled) {
// ...
}
}
But I have no experience with toggleable features. So, what is the recommended/cleanest/most efficient way of implementing toggleable features into my code?
That is a very nice question and its not specific to toggle, but to "single level of abstraction" as uncle bob calls it.
In my opnion the right thing to do is to put it inside the vibrate function and inside any function that is influenced by that parameter.
There are 2 things you should consider:
Does Vibrate(long duration) can do its job well without hapsticsSwitch. I think the answer to that is no and it will work well only if its caller did the if statement you suggested, other developer can easily fall in that pit and create a bug
How easy it will be to change that logic when this condition will be changed from only looking at hapsticsSwitch && newFeaturehow many changes will you have to make. In my opinion it will be nuch harder to go over all the callers of vibrate.
Final note, I think you might want to use the vibrate without the condition in your app it does not mean you should move the of statement from vibrate(Long duration) to its caller, but you need to split your functions to something like vibrateIfNeeded(Long duration) and vibrate(Long duration) function that vibrate if needed will call.
Tip: read the book called "clean code" by robert c. Martin
I'm making a prototype for a videogame using Java (I plan on porting it to Unity later, but since I'm pretty comfortable with Java, I figure it'll be quicker to get an idea for the structure and basic components of my game in Java). Perhaps ironically, however, I have some doubts about how to do this thing in Java.
What is the best way to collect key presses? I know about KeyListeners and how to use them, but they don't seem ideal. I would like to be able to call a keyPress() method once every update cycle (at the beginning of the cycle, specifically) for precision reasons–I have information being updated each cycle and I want it to vary depending on which key is pressed–I realize that being even a couple of frames asynchronous isn't a huge deal, but immediacy of response is pretty important in making the game play well, I feel. I also don't want to be individually alerted every time a different key is pressed, but ideally, I'd like to generate a kind of list of which keys are pressed at any given moment (the game input consists of specific keystrokes, and so at any moment, I want to know what the active keystroke is). There's also other issues, regarding the timings when game events happen that make being synchronized to within 3 or 4 frames pretty important. It is less important that each cycle run fast than it is that I get the response to keys at the beginning of the cycle.
Is there way to do this? If there is, is it a good idea? Would it be too slow to expect any kind of consistent gameplay if I run this every update cycle (I'd expect it might even be faster or at least lighter than a listener)? Are there other places where this could wrong?
Thanks
first you should look at your gameplay.
The use of events will not problem for you. And code disorder and event control make it difficult.
There are many solutions to this. At first, did you used any frameworks (like the Libgdx)? if yes. this is handle, Otherwise you can go yourself.
One way to use "Message Handling". in this solution,You can write the code below.
public interface Telegram {
public boolean handleMessage(final Telegram msg,Object yourObject );
}
public class MessageHandler {
private static Map<String,List<Telegram>> telegramKeyMap = new HashMap<>();
public static void addTelegram(String key,Telegram telegram){
List<Telegram> telegramList = telegramKeyMap.getOrDefault(key, new ArrayList<Telegram>());
telegramList.add(telegram);
}
public static void dispatchMessage(String key,Object addVal){
List<Telegram> telegramList = telegramKeyMap.getOrDefault(key, new ArrayList<Telegram>());
for (Telegram telegram : telegramList) {
telegram.handleMessage(telegram,addVal);
}
}
}
public class Player implements Telegram {
public Player() {
}
#Override
public boolean handleMessage(Telegram msg, Object yourObject) {
return false;
}
}
in this code you can implement Telegram for any classes. then on the listeners call dispatchMessage. for input you can used any Objects(like Listener, keyCode,...)
dispatcher fine any object with this key, them call handleMessage method. Now, each of your objects can handle their work.
second solution : Use "Event Management"
If the first option does not resolve your problem, then I'll take the second solution to the sample code. The message handler is used in most game engine engines, and it does increase the speed of the game, but it's opening up your hands sharply.
How should Listeners etc be managed? I've found only examples with one button etc.
I can think of following options:
Extra class for each - doesn't seem right, especially when items
can be created dynamically
Class for each group (such as form1,
form2, controlButtonsOnLeft, controButtonsOnRight, mainMenu,
userMenu, ...) where I'll check which button/component caused this
(via getSource method for example)
Some super (sized) controller,
which will accept all user actions
New anonymous class for each,
which will call controller's method with parameters specifying
details (probably enums)
And another question: I've found many examples for MVC, I was wondering what is better (or commonly used) for app. developed by 1 person (app will not be huge)?
A. Viewer sets listeners to controller (A1-3)
B. Controller calls viewer's methods, which accepts listener as parameter (methods addLoginSubmitListener, addControlBoldButtonListener etc)
All of above are possible to implement and so far I would choose B4.
Meaning in Control I would do something like this:
...
viewer.addLoginButtonListener(new Listener()
{
#Override
public void actionPerformed(ActionEvent e) {
...
someButtonsActionHandler(SomeButtonEnum, ActionEnum);
...
}
});
...
private void LoginActionHandler(LoginElementsEnum elem, ActionEnum action)
{
if (elem.equals(LOGINBUTTON)) {...}
...
}
...
This combines readable code (1 logic part at one place in code), doesnt create any unwanted redundant code, doesnt require any hardly-dynamic checks, is easily reusable and more.
Can you confirm/comment this solution?
To be honest the question comes down to a number of questions...
Do you want reusability?
Do you want configurability?
Are they self contained? That is, does it make sense for anybody else to listener to the component or need to modify the resulting action of the listener in the future?
Personally, I lean towards self containment. A single listener for a given action/task. This makes it easier to manage and change should I need to.
If I don't need reusability (of the listener) or configurability, then an anonymous inner class is generally a preferred choice. It hides the functionality and doesn't clutter the source code with small, once use classes. You should beware that it can make the source code difficult to read though. This of course assumes that the task is purpose built (its a single, isolated case). Normally, in these cases I will prefer to call other methods from the listener that actually do the work, this allows a certain amount of flexibility and extendability to the class. Too often you find yourself wanting to modify the behaviour of a component only to find that behaviour buried within an anonymous or private inner class...
If you want reusability and/or configurability - that is, the listener performs a common task which can be repeated throughout the program or over time via libraries, then you will need to provide dedicated classes for the task. Again, I'd favour a self contained solution, so any one listener does only one job, much easier to change a single listener then having to dig through a compound list of if-else statements :P
This could also be a series of abstract listeners, which can build functionality for like operations, deleting rows from a table for example...
You could considering something like the Action API (see How to Use Actions for more details), which are self contained units of work but which also carry configuration information with them. They are designed to work with buttons, such as JButtons and JMenuItems, but can also be used with key bindings, making them extremely versatile...
The second part of you question (about MVC) depends. I prefer to keep UI related functionality in the view and out of the controller as much as possible. Instead of allowing the controller to set listeners directly to components, I prefer to provide my own, dedicated, listener for the controller/view interaction, which notifies the controller of changes to the view that it might like to know about and visa versa.
Think about it this way. You might have a login controller and view, but the controller only cares about getting the credentials from the view and authenticating them when the view makes the request, it doesn't care how that request is made from the views perspective. This allows you to design different views for different circumstances, but so long as you maintain the contract between the view and the controller, it won't make any difference...But that's just me.
I have a dialog, which have four buttons say New, Save, Delete, Cancel. Now each of these need to perform their action. So I have defined a separate class which implements an ActionListener. I have used this class to perform each of the button action.
public class MyClass implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().toString() == "OK") {
// Code
} else if( .. ){
}
}
}
What I have done is, I defined an inner class which I used to do the same functionality. But what I was not getting is, is it best practice to write a separate class or is it best to use inner class. I was suggested to write in a public class so tomorrow some one can use this class to perform their action. So I have the following questions,
If the functionality is not called by any object (which I can't say) then I can write it in inner class? OR
Is it a good practice always to write inner class which performs the actions of that dialog?
There is no general answer to these questions. If the code in actionPerformed() is one line, writing a whole class file is usually overkill.
If the code is more complex, it might be suitable to reuse but as the code grows, it also gets more specific (so you can't reuse it anymore).
Try to follow this approach:
Build your application from simple blocks that are independent of each other.
Configure the application by writing code that connects the blocks.
So in your case, you could have helper methods which do the work. Wrap them in Swing Actions; this allows you to use them in all kinds of buttons and menus.
Try to move as much work as possible into the helpers so that the actions become really simple. If in doubt, ask yourself: Is this code part of the work? Does everyone need to do this?
If yes, then the code should go into a work/helper class.
If it's things like UI related checks (visible/enabled), conversion (string to number), validation, etc., it should go into the action.
When you talk about defining an inner class for a GUI listener, I think immediately of using anonymous classes to do the job:
newButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// do the work for a button press
}
});
// similarly for save, cancel, delete buttons:
saveButton.addActionListener(
new ActionListener()
{
// ...
You'll often see this, and I often use this in my own code.
Which you use depends on the structure of your code, for instance:
how much work each listener needs to do
how much code is shared between the handlers
If each handler is short (e.g. just one method call, with all the real work handled within another class method), I'll use anonymous classes this way. But it does look goofy: unfortunately java requires us to define an object to employ a callback method.
It's also a matter of personal preference and coding style.
However, I'd rarely make a new top-level class for a GUI handler as in your example: even if I separate out the class so that I use the same class for each button, I'd define the class within the class file controlling the buttons, either as a non-public top-level class, or as an inner (non-anonymous) class. If the complexity of a GUI callback grows to the point that it deserves a separate class, I'd start looking for places to refactor.
proper way should be Swing Action(mentioned in comment by #Robin), for JButtons Components as most scalable choice, with implementations of interesting methods
most complex GUI is there way to add EventHandler, which fired event and could be compare in String value
Greetings,
I'm currently developing an Android application, but I'd like to be able to handle button click events etc in a separate file for each Activity. Is this possible? At the moment, I have one very large file that handles all events for several Activity windows.
Any advice greatly appreciated.
Thanks in advance,
For event handling there is OnClickListener interface, you can create your own implementation and use it only in place you get the button, for example in onCreate():
#Override
public void onCreate(Bundle savedInstance) {
...
Button btn = (Button) findViewById(R.id.ok_button);
btn.setOnClickListener(new onClickListener() {
#Override
public void onClick() {
// the code
}
}
So, you don't have to create a separate file at all.
What you are trying to do is not possible (at least in a clean way).
To handle a click, you must implement one interface (View.OnCLickListener). I'm assuming clicking in a different view will produce a different type of response (i.e. one button might open a popup and another might start an activity).
Yes, you could check the id of the view that was clicked and decide what to do based on that.. but this looks like ugly!
In order to accomplish code reuse, usually I implement everything in a inner class. This way I can choose what to do in each case just once.
If you've done something very general, you might do it in a separate file so you can reuse it in other classes.
I think you should spend a little time familiarizing yourself with the basics of object orientation before you go further - you are doing yourself a disservice because without the basic understanding, you are probably going to write a ton of code that in the end, wouldn't be needed if you had the basic understanding. Pick up a beginning Java book or do a tutorial or two online - you will be glad you did.
And I hope you don't take my advice to be picking on you - I am simply telling you that your question indicates you don't know the basics.
Now to answer your question... You want to create a single class that implements all the shared event handling logic (shared code means only the code that all activities will use). You will then use this shared event handler from each of your Activity classes by making your activity classes either an IS A EventHandlingClass or HAS A EventHandlingClass. Now its up to you to find out what IS A or HAS A actually means, and when you do, you will then have the basic understanding of object oriented languages.
Good Luck!
Rodney