I'm experimenting with android terminal emulator(Terminal IDE) and trying to compile an Android project. I use the following script to compile.
#Build script
#cd into the home dir - this way it works when run from inside vim or any other folder
cd ~/projects/simple_search/
#Clean up
rm -rf build
rm -rf dist
#create the needed directories
mkdir -m 770 -p dist
mkdir -m 770 -p build/classes
#Rmove the R.java file as will be created by aapt
rm src/com/simple/search/R.java
#Now use aapt
echo Create the R.java file
aapt p -f -v -M AndroidManifest.xml -F ./build/resources.res -I ~/system/classes/android.jar -S res/ -J src/com/simple/search
#cd into the src dir
cd src
#Now compile - note the use of a seperate lib (in non-dex format!)
echo Compile the java code
javac -verbose -cp ../libs/demolib.jar -d ../build/classes \
com/simple/search/AboutDialog.java \
com/simple/search/CustomWindow.java \
com/simple/search/DatabaseHelper.java \
com/simple/search/SearchResults.java \
com/simple/search/SimpleSearch.java \
com/simple/search/SuggestionProvider.java \
com/simple/search/Tag.java \
com/simple/search/TestAction.java \
com/simple/search/TestDetails.java
#Back out
cd ..
#Now into build dir
cd build/classes/
#Now convert to dex format (need --no-strict) (Notice demolib.jar at the end - non-dex format)
echo Now convert to dex format
dx --dex --verbose --no-strict --output=../simple_search.dex org ../../libs/demolib.jar
#Back out
cd ../..
#And finally - create the .apk
apkbuilder ./dist/simple_search.apk -v -u -z ./build/resources.res -f ./build/simple_search.dex
#And now sign it
cd dist
signer simple_search.apk simple_search_signed.apk
cd ..
The script executes fine till cd build/classes/. But at dx --dex --verbose --no-strict --output=../simple_search.dex org ../../libs/demolib.jar I'm encountering the following error.
Now convert to dex format
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: org: file not found
at com.android.dx.util.FileUtils.readFile(FileUtils.java:55)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:139)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:113)
at com.android.dx.command.dexer.Main.processOne(Main.java:247)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:183)
at com.android.dx.command.dexer.Main.run(Main.java:139)
at com.android.dx.command.dexer.Main.main(Main.java:120)
at com.android.dx.command.Main.main(Main.java:89)
at com.spartacusrex.spartacuside.external.dx.main(dx.java:14)
at dalvik.system.NativeStart.main(Native Method)
processing archive ../../libs/demolib.jar...
ignored resource META-INF/MANIFEST.MF
processing org/library/libfunc.class...
1 error; aborting
What is wrong with the script? Can you point me in the right direction? Any smallest help is appreciated.
Remove 'org', as it doesn't seem to be a file for your build.
The line should read.
dx --dex --verbose --no-strict --output=../simple_search.dex ../../libs/demolib.jar
Related
We are configuring a self-hosted android runner for GithubActions, but when we run some command of gradlew, it crashes/stops sending an error connection reset.
Our docker file contains the basic for a android runner (few lines of code for gradle and sdk installation. the tools are also installed properly).
# Gradle
ENV GRADLE_VERSION 7.0.2
ENV GRADLE_HOME="/opt/gradle"
ENV GRADLE_SDK_URL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip
RUN curl -sSL "${GRADLE_SDK_URL}" -o gradle-${GRADLE_VERSION}-bin.zip \
&& unzip -q gradle-${GRADLE_VERSION}-bin.zip -d ${GRADLE_HOME} \
&& rm -rf gradle-${GRADLE_VERSION}-bin.zip \
&& chmod +775 /opt/gradle
ENV PATH ${GRADLE_HOME}/bin:$PATH
# Install Android SDK
RUN echo "SDK tools ${ANDROID_SDK_TOOLS_VERSION}" \
&& cd /opt \
&& chmod +775 . \
&& wget -q "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" -O android-commandline-tools.zip \
&& mkdir -p ${ANDROID_SDK_HOME}/cmdline-tools \
&& unzip -q android-commandline-tools.zip -d /tmp/ \
&& mv /tmp/cmdline-tools/ ${ANDROID_SDK_HOME}/cmdline-tools/latest \
&& rm android-commandline-tools.zip && ls -la ${ANDROID_SDK_HOME}/cmdline-tools/latest/
Then when in the workflow we do some ./gradlew command it crashes.
some example commands that crash:
> ./gradlew --version
> ./gradlew app:assembleBetaRelease --offline
Always same Error log:
Run ./gradlew --version
Downloading https://services.gradle.org/distributions/gradle-7.0.2-all.zip
Exception in thread "main" java.lang.RuntimeException: java.net.SocketException: Connection reset
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:78)
at org.gradle.wrapper.Install.createDist(Install.java:47)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:129)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
Caused by: java.net.SocketException: Connection reset
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:478)
at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:472)
at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1426)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1336)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:421)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:572)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1592)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
at org.gradle.wrapper.Download.downloadInternal(Download.java:59)
at org.gradle.wrapper.Download.download(Download.java:45)
at org.gradle.wrapper.Install$1.call(Install.java:60)
at org.gradle.wrapper.Install$1.call(Install.java:47)
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
... 3 more
Error: Process completed with exit code 1.
It seems that tries to download Gradle, but it exist previously in dockerfile.
Did we forget some configuration in dockerfile or something similar?
I've created a docker container in order to run my gradle tasks on it.
I'm downloading the sdk inside it, but when I run a task from outside it says that the sdk folder can not be found because it's getting the path I have in the local.properties file of the project. Which is pointing to my machine sdk folder. How can I specify the sdk folder inside the docker image? Thanks.
Docker image build file:
FROM openjdk:8
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \
ANDROID_HOME="/usr/local/android-sdk" \
ANDROID_NDK_HOME="/usr/local/android-sdk/ndk-bundle" \
ANDROID_VERSION=26 \
ANDROID_BUILD_TOOLS_VERSION=26.0.2
# Download Android SDK
RUN mkdir "$ANDROID_HOME" .android \
&& cd "$ANDROID_HOME" \
&& curl -o sdk.zip $SDK_URL \
&& unzip sdk.zip \
&& rm sdk.zip \
&& yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
# add to PATH
ENV PATH ${PATH}:${ANDROID_HOME}
ENV ANDROID_NDK_HOME /usr/local/android-ndk
ENV ANDROID_NDK_VERSION r19
ENV NDK_URL="https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
# Download Android NDK
RUN mkdir "$ANDROID_NDK_HOME" \
&& cd "$ANDROID_NDK_HOME" \
&& curl -o ndk.zip $NDK_URL \
&& unzip ndk.zip \
&& rm ndk.zip
# add to PATH
ENV PATH ${PATH}:${ANDROID_NDK_HOME}
# Install Android Build Tool and Libraries
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
"platforms;android-${ANDROID_VERSION}" \
"platform-tools"
RUN mkdir /application
WORKDIR /application
This is how I run the task:
docker run -it --rm -v "$PWD":/application packsdkandroiddocker.image sh -c "$#" ./gradlew clean
And this is the error I get:
NDK is missing a "platforms" directory. If you are using NDK, verify
the ndk.dir is set to a valid NDK directory. It is currently set to
/Users/adalpari/Library/Android/sdk/ndk-bundle. If you are not using
NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties
to remove this warning.
FAILURE: Build failed with an exception.
What went wrong: A problem occurred configuring project ':app'.
The SDK directory '/Users/adalpari/Library/Android/sdk' does not exist.
I think you need to remove local.properties file from your root folder as SDK is then searched locally which container cannot access.
Android Studio is too slow for my computer so I took it upon myself to learn how to build android apps manually. I finished with this script:
#!/usr/bin/env bash
##################################################################
# PREPARE ENVIRONMENT
##################################################################
path=$(pwd)
rm -rf bin
rm -rf gen
mkdir bin
mkdir gen
##################################################################
# SET VARS
##################################################################
# Set your application name
APP_NAME="mygame"
# Define minimal Android revision
ANDROID_REV="27.0.3"
ANDROID_PLATFORM_REV="android-27"
# Define Java compiler command
JAVAC="${JAVA_BIN}/javac -classpath ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar"
JAVAC_BUILD="${JAVAC} -sourcepath src -sourcepath gen -d bin"
##################################################################
# PROCESS
##################################################################
# Generate R class and pack resources and assets into resources.ap_ file
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt package -v -f -I ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar -M AndroidManifest.xml -A "assets" -S "res" -m -J "gen" -F bin/resources.ap_
# Compile sources. All *.class files will be put into the bin folder
${JAVAC_BUILD} src/com/mycompany/mygame/*.java
# Generate dex files with compiled Java classes
${ANDROID_SDK}/build-tools/${ANDROID_REV}/dx --dex --output=${path}/bin/classes.dex ${path}/bin
# Recources file need to be copied. This is needed for signing.
mv "${path}/bin/resources.ap_" "${path}/bin/${APP_NAME}.ap_"
# Add generated classes.dex file into application package
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt add ${path}/bin/${APP_NAME}.ap_ ${path}/bin/classes.dex
${ANDROID_SDK}/build-tools/${ANDROID_REV}/zipalign -f -v 4 ${path}/bin/${APP_NAME}.ap_ ${path}/bin/${APP_NAME}_unsigned.ap_
# Create signed Android application from *.ap_ file.
${ANDROID_SDK}/build-tools/${ANDROID_REV}/apksigner sign --ks ${path}/keystore/etamagotchi-release-key.keystore --ks-key-alias "mykeystore-alias" ${path}/bin/${APP_NAME}_unsigned.ap_
#
cp ${path}/bin/${APP_NAME}_unsigned.ap_ ${path}/bin/${APP_NAME}.apk
# Delete temp file
rm bin/*.ap_
rm bin/*.dex
It builds successfully. If I try to run adb install mygame.apk it says:
[INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.mycompany.mygame-1: Package /data/app/com.mycompany.mygame-1/base.apk code is missing]
If I manually try to install it says "The package appears to be corrupted". What's wrong with my build script?
I added -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" to my $JAVAC build rule
I am trying to build an NDK Android project using Bitbucket Pipelines continuous integration using ndk-build (not the newer CMAKE). But I am getting the following error when calling ./gradlew assembleDebug:
/opt/android-sdk-linux/ndk-bundle/build/ndk-build: 144: /opt/android-sdk-linux/ndk-bundle/build/ndk-build: file: not found
:sensorylib:ndkBuild
make: Entering directory '/opt/atlassian/pipelines/agent/build/sensorylib/src/main'
/bin/sh: 1: file: not found
make: execvp: /opt/android-sdk-linux/ndk-bundle/build/extract_manifest.py: Permission denied
make: execvp: /opt/android-sdk-linux/ndk-bundle/build/extract_manifest.py: Permission denied
[armeabi] Install : libSensoryVoiceJNI.so => libs/armeabi/libSensoryVoiceJNI.so
/opt/android-sdk-linux/ndk-bundle/build/core/build-binary.mk:797: recipe for target 'libs/armeabi/libSensoryVoiceJNI.so' failed
make: Leaving directory '/opt/atlassian/pipelines/agent/build/sensorylib/src/main'
make: /opt/android-sdk-linux/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/bin/arm-linux-androideabi-strip: Command not found
make: *** [libs/armeabi/libSensoryVoiceJNI.so] Error 127
make: *** Deleting file 'libs/armeabi/libSensoryVoiceJNI.so'
:sensorylib:ndkBuild FAILED
20 actionable tasks: 20 executed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':sensorylib:ndkBuild'.
> Process 'command '/opt/android-sdk-linux/ndk-bundle/ndk-build'' finished with non-zero exit value 2
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED in 45s
bitbucket-pipelines.yml
image: java:8
pipelines:
default:
- step:
caches:
- gradle
script:
# dependencies
- apt-get update
- apt-get -y install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
# environment vars
- export SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip"
- export ANDROID_HOME="/opt/android-sdk-linux"
- export ANDROID_NDK_HOME="$ANDROID_HOME/ndk-bundle"
- export PATH="$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_NDK_HOME:$PATH"
# download and unzip sdk
- wget -q $SDK_URL -O android-sdk.zip
- unzip android-sdk.zip -d $ANDROID_HOME && rm -f android-sdk.zip
# accept all licences http://stackoverflow.com/questions/38096225/automatically-accept-all-sdk-licences
- mkdir -p "$ANDROID_HOME/licenses"
- echo -e "8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
# download ndk
- sdkmanager "ndk-bundle"
# build
- chmod +x gradlew
- ./gradlew assembleDebug
The ANDROID_NDK_HOME path seems correct as I can ls the folder and it looks correct. The permission on ndk-build also looks correctly set...
The error was that I was missing file in the apt-get install dependencies.
Here is the working bitbucket-pipelines.yml.
(I also managed to reduce the overall apt-get dependencies)
image: java:8
pipelines:
default:
- step:
caches:
- gradle
script:
# dependencies
- apt-get update && apt-get -y install file build-essential
# environment vars
- export SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip"
- export ANDROID_HOME="/opt/android-sdk-linux"
- export ANDROID_NDK_HOME="$ANDROID_HOME/ndk-bundle"
- export PATH="$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_NDK_HOME:$PATH"
# download and unzip sdk
- wget -q $SDK_URL -O android-sdk.zip && unzip android-sdk.zip -d $ANDROID_HOME && rm -f android-sdk.zip
# accept all licences http://stackoverflow.com/questions/38096225/automatically-accept-all-sdk-licences
- mkdir -p "$ANDROID_HOME/licenses"
- echo -e "8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
# download ndk
- sdkmanager "ndk-bundle"
# build
- chmod +x gradlew
- ./gradlew assembleDebug
Here is a simplified version
image: umbrela/android-ndk-builder:latest
pipelines:
branches:
master:
- step:
caches:
- gradle
script:
# build
- chmod +x gradlew && ./gradlew assembleDebug
Where umbrela/android-ndk-builder:latest is
FROM java:8
RUN apt-get update \
&& apt-get -y install file build-essential
ENV SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
ENV ANDROID_HOME /opt/android-sdk-linux
ENV ANDROID_NDK_HOME $ANDROID_HOME/ndk-bundle
ENV PATH $ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_NDK_HOME:$PATH
# accept all licences http://stackoverflow.com/questions/38096225/automatically-accept-all-sdk-licences
RUN mkdir -p "$ANDROID_HOME/licenses"
RUN echo 8933bad161af4178b1185d1a37fbf41ea5269c55 > $ANDROID_HOME/licenses/android-sdk-license
RUN echo 84831b9409646a918e30573bab4c9c91346d8abd > $ANDROID_HOME/licenses/android-sdk-preview-license
RUN ls $ANDROID_HOME/licenses
# download and unzip sdk
RUN mkdir -p $ANDROID_HOME \
&& wget -q $SDK_URL -O android-sdk.zip \
&& unzip android-sdk.zip -d $ANDROID_HOME \
&& rm -f android-sdk.zip
# download ndk
RUN sdkmanager "ndk-bundle"
In my bash script I can build my Android Studio project like this:
#!/bin/bash
./gradlew assembleRelease
That creates .apk file in project's build folder but I don't know the path to that folder inside my script.Is there any way to get it?
You could add a line 'finding' it-
path=`find ./ -name "*.apk"`
echo "$path"
If you want the absolute path-
path=`find ./ \`pwd\` . -name "*.apk"`
echo "$path"
Since there's counting views for the question I post the final version of the solution suggested by #Chem-man17
# ---------------- Copy .apk file to output folder -----------------------
mkdir -p "$OUTPUT_DIR"
APK_FILE=`find ${PWD}/app/build/apk -type f -name "*.apk" -printf '%T# %p\n' \
| sort -k 1nr \
| head -n1 \
| sed 's/^[^ ]* //'`
APK_NAME=`echo $APK_FILE | xargs -I{} basename {}`
mv $APK_FILE $OUTPUT_DIR
echo "--- Created file: $OUTPUT_DIR/$APK_NAME"
Basically it sorts .apks in build folder by date and grabs the most recent