"A little bit of this also has to do to stick it to all those luddites people on the internet who post "that's impossible" or "you're doing it wrong" to Stack Overflow questions... Requesting permissions in the JNI "oh you have to do that in Java" or other dumb stuff like that. I am completely uninterested in your opinions of what is or is not possible. This is computer science. There aren't restrictions. I can do anything I want. It's just bits. You don't own me."
"I am completely uninterested in your opinions of what is or is not possible. This is computer science. There aren't restrictions. I can do anything I want."
This is quite interesting to see, as I recall experimenting with something similar a few years ago. In that case, borne out of anger and frustration from how slow Android was at some things, I complained to one of the engineers I had brought onboard about how a 1970s computer was vastly more responsive and performant (to the user's perspective) than these modern (in ~2016) Android devices. We ended up building a prototype of a vertical scrolling ListView, implemented entirely in C, implementing all the "normal" functionality required to allow Android to use it.
I believe my initial frustration was borne from performance tracing of an app we were developing, and finding the amount of time spent in nested constructors and other kinds of inherited object-oriented bloat was actually impacting on the user perceived performance (users said it was slow to scroll). My hypothesis was that if the functionality itself was implemented in C, properly and efficiently, with none of these extra layers of abstraction, it would be faster. That was definitely validated. I don't recall the figures now, but you could scroll a list with no perceptible latency as fast as you liked, with no stutter. The performance traces were nice and normal. It was smooth and fast.
Mobile apps were something I got far away from for a while, but every time I return, I'm disappointed to see an ecosystem of re-inventing the same (boilerplate) wheel, and running the same code. For the number of layers of abstraction I saw the OS burning cycles on, it is absurd to me why the "end-developer" is left to do so much boilerplate coding! Surely at least one of those layers of abstractions could get developers to a place of implementing their own logic, rather than platform-specific logic. Case in point, the Android activity lifecycle (!)
It is a bit confusing why developers are still expected to implement entire UIs themselves. Almost every app today that's not a game uses the same exact layout: tables and grids. As a mobile app developer I could save so much time by having the OS ask me what I want to put in these tables or grids, rather than having to implement the UITableViews and ListViews verbatim in almost every single project.
Since we're on this topic: Why is there still no native user login/registration widget? Why can't the user just press a button to have the OS autofill and save all of their information across all of their apps?
I know someone is going to say you can already do this, but the truth is, you still can't do it reliably enough to make it the first option. Sure, password manager extensions are supported by the OS, but I still have to go through whatever native interface my password manager wants to show me before I can get close to having a form filled out. In most cases, for most form fields, I am not prompted to fill anything out unless I'm in a web browser. It's a massive waste of time and developer energy considering these forms almost universally require the same input: name, profile icon, email, password.
Can't agree enough - when you delve beneath the scenes, it gets so ridiculously complex for something that just shouldn't be. For a List view, I can understand making something to put into that view.
I miss the days of VB6 and creating a GUI in drag-and-drop, aligning everything, and then double clicking each component to add add the default event handler. Occasionally I didn't want the default event handler, so I'd pick another one. Done!
I feel like with VB6 (and similar tools of the era), it was straightforward - I knew if I wanted to set the Label of Button1 programmatically as the window opened, I'd create a Window1.OnLoad method, and set Button1.Label to whatever I wanted... Doing this on Android will entail reading about the opinionated Android lifecycle model, which seems a good way of the OS forcing Devs to handle tasks that any sane OS should (i.e. handling loading, suspending and resumption of the app...) That should be given to me by the platform as a default! Overrideable if needed. Why must I totally redraw everything if the user rotates their phone? Can't I get shown 2 templates when I draw my UI, and make the landscape one a copy of the portrait, with some common sense adjustments (horizontal list view rather than vertical)? Then I wouldn't have to save and restore all state if the user jostles the device!
To your point about login, absolutely - if there was a simple Login View (I believe I recall one in VB6, just saying...) it would probably reduce a whole host of security issues from Devs doing it wrongly and logging credentials to places they don't belong, or putting them places they shouldn't be. It just seems crazy that for such dense and weighty platforms, we don't get any of this functionality included properly by the OS!
>I miss the days of VB6 and creating a GUI in drag-and-drop, aligning everything
That was a fixed non-resizable layout, showing static content.
>I knew if I wanted to set the Label of Button1 programmatically as the window opened, I'd create a Window1.OnLoad method, and set Button1.Label to whatever I wanted...
That works initially for simple UIs, but gets ugly really fast once you need to start displaying data items, including possible loading states and error states, etc. Mobile apps tend to fetch content from the internet a lot. You could also do your example in Android - just add a setText call to onStart of whatever empty Activity the wizard created for you.
Jetpack Compose promises to make Android UI development much nicer in the future https://developer.android.com/jetpack/compose - there is bit of a trend of mobile moving towards more React-like UI patterns (e.g. SwiftUI, Flutter, etc.).
Delphi definitely handles resizable layouts and data loading nicely: I’ve played around with again via Lazarus, and the experience is much nicer than any alternative I’ve seen, even for complicated layouts.
> That was a fixed non-resizable layout, showing static content.
It eventually morphed into the Windows Forms builder which handled dynamic layouts quite well, if a little different to most. Elements could be "anchored" to specific points of their container, so you button 10px off the bottom left would always be 10px off the bottom left, elements you wanted to grow to fill available space could be anchored on either side. All handled well by the visual designer.
Generally I prefer the gtk/qt method of just writing code, but the forms builder works really well too, both options are much better than the xml mess that is android and windows development these days.
This actually predates Windows Forms - it's the model used by Delphi/VCL (and these days, Lazarus). However, anchors are nowhere near as flexible as layout managers, and there are many things that they can't handle. For example, when localizing UI, length of labels can change substantially, which requires the other controls that they're labeling to be moved around.
Thanks for mentioning Jetpack Compose - not something I had heard of. Sounds like there is a growing trend towards declarative UI models, and that doesn't seem too bad. I don't particularly take offence with using XML to define the UI as such, but the clunky integration with Java was what annoyed me.
Agreed regarding the limitations of VB6 to static and non resizeable content, though I suppose from a developer perspective it worked nicely. It just seems genuinely strange we haven't seen innovation to improve on the UI design side. Maybe the declarative shift will give us this though!
Regarding the dynamic fetching and challenges there, absolutely this is the new challenge for an app model. But equally, surely this kind of logic is now the new "boilerplate"? Most apps need (or would benefit from) some kind of smart lazy loading. Can totally get my head around that, and clearly we need to work asynchronously. But I've never really seen anything that fit the bill for solving this, and it never felt like Android was trying to improve it itself.
To my mind the API should be elegant to the point of near invisibility, for simple tasks - assuming I already know the URL to fetch from and any HTTP Auth is handled by my HTTP library, in an ideal world, I'd just say where to get the "data stuff" from, and then tell it what to do when that happens. In this ideal world, caching helps to keep the UI responsive (and fresh) with minimum need to tweak this unless I want to.
It just feels to me that this should be a standard solved problem, either provided by the API, or by a library everyone uses near universally. I'm guessing the fact it's not the case means there's too many complex edge cases (but I could easily envisage a library telling me to provide it a function to call if there's a connectivity issue, and me being able to simply implement my desired logic to pop a little warning above the content, showing an exclamation mark and saying there are gremlins and content might be stale.
This is a great example of technology going in cycles. From my own experience:
1. ZX Spectrum - PLOT and LINE commands, graphics trivial and fun;
2. Using an X windows library in the early '90s writing 'idl' files to specify windows = super low-level stuff, 'attachments' to connect widgets together, incredibly easy to mess up, eg "where tf is my window? Oh right, it's that little ball of pixels over there, I must've messed my attachments up and the whole thing has scrunched in on itself like an effing neutron star"
3. VB6 - back to nice, easy, fun;
4. The Web | Mobile. JavaScript libraries (l'embarras du choix), or complex UI frameworks; back to pain.
Try Qt with QtDesigner/Creator it gives you pretty much the same experience as VB6 did. Knocking up UIs that look good, perform well and scale as the windows are resized is fast and easy. One of the best parts of Qt and stuff that generally speaking works really well.
You don't need to miss it. I still use Visual Basic .Net for a successful commercial Windows application. It's still that simple. I think C# is just the same, isn't it? Windows is also the most popular desktop OS by a large margin. It's not dead just because phones exist.
Making a performant list view is actually a very non-trivial task. All the weird complexity you see in the API is there to make it possible at all to have large list views that do not absolutely kill your phone.
That’s only necessary because a View in Android is ridiculously heavyweight and slow.
I ported a game from iOS to Android and just wrote simple C wrappers for all the views. I didn’t bother much with optimization, but lists with hundreds of complex items worked just fine, no lazy loading or recycling necessary.
> I miss the days of VB6 and creating a GUI in drag-and-drop, aligning everything, and then double clicking each component to add add the default event handler. Occasionally I didn't want the default event handler, so I'd pick another one. Done!
Android Studio almost does this - you still have to connect the event handler in the Java code, but the display itself is drag-and-drop:
Looks like the android studio setup is better than the old eclipse one. I'd love to be able to double click a control there and have a default event handler appear in my code, ready for me to add event logic.
This does look pretty nice however, though I imagine it's a one way sync, so only visualising the UI from the XML file, rather than letting you visualise and tweak your UI after seeing it populated with content that gets loaded in by Java code? I guess as everything has evolved, the amount of the actual layout contained in the XML is reducing over time.
Maybe this is where the more declarative approaches will make it easier to reconcile the layout and the content-filled layout.
> though I imagine it's a one way sync, so only visualising the UI from the XML file, rather than letting you visualise and tweak your UI after seeing it populated with content that gets loaded in by Java code?
Yeah, though you can (for example) put default text in that then gets replaced by the Java code before anyone sees it. I don't think it's very thorough for the other widget types, though.
> I guess as everything has evolved, the amount of the actual layout contained in the XML is reducing over time.
This is still all XML, it's just auto-generated for you through the GUI editor.
Thanks - I think I perhaps didn't explain what I was "asking for" that well - what I meant was akin to what Jetpack Compose looks to do for Android (thanks to another commenter for pointing it out!) with the "@Preview" notation to create some "real example" UIs that can contain real exemplar content.
They want you to use Google Sign-In, so Google can lock your users into their SSO. The more locked into the Google ecosystem people are, the easier it is for them to keep their search ad monopoly in the long term.
I was looking at Flutter recently and admiring the idea of cross platform (if you're going to use abstractions, at least let's get some benefit from them as developers!), but also grabbed a book about Swift UI too, just to see what was going on in iOS.
That sounds rather pleasant if it is performant (as I imagine it will be on iOS)
I can only recommend it. It is still in beta though.
SwiftUI is also cross platform: the generated UI is different on mac than iphone. With SwiftUI you are programming more with semantics than before
SwiftUI is not crossplatform in the context of Flutter, which builds to iOS, Android, web, macOS, Windows, and Linux, natively.
I've only played around with it a little bit, but it's quite an impressive achievement. It doesn't quite feel native, but it's pretty damn close.
If you are familiar with React Native, it is very similar in both its coding style and in how it works. It's like the virtual DOM with the middleman of the DOM stripped out.
>As a mobile app developer I could save so much time by having the OS ask me what I want to put in these tables or grids, rather than having to implement the UITableViews and ListViews verbatim in almost every single project.
A basic single-item-type RecyclerView on Android doesn't have that much boilerplate over just creating the "item" layout in any other way (which is still worse than a React-like automatic reconciliation would be). There are much bigger issues with Android's UI.
>I know someone is going to say you can already do this,
> Almost every app today that's not a game uses the same exact layout
The problem is that they don't. This is why RecyclerView took off over ListView, even though "out of the box" RecyclerView requires more work to use. ListView was that thing that everyone does - just define your bindings, and you're done. But it wasn't flexible enough. Everyone wants that one special change for their special app.
Funny that you mention that. I just spent a year developing and self publishing a Flutter app on the Play/App store, which is where my gripes with native development come from :P
> It's a massive waste of time and developer energy considering these forms almost universally require the same input: name, profile icon, email, password.
There's more to a user login/registration flow, way more, and that list is only what I could manage to write down in 5 minutes:
1. Support for a variety of custom 2FA methods - SMS, Yubikey/other tokens, RSA dongles, chip-TAN (used by German Sparkasse credit unions, works with an external chip reader), phone calls, the list is endless
2. Support for GDPR compliance (i.e. double opt in confirmation of email addresses)
3. Support for SSO solutions, with the added complexity that each app needs their own set of tokens for each social network
4. Support for password recovery in all the loads of combinations
5. Support for enterprise authentication (SAML / shibboleth)
Sure! I agree. There are plenty of different authentication standards. But if these are all highly ubiquitous standards implemented by a myriad of apps, why is this work passed on to the developer, and not handled by the operating system? Why can't I pass my OAuth tokens to this hypothetical login view (a la Firebase Auth), and let that handle signing my user in through X service? Why can't I just provide a shibboleth endpoint and let the native view handle exchanging tokens?
I'm not asking Apple or Google to figure out my highly custom one-and-done authentication protocol that relies on smoke signals and written poems to let the user sign in. I'm asking them to give me the tools to support these decades-old standards, standards that basically every app has to support already. It makes sense especially in the context of GDPR to provide system-wide support to a legal problem, as opposed to each developer having to solve the same exact problem over and over again.
If you call malloc/free in the inner loop of a C program you'll have the same problems.
Android has a RecyclerView for the exact reasons that you call out. The framework is far from perfect but at least from the details you listed I don't see why you had to drop to C.
Just for clarity, we resorted to C mostly as an experiment to prove our hypothesis that the abstraction and instantiation overhead was genuinely ridiculous. I don't have any of the screenshots to hand sadly now, but the performance traces were just appalling. And this was across the board
Our experiment in C showed that it was possible to implement a simple Android "view" or "control" (however it should be called), in native C, with significantly better performance than Android itself provided. It wasn't intended to be the least effort solution, rather a side project to prove something we always suspected.
RecyclerView is a start, but I believe we still found it slow. The delays from malloc()/free() were very significantly lower in impact, though admittedly we weren't doing them in nested loops or anything. I would like to think using C forced us to think more efficiently and we probably did a few little optimizations (noting it was just a side project) that were a bit like the recycler view does, to create enough memory in advance for a feasible scroll buffer both up and down, and fill it as the user moved.
The recycler view means at least you don't need to rebuild the object trees when you want to replace something, but it's still super slow to build it the first time.
Must confess I had gotten as far as possible from UI development in Android by the time recycler views came around (or at least I became aware of them), but this sounds very familiar. I think we were talking about hundreds of milliseconds to setup the view, full of nested constructors calling each other, calling their inherited super class constrictor, calling a few factories too for good measure.
It was liberating to reverse all that obfuscation and abstraction, and get all the logic into one single file, as a series of functions implementing the Android-expected API, without having to call out to a black box of stutters and constructors!
Yeah, I'm usually a backend person, but I have an app I want to build, because everything else that does it sucks. But the learn how to make Android UI stuff I need to do is all deathly slow, or says 'make a webview and do it there' if you want it to be fast, which is peobably true, but depressing.
I just want to fetch some data, and put it in something vaguely tabular. I can prefetch the data, so I have it when the app needs to draw, but I can't make drawing fast, which is super demotivating.
On the other hand, now I understand why even with 4GB of ram, Android is sluggish, and it's not worth using a 2GB phone anymore.
I'm in a similar position, although probably not with an idea for what I want to build right now. But been there in the not so distant past.
For me the "logic" part is easy - I can make it in a terminal UI fine. I could probably make it in a VB6 style UI similarly easily just from ancient muscle memory.
I have never actually built any personal "app" for Android, despite having been heavily into it since 2009, running an app development company (!) and doing a load of platform engineering. It just isn't enjoyable for me. Demotivating is a great way to describe it.
Any time I have an idea, the UI side ends up frustrating as the model for positioning components is very prescriptive and doesn't help me build fast. Once I get that UI, I then start uncovering horrific complexities in how it's bad to run things on the UI thread, but then apparently none of the effort has gone into making it straightforward not to do so.
The closest I got to something that made sense for me was Android Annotations (and a similar project whose name I forget) - http://androidannotations.org/ This made it less painful for me, although sadly it wasn't quite pain-free enough for me to actually cross the line and build a personal side project app...
If only it was possible to more easily chain together the APIs exposed by Android, without having to immerse oneself in the highly opinionated way of doing so "correctly", and instead focus on the logic required to get the data to the right address in memory.
Came across this (and remembered about Android annotations, which made life a bit less painful) and thought it might help you if you were trying to build the app equivalent of some basic CRUD stuff, and fetch some data into a view etc.
To throw some trivial examples from the top of my head, to just make a button do something when clicked, you need to call setOnClickListener to a new OnClickListener lambda type thing.
I just found absolutely every step of the way clunky and unwieldy. The amount of typing and keystrokes required to achieve anything was 5x more than it seemed to need to be, even with auto completions. I just wished for an event driven model like VB6 and old desktop programming, where the focus of the code was on my own logic and functionalities, rather than remembering I have to manually fetch every view by ID because of some arcane reason to do with how Android splits the UI and Java worlds!
Maybe my issues are outdated and fixed? Maybe android annotations has come far enough to alleviate my annoyances? I guess the day I can write a pleasant looking Android app that doesn't require me to think about someone else's vision for how my activity should behave in a complex lifecycle of different events, I'll be happy... What happened to sane defaults? Maybe my app (with its activities inheriting from activity) should have sane defaults already in place from the parent class, avoiding my need to even see such horrors, unless I want to?
Please never use androidannotations in a modern Android project. The codegen it does behind the scenes makes your compile times so much longer. It's been less than a month since it finally supported incremental compilation support. In addition, it's a lot of non configurable magic that will bite you if you ever need to do something a bit funky with different resources.
If you use kotlin, you can make use of synthethics which will automatically provide you with variables that bypass the need of calling `findViewById<T>`, including proper type inference. A slight step further, ViewBindings actually also give you type safety and null safety, depending on your layout. Then it simply becomes a matter of `binding.buttonThatIsNotHereOnLayout2?.setOnClickListener(this::onButtonClickedDoThing)`. Even if using Java, you can use the shorthand lambdas to do button.setOnClickListener((v) -> this.onButtonClicked()).
Much of the rest that is shown are matters of dependency injection, or are fixed with newer updates to the Android SDK. Fragments can have their layouts specified directly in their constructor, AsyncTasks have been deprecated over and over again, etc. AndroidAnnotations was alright in 2015-2016, where the Android API was truly dreadful. It still is, but most of the truly awful things are gone.
Thanks - sounds like the world of Android development has evolved a lot since I last looked at it. There's a lot of talk around Kotlin, so I guess it's time to look at that transition and what happened there.
It sounds promising if most of the bad and horrifying things are gone since the days of 2015/2016 when these tools helped!
Don't get me wrong, there's still plenty of crap. Google dug themselves in a deep hole with their god activities and insane fragment lifecycle. But if anything... The fragment lifecycle is about the worst there is now. The AndroidX libraries have done it a lot of good.
Are you saying that Android doesn't have proper Java support? In what way? I thought Java lambdas could be used with SAM interfaces, just like in Kotlin.
(Or are you saying that if Java supported Kotlin syntax it would look similar to Kotlin?)
Jake Warthon was doing contributions to support newer versions, but it remains a lotto what might eventually be supported long term, thus forcing Java library authors to have Android specific versions, or constrain themselves to what all flavours might actually support.
As for SAM, yes you are right, but many Android developers only know Android Java and still think Java == 6 || 7.
Yeah I never understood why everything should be so tightly bound to a single language... We mastered the idea of different software on a desktop PC using different languages a long time ago. Yet on mobile, given the fragmented and non-standardised ARM ecosystem and runtime environment, we have to put up with the complex abstractions given to us by the operating system... I can't access the accelerometer without using the blessed Google API for it, because I can't know where on earth the user's phone manufacturer saw fit to put it, nor even what chip they used... At least on x86 PC we got most of this stuff nailed down long ago, and we can boot an operating system without the permission of our motherboard maker and CPU designer.
No... But the drivers _are_ expected to implement a standardised interface. So whilst you're beholden to the OS on how to access it, it isn't an insanely obtuse Android-style interface.
For example, if the driver implements iio/accel, like it should for a Linux device, then you can either use the C-interface (including via FFI), or just treat it like a file and read/write from it however you feel like in your chosen language.
You don't _have_ to use C, and C-style semantics, to get at the accelerometer. You can use any language that can either read/write files, or has an interface to FFI.
This looks wonderful. I wish it had been around when I was doing an android app. I absolutely love seeing it and a good old make script. I am thrilled at the tiny tiny runtime requirements. Bravo. This must have required an incredible amount of experimenting and mucking through old, poorly documented examples in the dusty corners of an SDK somewhere.
android_native_app_glue is a Google-provided helper library in the NDK, and it's incredibly old at this point (hence the "Copyright (C) 2010 The Android Open Source Project" on those files)
Setting up a fully-native OpenGL ES window is also straight out of the NDK samples - this is also incredibly old (it's why NativeActivity even exists)
Most everything else looks to just be a handful of hand-written JNI to call common SDK methods - I'm not seeing anything that'd require incredible amounts of experimenting or mucking through old, poorly documented examples?
It's been around in form of NativeActivity for years (since Android 2.x I think) - it's literaly what that one does as well: initializes a canvas and gives control to native code.
Plenty of games used to be written like this, where you basically had a C (or C++) OpenGL ES platform independent code base, and then a bunch of small platform-specific parts for the different OSes.
They did usually have tiny pieces of code in platform-native language though.
I even wrote a game like that back in 2012 (originally for Samsung's bada OS, later ported to many things) https://github.com/peterholak/rail-climber (it says 2016 on github, but the code is much older).
One great thing about it is, when you have a desktop target, you can compile/test/debug things much faster (including things like level files), and only do a mobile build every once in a while to check that it still all works as it should. Almost like a full featured game engine.
This is what we do with X-Plane. It’s really, really nice to be able to debug code destined for mobile on the desktop sim first. It cuts the iteration time down by a huge factor.
You can similarly develop in C for Android using SDL2. Basically your app becomes a .so with a thin java shim SDL2 provides that calls into your .so and you're off to the races.
In 2013 a friend and I created an SDK for building games with GNOME's Vala (that transpires to C with GLib), SDL2 and Chipmunk physics for Android, Linux, and Windows (all within the same codebase).
But I have started porting some things to Kotlin. Nearly finished replacing all the Java
I also had to buy a new computer. The Pascal IDE worked great on my ten year old laptop; the Java/Kotlin IDE became so slow, it was unusable. It is surprising that Java can run on a phone, when it cannot run on my development system
If you mean Android Studio being slow (and the Android build system in general, with its many transform steps), that has little to do with Java itself.
Even IntelliJ IDEA, built on the same platform is much, much faster than AS (with non-Android projects).
Android Studio is just a slow IDE. 16 GB RAM and a good CPU is the absolute bare minimum for it these days for any non-trivial project, especially if you want to run the emulator as well.
The Android app development went from my first laptop with 4GB RAM and HDD to my second laptop with 8GB RAM and HDD to my current, third laptop with 16 GB RAM and SDD.
But all the laptops were really fast. I started writing Pascal code with Delphi under Windows 98 on a 166 MHz PC with 64 MB RAM or something, and it was fast enough
I'm pretty sure Delphi also didn't have the same level of code navigation and inspections across the entire codebase (including resources, even from 3rd party libraries), or a built-in CPU/memory/network/energy profiler of the same quality, or layout previews that actually reflect the written code.
Android Studio is still slow even by today's standards, but that is not an apples-to-apples comparison. There are also some ways to make incremental debug builds faster (can be brought down to a few seconds for smaller changes, gradle can show which step takes how long).
The same can be said about just about any software (plus again, AS is an exception, a typical IDE doesn't use anywhere near that much RAM - only few hundred MB to low GBs). Everything is bigger these days - web browsers show bigger web pages, photo editing software deals with much larger photos, etc. Today's cars and planes are also much more complex than the cars and planes from 100 years ago.
What it comes down to is, are the extra features provided by today's tools worth it? For most people, that's a no brainer.
As a random example, take auto import suggestions.
I can start typing 3 or 4 letters, and get a suggestion for a function name to call (and it's not just prefix search either, it is aware of words, etc.), then I just hit enter, and the function call is added to my code, plus the import statement is seamlessly added to the top of the file. I can see that function's documentation right then and there, navigate to its implementation and its usages inside a 3rd party library or just in my project, I get an immediate warning if I use it wrong or make a common mistake, etc.
Then you have languages like TypeScript that automatically narrow variable types based on the checks you perform around them. So if you have `if (user === undefined) { return }`, then it knows that below that block, `user` is definitely not `undefined` and the error reporting and autocomplete reflects that and doesn't complain. If you later remove that check, you'll immediately see red squiggly lines on code below it that broke because it can no longer rely on that assumption.
All of this requires having the code of my project and all of its dependencies indexed into a pretty verbose structure, but the productivity and reliability gains are 100% worth the extra bit of RAM and CPU time it takes - that's what it's there for.
I love TypeScript. But let's not use it to excuse our present situation. OCaml shares many properties with TypeScript, especially when TypeScript is used in a functional way with inferred types propagating through the system. And the tooling for OCaml has run for a long time on vastly less powerful machines.
Just yesterday, VSCode had a UI lock for a good 5-10 seconds in a pretty small typescript project. It easily could have been some extension I had installed somewhere. But our current ecosystem solves for the combination of satisfying business managers (fast iteration) and developer enjoyment over producing long term stable and reliable programs that can run on minimal hardware.
At the same time, I had typeahead find and completion for method and variable names back in the 90s with vi/emacs and exuberant ctags. It didn't need that much cpu or ram mojo. We tend to use whatever is available.
We were talking about code and IDEs, not media files.
Code completion, GUI designers and all sorts of fancy features already existed in IDEs 20 years ago.
You claim you have gained productivity, but coding a business app as a webpage or as an Electron app is not any faster than making it in VB6 or Delphi was. And the language were designed designed than JavaScript.
"Code completion" can mean many different things, from very basic features to more advanced ones. Many "lightweight" tools I've seen lack the more useful parts and offer only really basic completion.
For example if a function in a library I'm using is called `createUserWithSubscription`, and I start typing `usersub` anywhere in the project, it should offer that function near or at the top of the suggestion list, even if its location is not already imported/included in my current file. Things like that have a huge impact on easy discoverability of a library's functionality, which in turn has a huge impact on productivity and speed of adopting new technology.
If I just press Ctrl+space while the cursor is inside a function call, without typing anything, it should offer suggestions based on what other code passes into that function, or suggestions based on the type of the argument, etc. I don't recall these things from 20 years ago. And that is still just one of the features.
>coding a business app as a webpage or as an Electron app is not any faster than making it in VB6 or Delphi was
I would say it is. Of course the apps made today are very different from the apps back then, but making UI that displays data is much easier.
The kind of features you are describing existed two decades ago, in several IDEs, in one way or another, and for the most part do not require huge amounts of CPU/memory. Definitely not 2 orders of magnitude more.
> Of course the apps made today are very different from the apps back then, but making UI that displays data is much easier.
How so? Both VB6 and Delphi were designed to display and edit data quickly. Its main use case was creating business apps very quickly and both had WYSIWYG GUI designers in the IDE itself!
There were menus, buttons, lists, tables, tree displays, rich-text editors and many other ready-to-use controls. You had adaptors for different databases, OLE for embedded documents, COM support, etc. You could display images, video, sound too. Even commercial games were developed on them.
None of that matters when once you need to display a list of items (where every item has its own group of UI widgets), you have to start dealing with a whole bunch of clunky model wrappers, and even basic features like sorting and filtering require special care. Not to mention keeping all the UI in sync when one piece of data that is displayed in more than one place changes.
Instead of just doing
<>
<h1>List of items</h1>
{items
.filter(itemFilter)
.map(item => <div>
{/* UI for the individual item, e.g. name,
subtitle, icon, buttons, etc. */ }
</div>)}
</>
that also keeps the displayed data current no matter what - new data comes in from network, the filter in the search textbox changes, it all stays in sync...
I don't understand what you are talking about. What is so special about receiving data and displaying UI controls from it?
Networked apps, business apps, database frontends, etc. have been a thing since the 80’s, and I am not even talking about that but IDEs from the 90’s and later.
The code you show is identical to what was done back then in many languages, many frameworks and many systems. Filtering, sorting, per-item UI, multi-views, synchronization, etc. has been always a basic need.
The web is yet another UI/app framework. Nothing less, nothing more.
My point is that in environments like old-school Delphi or VB, or even with frameworks like Qt, those things take way more effort and boilerplate code than they should.
For exapmle in Qt you have to either subclass QAbstractListModel or use QStandardItemModel with weird QStandardItem wrappers around your data, then you have QSortFilterProxyModel (https://doc.qt.io/qt-5/qsortfilterproxymodel.html) and all that weirdness. And then for the actual UI of the individual items, you have QAbstractItemDelegate, etc. https://doc.qt.io/qt-5/qabstractitemdelegate.html
If you say so. I have worked professionally in quite a few UI frameworks and they are pretty much the same.
The web is actually one of the most complex ones out there due to the never ending frameworks and libraries that come into fashion every other year. Old environments had a defined set of things to use and learn and things were stable for many years.
In Qt you can build your UI on the fly with code without using those classes if that is what you are asking.
in Qt or one of the "old school" desktop tools as quickly as I just did in a few minutes, that loads data from the web (mock) and displays them in this way (and has this level of flexibility for further development). There's just no way.
One difference is that you can just use data directly as it comes from the net (or combine it with any other data in your application).
You don't have to wrap it in models like this https://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html and then either recalculate that when the data changes or have a custom model class that does it. Though granted that is still a huge improvement over doing this in regular Qt Widgets (see the star example a few comments above), or one of the "old school" desktop GUI builders. This difference would be felt even more if the items also had some interactivity with state (e.g. expanded/collapsed things in them, lazy loaded extra info etc.)
One consequence of the way rendering works is that I can just use language-native constructs like `if` or the ternary operator to either include or not include the "Top poster" line in the example. Instead of having to do something like this https://stackoverflow.com/questions/27695717/conditionally-i.... Similarly, you can use map/filter on arrays, transform the data more easily before rendering it, etc.
Another difference is that JS/TS is the main language of the entire app, not a separate DSL that you can use for some parts and not for others. You can use async/await, have the entire npm ecosystem available, etc.
Though QML is still hell of a lot better in this regard than old school VB or Delphi used to be.
Pretty sure it does. Delphi can be used to build its own components and the inspectors will pick up properties etc automatically. Compile time is a lot faster as well.
Creating GUIs, including resizeable windows and controls was not only possible but relatively easy.
I guess thats more an issue of "modern" IDEs, which seem invariably bloated. Im sure there are productivity arguments to be made about using an IDE, but I can't get over how they all take forever to start, and how any change in the UI layout causes everything to flash around for a good second.
The productivity argument can be had about using an IDE vs. not using any at all. But it doesn't really work to explain how the IDEs get larger and slower while not offering commensurate gains in productivity (and arguably, being slower creates a loss in productivity).
Agreed. I'd be interested in knowing if the perceived slowness is due to the number of layers of abstraction involved in aspects of the build process, that might also be used in the IDE figuring out what to include.
I remember when "android" IDE was a plugin for eclipse... Now it seems to be a deeply integrated plugin for IntelliJ, coupled with an infinitely more complex build system (gradle), that has a fairly high fixed overhead to run for anything, and which seems to need to download 100 MB worth of code from a server for itself.
Maybe we need to try get back to overall system designs where one good engineer can have the full design in their head? I suspect the slowness of the IDE has something to do with the complexity of the tooling, and the need to call the native tooling to figure out include paths, to enable features like search or finding definitions. But surely it shouldn't be this bad?
I'm not comfortable with a typical Android screen size either, but I have a Samsung tablet with physical keyboard flip case (Galaxy Tab S6).
These two together provide a functional and workable environment for me. I haven't tried the DeX-station, but I believe that too could be quite workable with a phone.
Termux has some "soft keys" for ESC, ctrl, alt etc (user-definable). Swipe in from left, hold the button labeled "keyboard".
Hacker's Keyboard (app) is the recommended onscreen keyboard (has ESC etc).
But really need a bluetooth keyboard e.g. logitech K480 or fullsize logitech K375s - or regular USB one if your phone has OTG.
Bonus: doubles screen space.
Yeah, Hacker's Keyboard makes a big difference, but I still only hit the right key 90% of the time, because I can't feel the keys with my fingers, and I can only hit a couple of keys per second. There's a big difference between making a typo once every 40 characters and making a typo once every 10 characters, especially in a vi command!
But very slow by 70s PC standards :) (Except my PC had a 9600 baud connection internally between the computer and the terminal! It still had keyboard echo in under 20ms, though.)
Cool. This seems like it would be really helpful for building libraries for other languages to enable native android programming in a variety of languages.
I know D's not the most popular language on here, but I know HN has a few D enthusiasts and Walter Bright hangs out here, but my first thought was this
I'm working on a somewhat similar development, where I however wrote an actual assembler for .dex (Dalvik bytecode) files, which gives access to all the Android APIs and allows defining your own subclasses (e.g. new GUI components etc.) For example, I can drive a regular SurfaceView in a multithreaded way. I plan to speak about it on the upcoming Online Nim Conference on Jun 6. You can see a "teaser" that is an old version of the project (initial PoC) here: https://forum.nim-lang.org/t/4840
My favorites are the WiFi signal strength mapping (it quite shaped my understanding of RF communication) and ColorChord. No! Euclid! (which has hot reloading in C!), glass PCBs and oscilloscope images through a VGA port (along with all the ESP8266 stuff) are also great.
If you like Applied Science you'll like this dude.
The sad part is that since mobile development has now drifted so far away from that ideal, porting existing iOS/Android applications to the Librem isn't trivial.
You could of course have an Android runtime on the Librem...
That's a good fallback for everyone's $ANDROID_APP that can't live without. But for the most part I'd be fine with not having that tire fire ported anyway, those apps are likely to be slow, suck battery and not conform at all to the native look and feel.
Yes, but iOS requires you to use Objective-C (or Swift) just like Android requires you to use Java.
I know the comment put Objective-C right next to C and C++, but it doesn't belong there. All platforms should have (at least) C interfaces, not requiring C++ or even Objective-C.
That would mean either implementing your entire API twice, or adding layers of pointless indirection, for extremely little gain. It is just not reasonable.
You're assuming that people want to program applications in "platform languages" like Objective-C or Swift or Java or Kotlin. That's generally not true. They want to use their language of choice.
That's why C interfaces are the reasonable choice, you can interface with them conveniently from pretty much any language and if you want a more idiomatic "pointless layer of indirection", you can build it.
> A little bit of this also has to do to stick it to all those luddites people on the internet who post "that's impossible" or "you're doing it wrong" to Stack Overflow questions...
> Requesting permissions in the JNI "oh you have to do that in Java" or other dumb stuff like that.
> If you want a bunch of examples of how to do a ton of things in C on Android that you "need" java for, scroll to the bottom of this file:
This code directly interfaces with the Java virtual machine. It obtains a handle to a Java class and a handle to one of its methods. Then it instructs the virtual machine to invoke the method with parameters supplied by code written in C.
I searched the repository for JavaVM and JNI_CreateJavaVM and got no results. So this code is being dynamically loaded by a pre-existing Java virtual machine at runtime.
I'm not sure I'm going to use it, though, as it still requires to install a lot of android stuff on the development computer.
Something I find to work well to make apps for myself on my phone without requiring the android ndk : using termux. I have installed nginx within it, then I write react apps that I load in my mobile browser and they make http request to golang apps that run in termux as well. The first time I experimented with that, I thought it would drain my battery, but it turns out I don't see any difference (I don't use a database, though, my apps work with files).
Having the possibility to write C and have it run on embedded hardware - it feels extremely empowering. Because the usual way (as intended by mobile architecture developers) of writing mobile apps introduces some overhead.
Also, this project allows for the slow introduction of the vast C ecosystem (libraries, frameworks) to the Android landscape. Just think of all the possibilities!
I've been building a native-only Android app for testing various aspects of a cross-platform (ie, Android and iOS) library we use at dayjob. Building and running with Makefile feels so liberating and is so d*mn fast compared to the Android Studio and Gradle molasses. Can recommend.
That's super cool. Would love to see someone using this as a base for KOReader (essential app, in my book) which has an unusual architecture for android, being written mostly in lua.
Would this permit to compile the APK for ancient android versions, like 2.1?
This seems super interesting! I've long been saddened at the requirement of Java to write applications for Android and now it's fixed! This should allow lots of interesting (art)projects and whatnot!
Very cool! But you can write apps in Java and not have big apk sizes... I have a pretty well optimized collaborative drawing pixel art app on the marketplace and it's < 8mb last I checked.
What about a drawing mechanism like Canvas?
What about custom font support?
JSON serialisation?
Google Play Services support?
A websocket client?
That's just off the top of my head the dependencies of said app. I'm not confident the C one would be much smaller, especially since Java's bytecode is more compact.
When you need a library you either call one of the Java default libraries (through JNI which I suspect is larger than a class file) or include a native library.
And the native code needs to be included four times for different CPUs. Or you need four different apks
Probably the normal apks are so big, because they include the support library or the Kotlin standard library
Java's bytecode is also more information dense than assembly is. Even if you only support a single architecture, a pure-Java Android app is going to almost certainly be smaller than a pure-C one, and by non-trivial amounts.
If you start adding things like the Kotlin standardy library or Jetpack libraries or whatever then yes size balloons. But so too will the C app's size as its feature set expands to match.
For example if this framework supported text[1] its size would explode as it grew ICU, FreeType, etc... dependencies, which are "huge."
I’ve recently pulled up Mission Impossible, Cybernoid II and International Karate on my C64 and played for a few hours. One of these games has synthesized speech. Each of them fits in less than 64K, on a processor that can be implemented with 930 logic gates (although the original 1978 version had about 3000 transistors which is a bit more)
As a funny aside, I built the emacs-native branch for the first time this week and I had to upgrade from 16GB to 32GB of ram for the build process to not run out of memory.
Do you know if not having enough RAM would result in segmentation faults during the build process? Or how exactly does it manifest? I have way less than 16 GB and when I tried to compile it a week ago, it segfaulted during the build, but I am unsure of the causes.
It would be interesting to know how to make something like that integrated with sensors and services OS offers: activity detection, geolocation, foreground tasks, scheduled alarms, etc.
Any experiences of building Android apps by just generating code from your favourite productive language on the desktop? Any ideas if this would be a better target than Java for that?
This is so funny and so relatable.