What is the best way to avoid having lots of code in the main.java file when writing android apps.
it seems i will have to switch the views constantly all running through the main java file and having worker services fireing events.
am i missing something or is this how it is meant to work?
Without more information, this is unanswerable.
The best advice now is to read the android dev guide. There is a section of best practices. You can take a look at: http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html and http://developer.android.com/guide/practices/design/performance.html
Think about putting some code in separate threads also: http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
It's hard to understand what you mean by services firing events. The android UI is meant to be coded as objects receiving and dispatching events, and the app should respond to those evens accordingly.
Depends what kind of app you have.
Normally, different "screens" are handled by separate Activities. Activities normally handle user input and take part in history stack (handling moving forward/back between activities and apps).
Views in Android are classes responsible for rendering parts of the screen. ViewGroups contain Views (and other ViewGroups) and are the basics of view hierarchy. View hierarchies are usually defined declaratively via XML, no coding required.
Services are code that run in the background without UI.
Recommended programming model is to program asynchronously: register handlers and code will be called when events happen. This is used not only for UI, but also for broadcasts, gps, alarms, data download, sync manager, notifications, etc..
So, Android apps are usually quite short - a 1000 lines app can already do quite a lot. Also, they tend to be nicely partitioned into distinct classes.
Related
How can I control life cycle of QML forms (I mean windows)? I am talking about onCreate, onResume, onPause etc. methods on Android or life cycle of views on iOS. And Can I work this life cycle of QML forms on Android, iOS, Windows 10 Mobile, desktop etc.?
Design of Qt Quick (QML) applications is different from Android ones. There is no difference between views and objects like Button, Text, etc. Every QML object with graphical representation inherits Item and it is possible to define Component.onCompleted and Component.onDestruction functions. They will be executed once object is created and destroyed. If you also need a pause signal I suggest creating functions pause() and resume() in every view you create and create an object that will manage the views - create, destroy, pause and resume them.
Please notice that you need to take care of transitions between views and states yourself. Also as you can create your own QML objects it is worth considering creating a template of a view and then only inherit it.
This will work with every system you deploy the app on.
If you have more questions, need example etc. consider editing the question or leaving a comment.
I want to thank BaCaRoZzo once again for useful tips. I added them to this answer.
I have created an example project that tries to mimic Android app life cycle. This will work with every OS. This is just an example but I think that similar approach may be used in release source. However, first you need to understand the nature of the QML. This is high level language that is already being managed by some other process. It is far different from Java. For example take a look at the fragment of the docs about a state used by background processes:
A Qt Quick application should not usually handle this state at the QML
level. Instead, you should unload the entire UI and reload the QML
files whenever the application becomes active again.
So if I were you I would only save sensitive data when I detect application is going to background. No need to try and unlod views etc. It would be needless uphill struggle becuase QML is not designed for this. Instead let your app be killed if OS needs more memory.
You can find the example project here. You can use it if you want. It contains comments to let you better understand what is going on.
Many Android apps include a BaseActivity class of their own, which all Activities in the app extend. This is useful because it gives a central place to put functionality that's common across most/all activities. The main drawback of having a BaseActivity is you are then unable to use any of the Activity subclasses (ListActivity, etc.).
One alternative is to have an ActivityDelegate. This gives a central place for functionality while still allowing you to use Activity subclasses. It's also arguably more testable, since it uses composition instead of inheritance.
Both of these solutions potentially lead to a lot of spaghetti code when the BaseActivity/ActivityDelegate gets too large and convoluted. A possible solution to this is to use the delegate pattern, but split the functionality into many different Delegates. This reduces spaghetti code in the Delegates, but then the Activities get more complicated - they're now trying to forward their on* methods to lots of different Delegates instead of just one.
A possible solution to all of these problems is to use a Delegate Manager. The Delegate Manager keeps track of all the smaller Delegates in the app. Activities forward their on* methods to the Delegate Manager, which forwards them on to all of the individual Delegates. This accomplishes all of the following:
Dedupes code - all common functionality gets placed into one of the Delegates
Allows use of Activity subclasses
Simple code in all Activities - all on* methods are forwarded to just one class
Easily testable - it's simple to mock out everything around the Delegates and the Delegate Manager for unit tests
Has anyone tried using this pattern before? If so, how did it go?
As far as I understand, you're talking about one single DelegateManager object for the entire application. If this is the case, you can use registerActivityLifecycleCallbacks, see http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29
If you're on < API level 14 you need to take a look at: https://github.com/BoD/android-activitylifecyclecallbacks-compat.
registerActivityLifecycleCallbacks lets you hook into the activities onXXX lifecycle methods.
Doing this certainly has all the benefits you described:
decoupling being usable only when you actually need to repeat behavior which is kinda seldom for controller+view logic tied in together the way Activity works.
Removing inheritance is nice if you have activities you might reuse - but I've never had to do it before. But I guess a good use-case would be your home-cooked activity for handling settings or something like it that needs app-wide L&F & behavior.
On the top of my head I can think of these downsides:
Using listeners all over the place can blur path of the application activity/call hierarchy and can make the code hard to understand. This holds true for all listener/dispatcher type of programming. It's a powerful tool, but handle it with care.
It can introduce a lot of (as you mention) boilerplate/spaghetti code if all you do is pass on to lifecycle listeners/delegates.
it is your responsibility to de-register yourself from the Application with Application.unregisterActivityLifecycleCallbacks. I don't think there's a good way around it,
Personally I haven't used this design-pattern much for lifecycles, but it might be worthwhile for some use-cases. For example:
ApplicationLifecycleLogger: Every time you create/resume/pause... an activity, you logcat or something else making debugging lifecycles a tad bit easier.
If for example someone goes into an activity he/she is not allowed to go into due to model state of some sort (e.g. a ringing alarm -> can't go into AlarmEditActivity), you could do finish() there.
Passing object state across activity boundaries without Parcelable:s and screen rotation changes. Usually this is implemented with a Map in Application or some static field somewhere. You can do this by letting the delegators hold state.
Also, take a look at: Is there a design pattern to cut down on code duplication when subclassing Activities in Android?
I hope this was helpful =)
If I want to make a request from an Android device to a remote service, I can use AsyncTask, AsyncTaskLoader, Intent, etc to make the a request apart from the UI thread. It seems there are a lot of options, but I am confused how to choose among them. Could you explain when and which to use? Also, are there any other options besides the ones I have mentioned?
This is an extensively discussed question, since Android provides a long list of mechanisms capable to handle service calls asynchronously, besides the one you mentioned there's also:
IntentService
Native Threads
Now, the key point in your question is "When to use it" and here would be my answer:
In software the only golden rigid rule is the "It depends rule", there's no hard rules for anything in software development there's always different ways to approach a problem in software (i guess that's the reason of the word "soft" in it...) and that's exactly why it always depends, it depends on whatever you need and although one approach might be the most common way to do it like for example "AsyncTask" it doesn't mean at all that AsyncTaks is always the way to go, it always depends on the factors and needs that affect your functionality. There's plenty of things that nowdays get executed using AsyncTaks when maybe all you need could be just a regular common Native Thread.
The only way to be able to make a decision towards the most appropiate approach would be knowing ALL the features around a tool, like for example most people 90% of the time use AsyncTaks just to run doInbackGround on separate thread, but might not even need preExecute, publishProgress, postExecute, etc, and that's something a Regular Thread could do, just like this example there's features for every single object provided in order to do remote calls, however as i already mentioned several times, it all depends on what you need and what tool fits better your needs. Remember there's no hard coded rules for "How, When, and What" to use in software, IT ALL DEPENDS, and making good decisions in that "DEPENDS" makes the difference between good developers from excellent developers...
This is a list of things i usually take on count to implement either one way or another, this list do not apply for all the scenarios but might give you an idea.
AsyncTaks- I know is a good idea to make use of asynctaks when the functionality needs to be monitored, by monitored i mean, i need to keep track of progress during my job, like (download/task progress), because that's exactly what the AsyncTask was originally created for, it was created attached to "The Task Pattern", and if i don't need to make use of at least two methods for monitoring provided by AsyncTaks like onPreExecute,onProgressUpdate, onCancelled etc. I know there might be another way to implement it.
Native Java Threads - I know is good to make use of this tool when my task is not related to any view in android at all, and do not need to be monitored (example: removing/adding data from remote database, and the response might affect just persistence elements that will not be displayed like configuration preferences)
IntentService - When i want to do a one time task in a queueprocessor fashion way, but unliked a native thread, here i would like to have some application context in order to maybe bind an activity etc...
Regards!
I've been coding for my Android phone lately, and i've been wondering... is this Intent class supposed to outline a new programming style?
I've been suspecting the API design discourages MVC: Intents are the main way to interact with all user-related objects (Activities, Services, Other apps...).
Is my train of thought right? Should is stick to "contaminating" Activities with business logic?
I have been reading the android developers site and no particular coding style is encouraged though.
Your question isn't entirely clear, because you seem to be confusing coding style with program architecture.
In my mind, Android really changes nothing in terms of coding style. Your coding style from Java will still work fine, and most Android apps look very similar to other apps. In the abstract, there are some things that you might want to do in Android you don't do as much in other languages, see the Android guide for details. The basic idea is: memory is limited, don't use it if you don't have to.
As far as whole program architecture goes, yes, the Android style is highly based around the message passing (through Intent objects) style. The way you react to GUI events within an Activity is still largely the same: you use event handlers to react to events like button presses, etc... But the platform is strongly centered around designing apps using different components (Activities, Services, BroadcastReceivers, etc...) and Intents to communicate between them. While Intents provide a flexible way of exchanging data between components, you still shouldn't be passing massive amounts of data within Intents, instead you should put those kinds of things in a ContentProvider or something similar.
I took a lot of the following ideas I took from this OReilly book. This is just whats worked best for me.
As far as architecture goes, its helped me to think of Android's UI as a Page Controller pattern - I found it to be similar to .Net Web Forms actually. So yes, it does fit with MVC (at least the Page Controller flavor of it). An Activity is your controller, you typically store your view in XML, and you can build out your Model however you like.
You see a lot of web-ish ideas in Android. Intents are a lot like HTTP, or more generally REST. Intents have a 'noun' that says what they are concerned with (can be explicit class declaration ie: go to a specific Activity, or can be more implicit using Intent Filters), the Action is a lot like an HTTP verb (Get, Post, etc), a Bundle is a lot like a list of query string parameters or payload...etc.
And similar to a web page, you want an Activity to be able to take care of itself. What I mean is, you don't want to pass around some big serialized object from activity to activity, its a lot cleaner/resilient/reliable to just pass the id of the a given record to the next Activity and let that activity grab the record with that id from the db (ContentProvider, some other persistent source...). Activities are also meant to be loosely coupled, and you're supposed to be able to navigate to one from various paths, it also makes them more re-usable. Thus, allowing the callers of an Activity to simply provide a recordId is a lot easier then the Activity expecting its consumer to have provided a large serialized object.
Bottom line - no, you don't need to contaminate Activities with Business Logic, tuck that stuff away in an application layer, or a gateway or something like that. As for persistence, the ContentProvider interface is pretty well designed - I like it alot. It also continues the Android RESTful theme, accessing content via URLs and verbs (query, delete, update, insert).
Sending and receiving intends is much like sending and registering (similar to a publish-subscribe channel) for command messages (e.g. in a distributed enterprise application, and this is about architecture, not style). This pattern helps designing a loosely coupled system of interacting applications.
I cannot remember having seen a similar architecture before used for the interaction of components and applications on a single computer but it helps to design application using other applications to easily build an ecosystem of features/components.
I want to develop an application that supports plugins and that provides data to these plugins. It seems to me that the correct way to implement this plugin-archtitecture on Android would be one apk for the main app and one apk per plugin.
But as the main app and every plugin are in different apks I can't easily pass (data) objects from the one to the other, the applications run in different processes and even if they run in one process (which can be achieved) they have different classloaders and this doesn't work. Currently I see two promising approaches for getting data from my main app to my plugins:
Declaring the main app as a ContentProvider. This seems to me to be the intended approach because it does exactly what I want to achieve: providing content/data to another process.
Making my data objects Parcelable and pushing them around with AIDL or - if I do not need multithreading - with the Messenger-approach. In my opinion, this approach seems to be easier because I can use an ORM-library which cares about the Database in the background. I never used ContentProviders before but at a first look at it I thought that using a ContentProvider is a bit like building SQL-Queries by hand (please tell me if I'm wrong), and I would like to avoid that work!
Now I would like to know if I missed any pros or cons and if there are notable performance differences between these two approaches. And which solution would you prefer and why would you do so?
Thanks in advance! Any replies are appreciated!
Content provider is just way to share data (that are stored in different ways [database, files and so on]) between applications. If you want just share data between application it is the best way to do this.
However, if you want services to perform some tasks with data (for instance, sum several values provided by you) it's better to have a remote service.
In general case, application - plugin interaction is more similar to a remote service. In this case the main application exposes a remote service (an API of this application) that can be used by plugins to perform some actions.