Android rant



  • Just posting here a link to my rant on Android.
    Curious if you think what I said is sensible or if I got it All Wrong :tm:

    Oh, as a bonus, after the line is something I had written some time ago, Discourse failed to get posted and I though was lost.


    I'm dealing with Android, which is a real SPOS like I haven't seen for a long time and makes everything else look nice and shiny.
    I'm not even bothered to write about it (edit: I eventually did, see above), but here's a nice representative line.

    Actually, let's see how we get there, for fun.
    We have a MapView which represents a map (technically not part of Android, because yeah, whatever). We can't control it directly, we have to get a GoogleMap object (asynchronously) which actually lets us do stuff like add markers etc. Alright...
    We've done some other operations with that object. Now we want to show a certain place instead of the default view, let's say we have the coordinates of Paris.

    So, quick go with intellisense... (italic is suggested completion)
    map.moveCamera
    Ah, that looks promising... the camera must set how we look at the map, makes sense. I assume there's an overload that takes a location?
    map.moveCamera( CameraUpdate )
    Uh... only 1 method signature... it takes an object of type CameraUpdate. Ok, I guess I can contruct it with a location and some options?
    map.moveCamera(new CameraUpdate( not found
    Mmm no... no constructor. Ok, probably one of those classes that provide static methods to create new instances. Maybe fromSomething?
    map.moveCamera(CameraUpdate.from no matches
    At this point I try a couple more things and I'm like... ok, let's check the samples, surely it's something similar and I just...
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13));
    What. The. Fuck.
    A... FACTORY to create an object that defines that we want to move the map to a different location?


  • sockdevs

    @Zmaster said in Android rant:

    A... FACTORY to create an object that defines that we want to move the map to a different location?

    There's a reason for this meme:


  • area_can

    newLatLngZoom(sydney, 13)

    That signature is nothing like what I expected it to be...



  • On the other hand, I've started looking at how iOS development works and I wonder what kind of hellish dimension Swift has spawned from.
    From my point of view, none of the platforms are perfect and comes with different sets of annoyances. I'm sure I could write a similar rant about using maps on iOS and how incompetently built the entire OS is if I start working with it, being used to using Google Maps on Android and Android development with Java myself.



  • tl; dr



  • @Atazhaia Swift by itself (as a language) isn't so bad. Has a nasty habit of changing language keywords between versions though. Also, the toolchain has really poor support for reasonable compiler/runtime error messages. Most of the time you get dumped into assembly code and have to backtrack and do poor-man-logging (console printing) to figure out what's happening.

    The iOS framework API is...horrible. The stench of ObjectiveC hangs all over it and it's got that Apple mentality of "there is only one way to do X. Our way. No, we're not going to tell you what that is, but anything else will break horribly. And with cryptic errors."

    The other big problem with iOS development is XCode. Ugh.


  • area_pol

    @Zmaster

    My feeling is that on Androideverything it’s easy to do really basic stuff, but it gets exponentially more difficult when you try to get serious.

    Also, you seem to have a lot of problem with passing data between parts of your program, because the tools you normally use, like Singletons, don't work in Android.
    I only did a bit Android development long time ago, but I remember there were some different tools for that, like data-stores, sending messages between Activities, background tasks.



  • @Benjamin-Hall The syntax at a first glance seems weird, but I have mainly been using C-based languages with a dash of Python this far. According to what Apple is saying, Swift is combining the best of C/Objective-C and Python, though. The example code I have read has left me a bit confused however.

    And there's nothing like android.util.Log for iOS development? Really? Because that class is quite helpful when developing on Android.

    The other stuff I have mostly figured. The Apple mentality I have mentally prepared myself for and I know about all the fun that awaits in the world of Xcode. But I also have masochistic tendencies, so... :smiling_imp:



  • @Zmaster From your blog post, it seems like your real problem with Android is that you're using too many singletons. Yes, one is too many, not just Android, but anywhere. The only singletons that makes sense is things that are provided to your process by OS in quantity of exactly one - standard input and outputs, current time, process ID, and that's pretty much it. All the other uses - session data, logging, subsystems, factories - is just lazy programming and it bites the ass sooner or later.

    Unless said "factory" is just a bunch of static methods without any persistent state - but then it's not a factory, it's a bunch of static methods.



  • @Gąska said in Android rant:

    Yes, one is too many, not just Android, but anywhere. The only singletons that makes sense is

    Contradiction spotted



  • I've only worked with Android a little, but enough to figure out that part of the trick is that you must do things the Android way, or you will be in for a world of pain. It's Java, and it looks just like a full Java environment, so you might instinctively try to do things like you would on a full OS, only to run into constant roadblocks and issues. If you're seeing that, then usually the real problem is that you aren't doing things the Android way. Once you do that, things may be kind of strange and awkward, but most of the roadblocks, workarounds, and headaches go away.

    Naturally, exactly what the Android way is and how it is different from other environments you've used isn't really documented anywhere. You just kind of stumble into it blindly while you're trying to figure out why the stuff you're used to using just seems impossibly difficult to get working.

    For example, Android really doesn't like passing POJOs and JVM-wide state around between contexts. Things need to be converted into Bundle and passed around, persisted in a system-supported XML file or SQLite database, or in some other system-provided data store.



  • @Adynathos said in Android rant:

    @Zmaster

    My feeling is that on Androideverything it’s easy to do really basic stuff, but it gets exponentially more difficult when you try to get serious.

    Sometimes it's the other way around... you have to read 46 manuals to understand how to compile and run the first program, but after that it's smooth sailing.


  • :belt_onion:

    @Zmaster said in Android rant:

    So, quick go with intellisense... (italic is suggested completion)
    map.moveCamera
    Ah, that looks promising... the camera must set how we look at the map, makes sense. I assume there's an overload that takes a location?
    map.moveCamera( CameraUpdate )
    Uh... only 1 method signature... it takes an object of type CameraUpdate. Ok, I guess I can contruct it with a location and some options?
    map.moveCamera(new CameraUpdate( not found
    Mmm no... no constructor. Ok, probably one of those classes that provide static methods to create new instances. Maybe fromSomething?
    map.moveCamera(CameraUpdate.from no matches
    At this point I try a couple more things and I'm like... ok, let's check the samples, surely it's something similar and I just...
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13));
    What. The. Fuck.
    A... FACTORY to create an object that defines that we want to move the map to a different location?

    Is this your poem about the kingdom of nouns:

    For the lack of a war,
    new ServiceExecutionJoinPoint(
      DistributedQueryAnalyzer.forwardQueryResult(
        NotificationSchemaManager.getAbstractSchemaMapper(
          new PublishSubscribeNotificationSchema()).getSchemaProxy().
            executePublishSubscribeQueryPlan(
              NotificationSchema.ALERT,
              new NotificationSchemaPriority(SchemaPriority.MAX_PRIORITY),
              new PublisherMessage(MessageFactory.getAbstractMessage(
                MessageType.WRITTEN,
                new MessageTransport(MessageTransportType.WOUNDED_SURVIVOR),
                new MessageSessionDestination(
                  DestinationManager.getNullDestinationForQueryPlan()))),
              DistributedWarMachine.getPartyRoleManager().getRegisteredParties(
                PartyRoleManager.PARTY_KING ||
                PartyRoleManager.PARTY_GENERAL ||
                PartyRoleManager.PARTY_AMBASSADOR)).getQueryResult(),
        PriorityMessageDispatcher.getPriorityDispatchInstance())).
      waitForService();
    

  • Winner of the 2016 Presidential Election

    @Adynathos said in Android rant:

    Singletons

    :well_theres_your_problem.avi:


  • Impossible Mission - B

    @dse Bleh. Most of Steve Yegge's stuff is on par with the output of a certain hat-wearing gorilla who shall remain nameless. He's more articulate about it, but it makes about as much sense as The Drunken One's rants.



  • @Adynathos said in Android rant:

    @Zmaster

    My feeling is that on Androideverything it’s easy to do really basic stuff, but it gets exponentially more difficult when you try to get serious.

    Also, you seem to have a lot of problem with passing data between parts of your program, because the tools you normally use, like Singletons, don't work in Android.
    I only did a bit Android development long time ago, but I remember there were some different tools for that, like data-stores, sending messages between Activities, background tasks.

    Well, Singletons have their limits but it's a common pattern. In the end, I'm talking about maintaining an app-level state, not specifically about singletons.
    I'm (constructively) curious about the other solutions you mention.

    1. Data-stores. What do you mean exactly? DB or other forms of saving data? Because in that case you need to handle DB stuff or serializing/deserializing the data.
    2. Sending messages. I'm not sure about this one either. The obvious communication between activities happens with Intents which means parcealeable objects only. A quick googling didn't reveal much.
    3. Background tasks. Do you mean Background Services? This is something I thought of, however, if i understand correctly, they run in a separate process so you need to do IPC and you also need to handle the OS possibly killing one or the other in case of memory pressure.

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.
    I understand it's not possible to just pass object references around because then you're still screwen when you need to preserve the Activity state in case of configuration changes. But this is indeed my point: why such a design? I can only see downsides and no benefits.



  • @Gąska said in Android rant:

    @Zmaster From your blog post, it seems like your real problem with Android is that you're using too many singletons. Yes, one is too many, not just Android, but anywhere. The only singletons that makes sense is things that are provided to your process by OS in quantity of exactly one - standard input and outputs, current time, process ID, and that's pretty much it. All the other uses - session data, logging, subsystems, factories - is just lazy programming and it bites the ass sooner or later.

    Unless said "factory" is just a bunch of static methods without any persistent state - but then it's not a factory, it's a bunch of static methods.

    I'm trying to make sense of this... "standard input and outputs, current time, process ID" are not singletons, they're just objects.
    I've lost you again on the "said factory", i assume you meant "singleton", in which case i agree with the sentence.

    Anyway, if singletons are lazy programming what other practical options would you suggest? I'm definitely interested in other approaches.


  • area_pol

    @Zmaster said in Android rant:

    I'm (constructively) curious about the other solutions you mention.

    I don't remember them exactly. What I meant is that there probably are common patterns in Android that solve your problem.

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.

    Is the limitation to serializable objects such a problem? All actual data is serializable, only references to things given to you by the OS (like the UI) are not. In the MVC approach, it seems you are allowed to pass the model but not the view - that seems reasonable.

    And you can make your objects parcelable using annotations and compile-time code generation.

    But this is indeed my point: why such a design?

    You answer this yourself:

    The idea is that in Android an Activity can start an Activity in another app (or a system activity). This is what happens when you want to compose an email for instance: the activity starts a new activity with the appropriate Intent and the default mail client will launch to let you write your email.

    Also on a mobile device the programs are often suspended/restored (when locking device / switching to other program), so their state should be serializable.



  • @Adynathos said in Android rant:

    Is the limitation to serializable objects such a problem? All actual data is serializable, only references to things given to you by the OS (like the UI) are not. In the MVC approach, it seems you are allowed to pass the model but not the view - that seems reasonable.

    And you can make your objects parcelable using annotations and compile-time code generation.

    My problems with that are:

    • I have to do extra work to make them serializable
    • That extra work is particularly annoying if you have code that you want to be cross-platform, so it can't contain platform-specific code or annotations.
    • See my car in the highway example in the blog post: why would the top activity need to store the entire app state?

    @Adynathos said in Android rant:

    But this is indeed my point: why such a design?

    You answer this yourself:

    The idea is that in Android an Activity can start an Activity in another app (or a system activity). This is what happens when you want to compose an email for instance: the activity starts a new activity with the appropriate Intent and the default mail client will launch to let you write your email.

    Yes, and i also pointed out that, while it's an interesting concept, it makes the common case much harder to handle.
    On the bright side, passing data between apps is probably more flexible than iOS.

    @Adynathos said in Android rant:

    Also on a mobile device the programs are often suspended/restored (when locking device / switching to other program), so their state should be serializable.

    This is not a problem on other platforms. IMHO, if you don't have enough RAM to keep the stuff in memory... that's the problem. Either kill my app and don't expect me to remember where every spanner in the workshop was or make a device with more RAM, it's cheap.



  • @Zmaster said in Android rant:

    Either kill my app and don't expect me to remember where every spanner in the workshop was

    But that's not a very good user experience. They're using your app and get a text message, then when they get back to your app everything's gone.

    :fa_pencil_square_o: Or alternatively, every open app stays in memory and their battery lasts for half an hour on a full charge.



  • @hungrier said in Android rant:

    But that's not a very good user experience. They're using your app and get a text message, then when they get back to your app everything's gone.

    Just like when I switch to a different tab in Chrome and it loses my fucking state!



  • @anonymous234 So don't switch tabs when you're filling out an address form :tropical_fish:



  • @Zmaster said in Android rant:

    Well, Singletons have their limits but it's a common pattern.

    Because they're easy to write. But their goal - to provide some global state in a way accessible everywhere in your application - is directly opposite to one of basic principles of making maintainable software - to NOT have any global state that controls everything and can be changed everywhere in your application.

    @Zmaster said in Android rant:

    I'm trying to make sense of this... "standard input and outputs, current time, process ID" are not singletons, they're just objects.

    What is a singleton if not an object?

    @Zmaster said in Android rant:

    Anyway, if singletons are lazy programming what other practical options would you suggest? I'm definitely interested in other approaches.

    Everything you would get from a singleton, provide in a constructor instead. That way, all your dependencies are explicit, so you have finite, easily accessible list of things that can affect execution of any given line of code. Also, free dependency injection without any frameworks.

    @Zmaster said in Android rant:

    My problems with that are:

    • I have to do extra work to make them serializable
    • That extra work is particularly annoying if you have code that you want to be cross-platform, so it can't contain platform-specific code or annotations.

    Different platforms require different steps to do the same thing. What a shock.

    • See my car in the highway example in the blog post: why would the top activity need to store the entire app state?

    Car analogies are like used cars - they look okay at first glance, but when you take closer look, they're barely holding together and have more problems than they solve. Activity is the central things in Android ecosystem, and they're literally responsible for everything. Application is just collection of activities - unlike in other ecosystems, where application is the central thing and windows/screens/whatever are just to gather user input and show output.

    @hungrier said in Android rant:

    :fa_pencil_square_o: Or alternatively, every open app stays in memory and their battery lasts for half an hour on a full charge.

    Fun fact: maintaining DRAM state requires constant amount of energy regardless of amount of applications open, or bits of meaningful informations saved.


  • Impossible Mission - B

    @Gąska said in Android rant:

    But their goal - to provide some global state in a way accessible everywhere in your application - is directly opposite to one of basic principles of making maintainable software - to NOT have any global state that controls everything and can be changed everywhere in your application.

    So databases are evil, then? :tropical_fish:



  • @masonwheeler depends on how they're represented in your application. A global object that has a method to do arbitrary queries is pure evil. A global object with very restricted set of queries you can execute, all separated in their own methods, is marginally less evil.


  • Impossible Mission - B

    @Gąska Just saying. What is a database if not a giant singleton containing the global state of your application? In fact, its scope is even broader than global, as other applications can connect to it and alter it as well!



  • @masonwheeler global state is alright if it can't be accessed and changed randomly in literally any place in your codebase. And the most common way to make it inaccessible and unchangeable is making a local variable holding a reference to the same object everywhere it's needed. It's actually a global object, but technically it isn't.


  • Discourse touched me in a no-no place

    @Zmaster said in Android rant:

    Singletons have their limits but it's a common pattern.

    The problem with Singletons as a pattern is that people tend to design their code to assume that the objects are singletons. This causes all sorts of subtle problems (e.g., harder to test, harder to work with some environments) and generally makes things suck. The problem isn't that there's just one instance, but rather that you've nailed in the assumption all over the place. Instead, you should pass the (single, as it happens) object instance in via constructor arguments or a property setter or an argument (depending on what you're doing) and let that instance just behave normally.

    I didn't know that singletons were a problem for Android until reading this thread. I know that they're a problem elsewhere; if you work with OSGi, you definitely want to avoid singletons (they really fuck with code unloading, but usually convert to application-wide services instead). They're also a horrible problem if you want to test, as they make it much harder to isolate tests from each other; the baked-in Singleton-ness just cuts across boundaries even if you don't want it to.



  • @Zmaster Sorry, but your rant is kinda wrong, but I don't have the nime right now to explain why in details.

    But it sounds like your major mistake, was breaking your application into multiple Activities without needing it. You can make your app as a single Activity. The thing you lose if you do this is the ability to load only parts of the apps, and the ability for other apps to use one of your activities.


  • :belt_onion:

    @masonwheeler said in Android rant:

    He's more articulate about it

    That is a sign of intellect

    @masonwheeler said in Android rant:

    but it makes about as much sense as The Drunken One's rants.

    Did I mention intellect?



  • @Zmaster said in Android rant:

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.
    I understand it's not possible to just pass object references around because then you're still screwen when you need to preserve the Activity state in case of configuration changes. But this is indeed my point: why such a design? I can only see downsides and no benefits.

    But why? Either you need your Activities to be air airtight and then serialization is by definition the only solution because you are not air tight if you just allow passing objects in as is. (Otherwise you would allow any other app on the phone, to inject arbitrary objects into your app. You don't want that).

    If you don't need your Activities to be air tight, then you don't really need to use multiple Activities at all.

    An Activity is part of the program which can be used independently, and it is used to support loading of only part of the app(For performance) and sharing of parts of the app. (So other apps can call your Activity). It really sounds like you just need your app to be one big Activity.



  • @anonymous234 said in Android rant:

    @hungrier said in Android rant:

    But that's not a very good user experience. They're using your app and get a text message, then when they get back to your app everything's gone.

    Just like when I switch to a different tab in Chrome and it loses my fucking state!

    Turn off tab discarding, at least for desktop chrome.



  • @Sumireko woosh



  • @Martin_Tilsted said in Android rant:

    @Zmaster said in Android rant:

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.
    I understand it's not possible to just pass object references around because then you're still screwen when you need to preserve the Activity state in case of configuration changes. But this is indeed my point: why such a design? I can only see downsides and no benefits.

    But why? Either you need your Activities to be air airtight and then serialization is by definition the only solution because you are not air tight if you just allow passing objects in as is. (Otherwise you would allow any other app on the phone, to inject arbitrary objects into your app. You don't want that).

    If you don't need your Activities to be air tight, then you don't really need to use multiple Activities at all.

    An Activity is part of the program which can be used independently, and it is used to support loading of only part of the app(For performance) and sharing of parts of the app. (So other apps can call your Activity). It really sounds like you just need your app to be one big Activity.

    I actually agree with you on the single Activity. Should I start from scratch, it looks like a better option.
    This doesn't change the fact that Android will re-create the Activity in case of configuration changes though, so you still need to serialize all of your state.



  • @Gąska said in Android rant:

    Because they're easy to write. But their goal - to provide some global state in a way accessible everywhere in your application - is directly opposite to one of basic principles of making maintainable software - to NOT have any global state that controls everything and can be changed everywhere in your application.

    IMHO when developing some software there is no perfect solution. There are different solutions and one has to find a balance between pro/cons. You definitely don't want to have just global variables all around your software.

    @Zmaster said in Android rant:
    What is a singleton if not an object?

    It's a class of which one and only one instance exists. std and stdout and both instances of Stream, current date/time is one of the many possible instances of DateTime, etc.

    @Zmaster said in Android rant:
    Everything you would get from a singleton, provide in a constructor instead. That way, all your dependencies are explicit, so you have finite, easily accessible list of things that can affect execution of any given line of code. Also, free dependency injection without any frameworks.

    I'm getting the feeling that everyone thinks I've scattered my app with singletons. I have 1, maybe 2 I can't remember now.
    Anyway, passing things in the constructor is what I normally do. If a class uses that resource it makes sense.
    What doesn't make sense IMHO is passing an object around many classes just because one might eventually use it. You end up with constructors that take too many objects, so then you create a container for all of them and you pass this god-object around (Android's Context anyone?). So, in particular and planned situations I consider it an acceptable approach.

    Now, let's forget about the singletons. Even passing all your objects around as you suggest, you still need to serialize them in the current Activity when it gets re-created.

    @Zmaster said in Android rant:
    Different platforms require different steps to do the same thing. What a shock.

    No, THIS platform requires different steps. And I could be fine with that, except, as far as I can tell, there's no advantage whatsoever other than saving a few cents in RAM.

    Car analogies are like used cars - they look okay at first glance, but when you take closer look, they're barely holding together and have more problems than they solve. Activity is the central things in Android ecosystem, and they're literally responsible for everything. Application is just collection of activities - unlike in other ecosystems, where application is the central thing and windows/screens/whatever are just to gather user input and show output.

    Agreed. I like the latter the most because it provides a clear separation between UI and backend.

    Fun fact: maintaining DRAM state requires constant amount of energy regardless of amount of applications open, or bits of meaningful informations saved.

    +1



  • @Zmaster said in Android rant:

    @Gąska said in Android rant:

    Because they're easy to write. But their goal - to provide some global state in a way accessible everywhere in your application - is directly opposite to one of basic principles of making maintainable software - to NOT have any global state that controls everything and can be changed everywhere in your application.

    IMHO when developing some software there is no perfect solution.

    But there are plenty solutions that are just plain wrong, unconditionally. Singletons are one of them.

    @Zmaster said in Android rant:

    @Gąska said in Android rant:

    @Zmaster said in Android rant:

    What is a singleton if not an object?

    It's a class of which one and only one instance exists.

    Unnecessary lower bound on instance count aside, I made a simple mental shortcut in my post - when I said singleton, I actually meant what the instance of a singleton represents. There can only ever be one current time at any given moment, so it makes sense to make the current time provider a singleton. There can only ever be one standard output, so it makes sense to make standard output provider a singleton. But if you hardcode your classes to use those singletons directly, you can't easily mock time for test purposes, or easily redirect output to something else than stdout. So even with such guaranteed-to-ever-be-one-of-by-laws-of-physics things like current time, it's not a very good idea to put them in globally accessible singletons to be used wherever there's need to.

    @Zmaster said in Android rant:

    std and stdout and both instances of Stream, current date/time is one of the many possible instances of DateTime, etc.

    That really depends on how you represent them. In Rust, for example, there's an Stdout type that represents stdout and nothing else. It implements Write trait, so it can be used just like any other stream, but it's still separate type.

    My point is, OS provides just one stdout, and there will never be another one within the same process.

    @Zmaster said in Android rant:

    I'm getting the feeling that everyone thinks I've scattered my app with singletons. I have 1, maybe 2 I can't remember now.

    That makes me think they're not only singletons but also god objects. That's even greater antipattern. Anyway, as I said earlier, 1 singleton is already too many.

    @Zmaster said in Android rant:

    @Gąska said in Android rant:

    @Zmaster said in Android rant:
    Different platforms require different steps to do the same thing. What a shock.

    No, THIS platform requires different steps.

    For this one thing. For other things, it'll be another platform that will require special treatment. That's the thing about different platforms - they're different. If they weren't, they would be a single platform (like all those flavors of Linux).

    @Zmaster said in Android rant:

    And I could be fine with that, except, as far as I can tell, there's no advantage whatsoever other than saving a few cents in RAM.

    Just yet another thing in the 70-year history of computers that original developers predicted wrong about the future and we're stuck with their bad choices for the rest of eternity.



  • @Zmaster said in Android rant:

    @Martin_Tilsted said in Android rant:

    @Zmaster said in Android rant:

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.
    I understand it's not possible to just pass object references around because then you're still screwen when you need to preserve the Activity state in case of configuration changes. But this is indeed my point: why such a design? I can only see downsides and no benefits.

    But why? Either you need your Activities to be air airtight and then serialization is by definition the only solution because you are not air tight if you just allow passing objects in as is. (Otherwise you would allow any other app on the phone, to inject arbitrary objects into your app. You don't want that).

    If you don't need your Activities to be air tight, then you don't really need to use multiple Activities at all.

    An Activity is part of the program which can be used independently, and it is used to support loading of only part of the app(For performance) and sharing of parts of the app. (So other apps can call your Activity). It really sounds like you just need your app to be one big Activity.

    I actually agree with you on the single Activity. Should I start from scratch, it looks like a better option.
    This doesn't change the fact that Android will re-create the Activity in case of configuration changes though, so you still need to serialize all of your state.

    You have to do this anyway, due to the nature of mobile apps. Because the user newer explicit starts or terminates apps, you have to handle the fact, that when your app goes to the background, the user may be back in 20 seconds, or he may be back after 3 months.

    Btw: You can configure your Activity, not to be recreated when the user turn the screen around.



  • @Zmaster said in Android rant:

    This doesn't change the fact that Android will re-create the Activity in case of configuration changes though, so you still need to serialize all of your state.

    Well, you could mark your activity as one that handles orientation changes, and remember to reset the view yourself.


  • Winner of the 2016 Presidential Election

    @Zmaster said in Android rant:

    This doesn't change the fact that Android will re-create the Activity in case of configuration changes though

    RTFM


  • Winner of the 2016 Presidential Election

    @Zmaster said in Android rant:

    make a device with more RAM, it's cheap.

    You do realize how much memory the average WebView needs, right? This is completely unreasonable, and you know it.


  • :belt_onion:

    @asdf said in Android rant:

    @Zmaster said in Android rant:

    make a device with more RAM, it's cheap.

    You do realize how much memory the average WebView needs, right? This is completely unreasonable, and you know it.

    Paging @codnghorror :tropical_fish:


  • Winner of the 2016 Presidential Election

    @asdf said in Android rant:

    @Zmaster said in Android rant:

    This doesn't change the fact that Android will re-create the Activity in case of configuration changes though

    RTFM

    Note: Using this attribute should be avoided and used only as a last resort


  • Winner of the 2016 Presidential Election

    @Jaloopa said in Android rant:

    Note: Using this attribute should be avoided and used only as a last resort

    Well, duh, because they want you to serialize your state, as mentioned before in this thread. It has still been there since the very beginning and has always been mentioned in the introductory documentation:

    So if you don't know about it, then you were too fucking lazy to read the "getting started" documentation, and should go back to writing shell scripts in your basement instead of writing software for a living. You're not a professional if you start throwing together an app using IntelliSense and don't RTFM. Fucking cowboy coders.



  • @Zmaster said in Android rant:

    Well, Singletons have their limits but it's a common pattern.

    Singletons: Solving problems you didn’t know you never had since 1995

    @Zmaster said in Android rant:

    In the end, I'm talking about maintaining an app-level state, not specifically about singletons.

    Android does not have applications and app-level. It has Activities (~windows) and Services and they have their own life-cycles. And then there is the process that hosts them, which can be killed approximately anytime without warning (the system will prefer to not kill a process that is hosting active activity or service, but sometimes it does not have a choice—and active is different from existing).

    But if you really want, there is always the android.app.Application escape hatch from the object-oriented hell if you really want your Singletons back.

    @Zmaster said in Android rant:

    All I'm asking is be able to use native (Java/C++/C#) objects in the app, without doing extra work just to pass the data between airtight Activities.

    Activities are definitely not airtight. You can pass references in and out of them just fine within one application. Between applications you are doing IPC, so it's obvious the objects must be serializable. At least you don't have to serialize yourself—that's still better then many other systems.

    I suggest making the Activities just dumb views and put all the model and controller stuff in Services or Application. Then the Activities will be mostly stateless and you won't have problems when the system drops and reinstantiates them when rotating screen, switching windows and such.

    @Zmaster said in Android rant:

    See my car in the highway example in the blog post: why would the top activity need to store the entire app state?

    Because it shouldn't.

    @Zmaster said in Android rant:

    Either kill my app and don't expect me to remember where every spanner in the workshop was or make a device with more RAM, it's cheap.

    Android does keep your app in memory as long as there is enough of it and then kills it. It is not making you to remember anything. It's about what you want to remember.

    @hungrier said in Android rant:

    But that's not a very good user experience. They're using your app and get a text message, then when they get back to your app everything's gone.

    If you store it in Service or Application and not the ultra-volatile Activity (do treat Activity as equivalent to Window on other systems; that's what it is), nothing will be gone with plain text message.

    @Gąska said in Android rant:

    Activity is the central things in Android ecosystem, and they're literally responsible for everything. Application is just collection of activities - unlike in other ecosystems, where application is the central thing and windows/screens/whatever are just to gather user input and show output.

    I would tend to disagree here. Activities are the entry points, but any complex state is better placed in Services for which the Activities are just views.

    @dkf said in Android rant:

    I didn't know that singletons were a problem for Android until reading this thread.

    What is more complicated on Android compared to other platforms is that the system interfaces are not static, but are tied to an(y) instance of Context. All your entry points—Activity, Service and Application—are instances of that, but if you use singletons, you have to somehow get a valid Context reference into them before you can access the outside world from them.

    However, since Application is a singleton itself, you always can.



  • Very interesting thread. I recently started getting a bit into Android development. So far, everything seems pretty well put together, but I'm just getting started.

    Re: singletons. I recently also did some C# UWP dev. So I looked into C# patterns on how to manage your services' lifecycle, separate islands of cleanliness from the IO ugliness, all the usual best practice stuff.

    I was horrified to find basically ALL tutorials and guides still relying on singletons to get their state organized. Even fucking Microsoft seems to have given up in their demo apps. If Singletons were ever declared an anti-pattern, C# community seems blissfully unaware of it.

    So I see why someone from C# background would immediately reach for singletons as the state sharing mechanism. As for me, if Android offers a better way to organize state, I'm all for it.



  • @asdf said in Android rant:

    @Jaloopa said in Android rant:

    Note: Using this attribute should be avoided and used only as a last resort

    Well, duh, because they want you to serialize your state, as mentioned before in this thread. It has still been there since the very beginning and has always been mentioned in the introductory documentation:

    So if you don't know about it, then you were too fucking lazy to read the "getting started" documentation, and should go back to writing shell scripts in your basement instead of writing software for a living. You're not a professional if you start throwing together an app using IntelliSense and don't RTFM. Fucking cowboy coders.

    Look, I know about that, I've seen it. But every place I've found while learning about the best way to handle configuration changes basically said "don't do that" as the first rule. As a beginner I assume it's good advice.
    About the map... whatever. You've clearly learnt every single method of a new API from TFM before writing your first line of code.



  • @Zmaster said in Android rant:

    You've clearly learnt every single method of a new API from TFM before writing your first line of code.

    It's a German thing.


  • Winner of the 2016 Presidential Election

    @Zmaster said in Android rant:

    About the map... whatever.

    Well, the maps API is overly complicated, I don't disagree with that.


  • sockdevs

    @asdf The AdWords API is just as bad, if not worse.



  • @Atazhaia said in Android rant:

    @Benjamin-Hall The syntax at a first glance seems weird, but I have mainly been using C-based languages with a dash of Python this far. According to what Apple is saying, Swift is combining the best of C/Objective-C and Python, though. The example code I have read has left me a bit confused however.

    And there's nothing like android.util.Log for iOS development? Really? Because that class is quite helpful when developing on Android.

    The other stuff I have mostly figured. The Apple mentality I have mentally prepared myself for and I know about all the fun that awaits in the world of Xcode. But I also have masochistic tendencies, so... :smiling_imp:

    "According to what Apple is saying..." also leads you to believe that it's INNOVATIVE! MAGICAL! BETTER BETTER BETTER!!! SMARTER SMARTER SMARTER! AMAZING!!! CLAP

    Incredible amazing awesome Apple – 01:50
    — justanotherguy84


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.