My goal is to create a modified version of WebView (call it WebViewCustom) in Android for my personal use in my application. WebView is WebKit based so I need to compile it in C by means of NDK. I am not interested in participating in the open-source Android project now, so my need is just to be able to compile the original C source of WebView and use it as a customized control in my Android application (both SDK and NDK are possible environments for the application). I think it is possible without all that GIT WebKit stuff I am not interested in, but I am not an expert of the Android and WebKit projects. Is it possible to just edit and compile the WebView code and put it in my application as a new control? Can you show me the main steps of this task?
This is certainly possible. The main difficulty in rebuilding android.webkit from source lies in the lack of a correct build environment. It was never intended to be built outside of the target platform, but a couple of simple hacks around the sources make it quite easy to accomplish.
First of all, the whole android.webkit package business has to be renamed for obvious reasons, since an android.webkit.WebView class would already be available during runtime. Use sed on all the frameworks/base/core/java/android/webkit tree for example.
Basically you have to grab the full source tree, initialize a build environment (More information here http://source.android.com/source/initializing.html), make framework to make the internal runtime environment available, create a new development platform, replace all the classes from framework.jar (after building it's in out/target/common/obj/JAVA_LIBRARIES/framework_intermediaries/classes.jar) into android.jar of the platform, build your own webkit package against this new platform that contains the internals.
Check out https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/ for more information on getting an internal runtime available for development purposes.
You will also need core_intermediaries, bouncycastle_intermediaries and others in order to compile webkit, these are all available when make framework is invoked, look at the errors when building your webkit package and grep the out/target/common/obj/JAVA_LIBRARIES/ to figure out which classes contain the symbols.
That's not all, however, the package uses libwebcore.so which exposes native methods to the android.webkit package; this would have to have all native method bindings registered to your new package name (in external/webkit/WebKit/android/jni) and be recompiled without prelinking (make libwebcore) and packaged with your application as a native library.
After everything is satisfied, you would then use your own WebView class from your own package instead of the android.webkit one. If you intend to replace android.webview completely - you would have to recompile a framework.jar and replace it inside system/framework/ (root privileges required).
Related
I am currently working on an Android AOSP project for which I am developing a java module which will be a part of the core services (such as the Phone app, for example).
There are some frameworks I use which are not exposed by default to "regular" apps (which lay in the private framework.jar).
For example: There are places I directly use android.app.IActivityManager's Binder API.
I do own the platform keys, but I not prefer compiling the whole AOSP framework each time I want to make a change.
I also prefer working with Android Studio, but will compromise on compiling the application through the terminal, if not possible.
What is the correct way of working on a project of this kind?
How do AOSP's developers develop their code without re-compiling the whole framework each time?
Update:
The best way I've found so far is to simply create an android studio project, get the framework.jar from the device (adb pull /system/framework/framework.jar) or from the AOSP source code, and add it as a compileOnly or runtimeOnly dependency in the gradle.build file of your app.
dependencies {
compileOnly files('libs/framework.jar')
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
Then just add android:sharedUserId="android.uid.system" to the Android Manifest and compile it using the platform keys.
It should be installable as is.
This post seems to sum it up pretty good:
https://kwagjj.wordpress.com/2017/10/27/building-custom-android-sdk-from-aosp-and-adding-it-to-android-studio/comment-page-1/
Is there any other way?
You can wrap those API callings to a new manager and service. For example, you have a manager called CustomManager, and it will call IActivityManager or other private/hidden API directly. And then you can create a module for you CustomManager, and build jar/aar for it. After every changing, you can copy that generated jar/aar file to you AndroidStudio project. You can use it as a normal library. Actually, there are some examples in AOSP source code, such as SystemUISharedLib, wrapper of SystemUI internal API, used by Launcher3.
I'd like to create small Excel worksheet from an android application using Mono for Android.
I tried using both EPPlus and ExcelLibrary .NET libraries, however I'm having trouble building the project:
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2,2): Error: Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Perhaps it doesn't exist in the Mono for Android profile?
Is there any fix for that or other way to manipulate Excel files through Mono for Android ?
Thanks.
It looks like you are trying to reference a pre-built .NET 4.0 assembly into your Mono for Android project. You can't reliably do this (sometimes it works if you get lucky). MonoTouch and Mono for Android do not have a System.Drawing assembly, so you can't use libraries that link to it.
What you'll need to do is create a new project for the EPPlus or ExcelLibrary libraries and use the Mono for Android Library Project type. You'll probably also need to make some modifications to the project such that it doesn't use the parts of System.Drawing that Mono for Android don't have (it has a few bits and pieces like System.Drawing.RectangleF and SizeF, but is missing most of it).
I was going to work on doing this for MonoTouch using the npoi project (which has a more agreeable license than EPPlus), but have been too busy with other things.
I've got a fork of npoi that I'm working on cleaning up the API here: https://github.com/jstedfast/npoi/tree/enumification
Once I finish that and get that merged upstream, my plan is to create a new branch where I will be working on porting the library to the subset of .NET that MonoTouch and Mono4Android use. I'll probably call it "mobile" or something.
In the meantime, the quick and dirt fix is to just create a new Mono for Android Library project, add all the source files to it in the same way that npoi has, and then try building. It will fail, but the errors will give you a good starting point for figuring out which parts of the library to rip out mercilessly. Keep doing that until it compiles.
If you use either of the npoi repositories that I linked to above, I've already done some of the work to make font.metrics and some other resource file I can't think of build properly for MonoTouch/Android, so there will be a little less work to do than if you use a release like 1.2.5.
Can somebody help me write Android.mk for LibXtract or point me in correct directoin?
Here is source for lib - https://github.com/jamiebullock/LibXtract.git
Or mayby there is a way to use linux generated shared objects in Android?
Especially for bigger established projects, crafting Android.mk files is quite an effort. More so, if you are not familiar with Android NDK build architecture whose understanding requires digging deep into the documentation and Android NDK make files. I would suggest trying to use existing make files by setting CC to point to your NDK tool chain, and CFLAGS += -sysroot $(SYSROOT) where SYSROOT=${NDK_INSTALL_DIR}/platforms/android-<level>/arch-<arch>/ (depending on targeted Android API version and architecture). Even without knowing about your library, I would bet you should have good chance of success this way. Android NDK documentation (${NDK_INSTALL_DIR}/doc/STANDALONE-TOOLCHAIN.html) details the use of independent tool chain and also instructs how to create a standalone tool chain that will not require the use of -sysroot argument to xxx-gcc.
If you decide to use Android.mk instead, you might check existing projects -CSipSimple comes to my mind (PJSIP converted from standard form GNU make files).
Important is to create the shared objects using Android tool chains. It is possible to build them outside of your application source tree, and then just copy the shared objects into the package source libs/<architecture>/ directory.
Integration with your build system depends on details that are not known (including how smooth you desire this whole integration to be e.g. because of other people working with the same project). If you are creating an application from command line, the easiest would be to have GNU make file or shell script in the package root directory ensure libXtract.so and your application package is up-to-date by calling libXtract make file and ant to build and pack your Java application. If you are using ant there should be a way to specify using make to take care of libXtract.so. I am not sure if eclipse is completely relying on ant for building an application to know if this would be enough for enabling complete build by clicking mouse buttons from within eclipse, too.
The answer to this question says you could use cmake script to build Android.mk files - I have not tried this approach.
is there any guide how to use ANTLR on Android? I have found some ANTLR portation for Android but it looks like being without any tutorial or manual. Do you know where to find some? (and yes, I have been googling...)
Thx
After reading the README from this ANTLR port:
AntlrJavaRuntime - Earlence Fernandes, The CRePE Project, VU Amsterdam
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Runtime is available as an external library against which apps can link.
It provides the necessary mechanisms to execute Lexer/Parser code generated by the ANTLR tool.
The model is offline, in the sense that the parser/lexer is generated off the mobile phone on a desktop computer.
The resulting files are transferred to an Android project which then uses this library.
Building
~~~~~~~~
lunch the appropriate target
make AntlrJavaRuntime
verify that AntlrJavaRuntime.xml was placed in /system/etc/permissions and AntlrJavaRuntime.jar was placed in /system/framework
after this, you can run a normal make
It seems to me that the only difference is when you want to run your parser on an Android device (or -emulator) you must include the AntlrJavaRuntime in your Android project/app.
So, writing the grammar, generating a parser and lexer from said grammar would be the same as on a "normal" machine. Here's a previous Q&A that shows how to write a simple expression parser: ANTLR: Is there a simple example?
EDIT
Also see this Q&A: android ANTLR make not working properly
I'm not sure what "using ANTLR" means to you. Here's what it means to me:
I'm assuming that you will create a grammar, generate the parser/lexer Java classes, compile them, deploy them in your Android app, and then let them parse whatever your app sends into an AST.
If you want to know how to do that, there's no better place than the ANTLR documentation or the book you can buy from Amazon.
There is an Android Studio (actually IntelliJ) plug-in for this, called "ANTLR v4 grammar plugin".
This tutorial worked for me.
In short, simply copy grammar (a .g4 file) into your project, right-click on it > Configure ANTLR...
From there you can select to generate Java or Kotlin files, which will compile and run once you added the runtime in your dependencies:
implementation 'org.antlr:antlr4-runtime:4.7'
I am interested in integrating Scala (or some other non-Java JVM-language) into the android platform. I am not referring to writing an android application with Scala, that I did early early on, but actually hooking into the build process that builds the android platform source tree. I imagine this will be a matter of hooking into the makefiles and such. Does anyone have insight into this?
What I have so far:
The platform source treefrom git://android.git.kernel.org/platform/manifest.git built in its virgin form, guided by "[Download and build the Google Android][1]"
build/core/combo/scalac.mk # Configures scala compiler related variables, included by config.mk
Added definitions in build/core/definitions.mk for an all-subdir-scala-files and an all-scala-files-under
Added definition in definitions.mk to build scala files such that they are included in the package
What's left:
Include scala-library.jar
Ensure changes to -bootclasspath has not broken anything
Figure out how to handle case where scala classes depend on java classes and visa versa
Major cleanup of code
Testing!
Figure out what to do (other than just posting them here) with the changes I've made
Looks like I'm almost there!!!
Some notes from the past
Latest: I have found where the Java source files are compiled! In definitions.mk, see 'define transform-java-to-classes.jar'. The latest idea is to write a transform-scala-to-classes definition and then have it store those classes in the directly that gets packaged. I will call transform-scala-to-class right before this step in transform-java-to-classes.jar. Support for eclipse and cygwin will for now be dropped as it clutters up the code with workarounds and therefore increases my chances of failure.
The build process starts out by the root Makefile running build/core/main.mk
build/core/main.mk includes build/core/config.mk which includes build/core/combo/javac.mk which sets HOST_JAVAC, TARGET_JAVAC, and COMMON_JAVAC. COMMON_JAVAC is the "Java compiler command with common arguments," by the look of it the other two variables get these values by default, unless in a special environment (openjdk or eclipse). COMMON_JAVAC is not used outside this file. The other two are only used in build/core/definitions.mk.
build/core/java_library.mk (included by config.mk) seems to only be concerned with building jars. This is out of the scope of us caring. Any interaction with jars presupposes class files which presuppose that we were already successful in building our scala files.
There are checks in main.mk regarding the version of java. We will ignore these and assume that our version of scala is compatible. Right now (in combo/scalac.mk) I am using the same --target arg used in javac.mk. This should perhaps be stored in a variable.
main.mk also includes build/core/definitions.mk which in turns defines some useful functions. The one we care about here is all-java-files-under and all-subdir-java-files. The latter is used in Android.mk files to find java files. The former is used in the implementation of the latter. I will write Scala equivalents of them.
To figure out how the build process works, I am now running make with -n and others. I got this idea from the stackoverflow article "[Tool for debugging makefiles][2]". I am also investigating debugging with remake.
build/core/{config.mk, definitions.mk} gives us light as to which make files/commands are used to do what.
As a possible way of hacking in support on a per project bases, additional code could most likely be added to the project's Android.mk file. From platform/build/core/build-system.html we read "Android.mk is the standard name for the makefile fragments that control the building of a given module. Only the top directory should have a file named "Makefile"." You could create a new target like "scala-build" and run that (make PackageName scala-build) before the final make. One could perhaps also hide it sneakily in a variable assignment, mitigating the need for a target to be called explicitly.
Another way (far far more hackish) is to hijack the command being used for javac. This is set in build/core/combo/javac.mk. Your project's Android.mk will have to include *.scala files in LOCAL_SRC_FILES along with the *.java files.
Guys on reddit say, there's a tutorial on integration Scala into Android with ant here.