Rawdrawandroid: Build Android apps in C
github.com
github.com
This is so funny and so relatable.
Sir, this is a mobile platform.
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 (!)
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.
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!
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.).
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.
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.
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:
https://developer.android.com/studio/write/layout-editor#int...
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.
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.
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.
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.
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'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.
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)
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.
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,
I know about https://firebase.google.com/docs/auth/android/firebaseui but haven't used it myself.
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.
But you're not expected to start from scratch, it's why things like the Material Design Components library exists: https://material.io/develop/android/components/lists/
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.
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.
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.
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!
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.
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.
Do you have some examples ? Nowadays with "modern" Android dev practices, the amount of boilerplate I write in day to day dev is pretty minimal.
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?
I remember that project from very long ago (I never used it for various reasons)
hmm
As far as click goes ->
myButton.setOnClickListener { doSomething() }
kotlin makes this pretty minimal, I don't really see much we can remove there
(Or are you saying that if Java supported Kotlin syntax it would look similar to Kotlin?)
https://developer.android.com/studio/preview/features#j8-des...
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.
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.
It sounds promising if most of the bad and horrifying things are gone since the days of 2015/2016 when these tools helped!
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?
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.
It worked flawless, I even ported a XNA example. It may be useful for someone today: https://github.com/avalanche-games/avalanche/wiki/Getting-St...
Although I used Java to create the layouts/views.
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
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
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).
There is something very wrong with IDEs and complex applications these days.
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.
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.
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.
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.
> 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.
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...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.
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
I mean, just look at this example: https://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-exam...
No way that should take that much code.
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.
https://codesandbox.io/s/eloquent-spence-d51td?file=/src/App...
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.
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.
Creating GUIs, including resizeable windows and controls was not only possible but relatively easy.
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?
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.
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.
Physical keyboard! With a full size one, it really feels like a unix terminal. Which it is. And very fast by 70's unix standards.
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
https://wiki.dlang.org/Build_D_for_Android
I've tried to cross compile D apps for android and it was a hassle, I never really got it to work properly.
Would something like this project help efforts in that direction? Writing wrappers around C libraries in D is fairly painless comparatively.
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.
I highly recommend you to check out his YouTube channel: https://www.youtube.com/channel/UCG7yIWtVwcENg_ZS-nahg5g
No idea what framework the author used to accomplish that.
You know, kind of like the old Palm, WebOS, or iPhone platforms.
You could of course have an Android runtime on the Librem...
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.
The point is that it shouldn't be a pain to use these interfaces from C, concepts from ObjC/Java/C++ shouldn't leak into them.
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.
> 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:
> https://github.com/cntools/rawdraw/blob/master/CNFGEGLDriver...
> it shows how to use the JNI to marshall a ton of stuff to/from the Android API without needing to jump back into Java/Kotlin land.
I respect this attitude but it's wrong to say Java isn't being used or executed. The truth is Java code is being called from C.
jclass ClassActivity = env->FindClass(envptr, "android/app/Activity");
jmethodID MethodrequestPermissions = env->GetMethodID(envptr, ClassActivity, "requestPermissions", "([Ljava/lang/String;I)V");
env->CallVoidMethod(envptr, activity, MethodrequestPermissions, perm_array, 0);
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.
The part of the Android operating system that handles permissions is written in Java, so obviously to use it you would need to use Java.
He isn't wrong, because he didn't say that.
It's admittedly very close to that, but not quiet.
You just don't have to use Java to ask for permission. If that ultimately still executes Java code... Well, he didn't say.
> it shows how to use the JNI to marshall a ton of stuff to/from the Android API without needing to jump back into Java/Kotlin land
The C code "jumps back into Java/Kotlin land" when it calls the CallVoidMethod function.
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).
I quit mobile development after too many Java-induced meltdowns. This just renewed my interest in it.
Quick ideas: - Demoscene potential!! - Needs a C-based Android UI lib! - Musical potential! VCV Rack for Android?! - Great for ports!
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!
If I ever get over that experience I know where I'll start anew.
Would this permit to compile the APK for ancient android versions, like 2.1?
Big is a notion that has changed over the years. Comparing to what I did on my 2.5 megabyte Amiga, I feel like more should be done with less.
Nostalgia isn’t what it used to be.
Unfriendly it’s not always triggered fast enough, so your system might lock up slowing to a crawl swapping before it gets a chance to run.
You’ll find a message about it in dmesg
The example app doesn't even support half the permissions my app uses. Add those and you're probably in megabyte territory.
Even if not, the point is that for apps going on the marketplace - this kind of thing probably isn't worth it.
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
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."
1: yes there is a CNFGDrawText function but it uses a static map ( https://github.com/cntools/rawdraw/blob/a2a9f3c88b5caf92ef3c... ) which I'm pretty sure is ASCII only, and obviously doesn't support fonts. Or internationalization of any kind. And similarly for text layout it only "works" because it's always monospace with a known "font" ( https://github.com/cntools/rawdraw/blob/a2a9f3c88b5caf92ef3c... )