How does ViewBinding generate code in real time? - android

When i use ViewBinding, it always generate xxxxxBinding.
I know android use Android Gradle Plugin build apk with code and resources。
And they're going to split some task (or transform).
I know task(transform) will build some file into ./build .
But the ViewBinding makes me confused,He doesn't appear to be generating files(Because every time I create layout file, I can access it directly)(Or I can just delete the build folder and it won't be created again,But he can still get it right(No error) in the code)。
Were some files secretly generated?
If so, where will it be generated?
If not, how can I do the same? For example, use a markdown file to generate code in real time.

Related

Releasing Mobile (React Native) Artifacts with Config File

Taking inspiration from The Twelve-Factor App: V. Build, release, run, I'm working on updating our CI/CD pipeline with these three distinct steps in mind for an app being built with react-native-web.
Specifically, I want to:
Build: generate an environment agnostic artifact of the code for each platform (web, android, ios)
Release: take an artifact and a config file (API URLs, API keys, debug settings, etc), and release to each platform
This is trivial for web, which is what The Twelve-Factor App had in mind. My question is how do I read a config file on mobile platforms and how can I incorporate this with react-native-web build artifacts? Does my artifact need to contain all of the source code and dependencies so I can pull in the config at release time and build then?
Ideally, each artifact would contain code compiled for each platform that somehow knows how to pull in a config file and do something with it. Next best would be to have the source code for each platform that I can compile with a config file at release time. Third best is have a way to give each distribution enough information at release time so it can request the config at runtime.
Full disclosure, I know nothing about building and deploying mobile apps so I apologize if there is an obvious solution for this!
It's similar for Android. Once the build binary is created it's immutable.
So unfortunately that negates option #1. We can't do anything else with the binary once we build it.
I think for react-native option two is the best approach.
Essentially you'll need to build the apps at release time once you have resolved what your configs need to be. That avoids any overhead of loading stuff at runtime in option #3 and still matches nicely to Twelve Factor. You'll still have a mobile binary that matches the same configuration as your release type.
For actually reading those values, you can just drop the config file into the project's root and we can help with the setup to pull them in.
I'll be glad to discuss those details if you'd like.
UPDATE:
Anything iOS does we can do (almost as well)
Current build tools compile all code into bytecode classes.dex and compress all resrouces into resrouces.arc but res/raw is left untouched.
This gives us a place to inject our files.
From there, the app will be able to read and parse at runtime.
For iOS, the build and (non-App Store) release process works like this at a high level:
Archive your project in Xcode, which results in an .xcarchive artifact.
Export your archive which signs and generates an .ipa file.
Either host this .ipa file yourself (with some additional metadata files) or upload it to a service like HockeyApp for distribution.
There are a few ways that you can manage config inside an Xcode project. One fairly common and straightforward way is to use the info.plist file to store custom keys and values. The app can then look up and use these values at runtime.
In the scenario you describe, it sounds like you want to be able to inject specific config values after step 2 but before step 3. Fortunately, the .ipa file generated during step 2 can be extracted, which will reveal a Payload folder containing an .app file. This file can be inspected, and inside you will see, amongst other things, the app's Info.plist. Modifying this file will allow for injection of whatever config values you want to set.
This will save needing to manage configs inside the Xcode project, and creating a separate archive for each configuration of the app. However what this doesn't solve is step 3. You are still going to need to distribute each configured .ipa file separately.

How do I use this file from Github on Android Studio?

I understand this might be an extremely obvious and ridiculous question to ask, but please excuse me as I'm a beginner. I want to integrate this file into my project so I can call its methods:
https://github.com/RomainPiel/Shimmer-android
The question is, what do I do with it? Is it considered a "module", "library" or "file"? Should I manually copy the source files and create new classes in my project, and then call the methods from there? This would be the most straight-forward but in the "how to use" section in that package, it was mentioned "compile 'com.romainpiel.shimmer:library:1.4.0#aar'"
What I tried:
I downloaded the file as a .zip and then File->New->Import Module then navigated to the unzipped file. I believe I'm then supposed to add "compile 'com.romainpiel.shimmer:library:1.4.0#aar'" so I went to the gradle file to try to add it.
There are two: build.gradle (Module:app) and (Project:ProjectName).
I've tried adding to either and\or both and got this error: (Error:9,0) The project 'ProjectName' may be using a version of Gradle that does not contain the method. Did I do something wrong? Is it supposed to be this easy?
I would be extremely grateful to anyone who can point me in the right direction :)
You have three option
Using the GitHub Desktop you can clone the project and open it like a local project. Every change you make will be tracked. You can then commit and push using the GitHub Desktop. It's all UI and simple to use.
https://desktop.github.com
On Android Studio, when you open it, you'll see this, select GitHub and continue by adding your credentials.
You can then commit and push directly from that.
Using the terminal / command line.
If you are new, I recommend the first. It's simple to use and you get a hang of using it as it is the same steps with any project on any IDE you use.
Note: Downloading it as zip and then using it a bad idea because you're making it difficult on yourself because you can't keep track of changes and you'll have to re-upload everything every time. Which defeats the purpose of version control
If that GitHub account is not yours, then you'll have to fork the project, this way you'll have a separate version of the code on you GitHub on which you can modify. If it is yours then you're good.
Typically, you do not want to include external source code manually. This inhibits your build tool's (i.e. Gradle's) ability to manage that source code. It's very easy in Gradle to, say, set the version (like you have done by specifying "1.4.0") and then later remind yourself what version you have by merely looking at your build.gradle file. However, how would you go about doing that with raw source code? Typically developers do NOT put the version number of the source code in the actual source code - that's what they use their version control system (e.g. git) for, usually with tags.
Another aspect of Gradle is downloading and caching (and compiling) the external project for you. So that's nice.
With that said, you typically want to put that "compile..." line in your module's build.gradle file. Not the Project's build.gradle.
A module corresponds to your application (or library) that you are building or using. Some project's have multi-module configurations, where one module acts as a dependency for another (or several others). A Project in gradle is more of a 'meta' configuration that you can apply to all of your modules. The gradle docs recommend you focus on your module's configuration first and adjust the Project's configuration only if you have a specific need and reason to do so.
For the error you mentioned, you might have some unnecessary configurations in your build.gradle file, or the tool version numbers might not reflect what's on your system - if you copied and pasted from the internet, you might want to correct this by letting your IDE generate that file (the brute-force approach would be to create a new project entirely, and use its build.gradle files as a reference). Before you do that, you might want to check if your IDE provides any warnings inside that file.
You have to add the dependency to your module's gradle file.
There are two gradle file present in an android project. One is the project gradle and the second is the module gradle for each individual module.
You just have to copy the given
compile '......' in the dependency block.

How to install two versions of an app

is there a simple way to have installed two version of the app on the same android Phone?
Im updating a old web app to a native android app. For testing purpose it would be great if we could have both installed at the same time on the same device.
It would be great to rename the update just temporary.
If I rename the package name in the AndroidManifest, then also R will be renamed and I have to reorganize the imports etc.
Is it possible to do a simple rename only somewhere in the AndroidManifest without changing a single line of code (even not with eclipse / android studio refactoring mechanism).
I have tried to mark my native app as library project and to include it in a new Android Project with another package name. But I will get trouble with this approach, for instance with actionbar sherlock:
Unable to execute dex: Multiple dex files define Lcom/actionbarsherlock/R$attr;
Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/actionbarsherlock/R$attr;
If you are using new gradle build system you could create new build type and then just add packageNameSuffixto it. This will add suffix to your package name but everything else stays the same.
buildTypes {
debug {
packageNameSuffix ".debug"
}
}
There is an easy way if you want to do it temporarily. You need to modify the AndroidManifest.xml file.
Find the line that looks like this:
manifest package="com.example.myapp"
and change it to something like:
"com.example.myapp.debug"
AFAIK there is no way other than changing the application package name, but it's fairly easy.
In Eclipse, right-click your project and select Android Tools > Rename Application Package.

How to supply Jacoco agent to an Android app?

I am trying to get code coverage using Jacoco for manual testing. I am trying to use offline instrumentation. http://www.eclemma.org/jacoco/trunk/doc/offline.html
In there it mentions:
Configuration File: If a file jacoco-agent.properties is supplied on the classpath options are loaded from this file.
My question is how do I supply this? On some other forum, I saw that jacoco-agent.properties needs to be deployed with the app.
I tried putting jacoco-agent.properties under the res/raw, but it complained about "-" in the file name.
I tried putting this under the root directory it didn't take any effect.
I was wondering how could I setup\run jacoco so that it uses jacoco-agent.properties?
Well, at least for an Ant command line build the trick was to put jacoco-agent.properties in the src directory, which makes it get packaged as-is into the root of the APK file, from where it seems to be properly read (i.e. I can see setting the destfile property having an effect on where the execution data file is being created).
However, the created jacoco.exec file was always empty for me (like also mentioned here), probably because JaCoCo only writes the execution data at JVM termination, but Android's Dalvik VM does not terminate when the app stops.
The way we currently solve this is to explicitly call
org.jacoco.agent.rt.RT.getAgent().getExecutionData(false)
and write the returned byte array to a file when our custom test runner finishes.

Empty Package (model) in generated client jar

I have an app engine app that I want to expose its data to android app. I can test the endpoint's method just fine using curl/the explorer. However when I generated the android client using:
endpointscfg.py get_client_lib java -o . -f rest api.MyApi
and included the generated subdomain-myapp-v1-20130522125850-java-1.15.0-rc-sources.jar in the /libs folder of my android app, eclipse shows the empty package icon of com.google.api.services.mypp.model where it should contain the model class. I also tried to include the generated jar's dependencies into my android libs folder too with no result.
Thinking that my app engine implementation might be flawed, I downloaded the app engine app tictactoe and generated the client code and include it in my android app. But, still empty package. What am I missing here?
Apparently one have to extract the generated bla-bla-sources.jar inside the zip file and copied them into the Android project to make it work. Maybe I'm missing a simpler way to do it (I thought I can just include that sources.jar file like its dependencies into the Android project) but for now this is my only solution that works. I hope it helps anyone facing the same issue.

Categories

Resources