Modern XML Parser for Android

Overview

Work in Progress

Please note that this is still work in progress!, although quite stable and used in production. CircleCI

TikXML

A fast xml parser for android (and java)

implementation 'com.tickaroo.tikxml:annotation:0.8.15'
implementation 'com.tickaroo.tikxml:core:0.8.15'

annotationProcessor 'com.tickaroo.tikxml:processor:0.8.15'

For pure java project use this apt plugin

For koltin project (android or pure) use kotlin-kapt plugin and use kapt instead of annotationProcessor in dependencies section of build.gradle.

(NOTE: In IDEA for non-android project this won't run annotation processor if you didn't set project to delegate build to gradle)

For retrofit2:

implementation 'com.tickaroo.tikxml:retrofit-converter:0.8.15'

Also, an AutoValue extension is available:

annotationProcessor 'com.tickaroo.tikxml:auto-value-tikxml:0.8.15'

Latest snapshot 0.9.0_11-SNAPSHOT available:

repositories {
  mavenCentral()
  maven {
    url 'http://oss.sonatype.org/content/repositories/snapshots'
  }
}

Documentation

The documentation (<= 0.8.x) can be found here

The documentation (>= 0.9.x) can be found here

Benchmark

We did benchmark on this early version of TikXml to compare field's results with other popular xml parsers like SimpleXml and Jackson. TikXml is working around 1,9 times faster than jackson and 4,3 times faster than SimpleXml by also having a low memory footprint: Benchmark

TikXml has been built on top of Okio and therefore is highly optimized for Retrofit2.

License

Copyright 2015 Tickaroo

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Releasing on Maven Central

If you are a Tickaroo employee and you want to release a new version on Maven Central, take a look at this document

Comments
  • onResponse doesn´t called after adding TikXmlConverterFactory.create

    onResponse doesn´t called after adding TikXmlConverterFactory.create

    Im doing the following to create the TikXml object

    TikXml tikXml = new TikXml.Builder()
                    .exceptionOnUnreadXml(false)
                    .build();
    

    adding the converter factory

    ...
    .addConverterFactory(TikXmlConverterFactory.create(tikXml));
    ...
    

    My object

    @Xml(name = "myroottag", scanMode = ScanMode.ANNOTATIONS_ONLY)
    public class ResultData {
    
        @com.tickaroo.tikxml.annotation.Path("profile")
        @com.tickaroo.tikxml.annotation.Element(name = "user")
        private User mUser;
    
    }
    
    @Xml(scanMode = ScanMode.ANNOTATIONS_ONLY)
    public class User extends RealmObject implements IIdentifyable {
    
        @PrimaryKey
        @PropertyElement(name = "id")
        private int mIdentifier;
    }
    
    opened by FabianTerhorst 41
  • java.lang.ArrayIndexOutOfBoundsException size=1 offset=1 byteCount=1

    java.lang.ArrayIndexOutOfBoundsException size=1 offset=1 byteCount=1

    On parsing content i receive

    java.lang.ArrayIndexOutOfBoundsException
    size=1 offset=1 byteCount=1
    at okio.Util.checkOffsetAndCount(Util.java:30) 
    at okio.Buffer.getByte(Buffer.java:302)
    ...
    
    opened by maxlord 23
  • Caused by: com.tickaroo.tikxml.TypeAdapterNotFoundException: No TypeAdapter for class found.

    Caused by: com.tickaroo.tikxml.TypeAdapterNotFoundException: No TypeAdapter for class found.

    Here is app build.gradle:

    buildscript {
        repositories {
            maven { url 'https://maven.fabric.io/public' }
        }
    
        dependencies {
            classpath 'io.fabric.tools:gradle:1.27.0'
        }
    }
    
    apply plugin: 'com.android.application'
    apply plugin: 'io.fabric'
    
    repositories {
        maven { url 'https://maven.fabric.io/public' }
    }
    
    def versionMajor = 1 //up to 9
    def versionMinor = 0 //up to 9
    def versionBuild = 12 //up to 999
    
    android {
        compileSdkVersion 28
        buildToolsVersion '28.0.3'
        defaultConfig {
            applicationId "com.myapp"
            minSdkVersion 21
            targetSdkVersion 28
            versionCode versionMajor * 10_000 + versionMinor * 1_000 + versionBuild
            versionName "${versionMajor}.${versionMinor}.${versionBuild}"
            multiDexEnabled true
        }
    
        android.applicationVariants.all { variant ->
            variant.outputs.all { output ->
                outputFileName = "${parent.name}-${variant.versionName}-${variant.versionCode}.apk"
            }
        }
    
        lintOptions {
            checkReleaseBuilds false
            abortOnError false
        }
    
        dataBinding {
            enabled = true
        }
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    
        signingConfigs {
            debug {
                storeFile file("keys/debug.jks")
                storePassword "android"
                keyAlias "androiddebugkey"
                keyPassword "android"
            }
        }
    
        buildTypes {
            debug {
                minifyEnabled false
                debuggable true
                signingConfig signingConfigs.debug
                buildConfigField "String", "API_ENDPOINT", "\"https://my.api.endpoint/\""
                buildConfigField "String", "GOOGLE_MAP_API_ENDPOINT", "\"https://maps.googleapis.com/maps/api/\""
                buildConfigField "String", "GOOGLE_PLACE_API_KEY", "\"some_google_api_key\""
            }
        }
    }
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation files('libs/mail.jar')
        implementation files('libs/activation.jar')
        implementation('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {
            transitive = true
        }
        implementation 'com.google.android.gms:play-services-maps:16.0.0'
        implementation 'com.google.android.gms:play-services-places:16.0.0'
        implementation 'com.google.android.gms:play-services-location:16.0.0'
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation 'com.android.support:design:28.0.0'
        implementation 'com.android.support:multidex:1.0.3'
        implementation 'com.android.support:support-v4:28.0.0'
        implementation 'com.android.support:cardview-v7:28.0.0'
        implementation 'com.google.android:flexbox:0.1.2'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
        implementation 'com.jakewharton:butterknife:8.8.1'
        implementation 'com.squareup.retrofit2:retrofit:2.4.0'
        implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
        implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
        implementation 'com.squareup.okhttp3:okhttp:3.11.0'
        implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
        implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.11.0'
        implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
        implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
        implementation 'com.facebook.stetho:stetho:1.5.0'
        implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'
        implementation 'me.ydcool.lib:qrmodule:1.0'
        implementation 'com.google.firebase:firebase-messaging:17.3.4'
        implementation 'com.google.firebase:firebase-core:16.0.6'
        implementation 'com.github.simbiose:Encryption:2.0.0'
        implementation 'org.greenrobot:eventbus:3.0.0'
        implementation 'com.github.bumptech.glide:glide:4.7.1'
        implementation 'q.rorbin:badgeview:1.1.2'
        implementation 'jp.wasabeef:recyclerview-animators:2.2.7'
        annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
        annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    
        implementation 'com.tickaroo.tikxml:retrofit-converter:0.8.16-SNAPSHOT'
        implementation 'com.tickaroo.tikxml:annotation:0.8.16-SNAPSHOT'
        implementation 'com.tickaroo.tikxml:core:0.8.16-SNAPSHOT'
        annotationProcessor 'com.tickaroo.tikxml:processor:0.8.16-SNAPSHOT'
    }
    
    apply plugin: 'com.google.gms.google-services'
    

    Here is myApp build.gradle:

    
    buildscript {
        repositories {
            jcenter()
            maven {
                url 'https://maven.google.com/'
                name 'Google'
            }
            mavenCentral()
            maven {
                url 'http://oss.sonatype.org/content/repositories/snapshots'
            }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.2.1'
            classpath 'com.google.gms:google-services:4.2.0'
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
            mavenCentral()
            maven {
                url 'http://oss.sonatype.org/content/repositories/snapshots'
            }
            maven { url 'https://jitpack.io' }
            maven {
                url "https://maven.google.com"
            }
            maven {
                url 'https://maven.google.com/'
                name 'Google'
            }
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    

    Here is my gradle.properties:

    org.gradle.daemon=true
    org.gradle.configureondemand=true
    org.gradle.parallel=true
    org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
    android.buildCacheDir=/home/alex/AndroidStudioProjects/myApp_cache
    

    I'm trying to send request via Retrofit2 + RxJava2:

    public interface SomeApi {
    	@POST("SomeService")
    	Observable<Response<PostAuthResponseEnvelope>> login(@Body PostAuthRequestEnvelope body);
    }
    
    @Xml(name="Envelope")
    public class PostAuthRequestEnvelope {
    	@PropertyElement (name = "Body")
    	private String body;
    
    	public String getBody() {
    		return body;
    	}
    	public void setBody(String body) {
    		this.body = body;
    	}
    }
    

    Here is logcat:

    01-04 12:17:44.661 22973-22973/com.myapp W/System.err: java.lang.RuntimeException: Unable to convert com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope@237b3ad2 to RequestBody
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:357)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.ServiceMethod.toCall(ServiceMethod.java:110)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.OkHttpCall.execute(OkHttpCall.java:167)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:10981)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at java.lang.Thread.run(Thread.java:818)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err: Caused by: com.tickaroo.tikxml.TypeAdapterNotFoundException: No TypeAdapter for class com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope found. Expected name of the type adapter is com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.TypeAdapters.get(TypeAdapters.java:112)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.TikXmlConfig.getTypeAdapter(TikXmlConfig.java:85)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.TikXml.write(TikXml.java:128)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.TikXml.write(TikXml.java:121)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:45)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:34)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err:     at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:355)
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err: 	... 12 more
    01-04 12:17:44.661 22973-22973/com.myapp W/System.err: Caused by: java.lang.ClassNotFoundException: com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.Class.classForName(Native Method)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.Class.forName(Class.java:308)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.Class.forName(Class.java:272)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at com.tickaroo.tikxml.TypeAdapters.get(TypeAdapters.java:88)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: 	... 18 more
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter" on path: DexPathList[[zip file "/data/app/com.myapp-2/base.apk", zip file "/data/app/com.myapp-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: 	... 22 more
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: 	Suppressed: java.lang.ClassNotFoundException: com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.Class.classForName(Native Method)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: 		... 23 more
    01-04 12:17:44.671 22973-22973/com.myapp W/System.err: 	Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
    01-04 12:17:44.671 22973-22973/com.myapp E/<-- myappApp -->: Unable to convert com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope@237b3ad2 to RequestBody
        java.lang.RuntimeException: Unable to convert com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope@237b3ad2 to RequestBody
            at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:357)
            at retrofit2.ServiceMethod.toCall(ServiceMethod.java:110)
            at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184)
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:167)
            at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
            at io.reactivex.Observable.subscribe(Observable.java:10981)
            at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
         Caused by: com.tickaroo.tikxml.TypeAdapterNotFoundException: No TypeAdapter for class com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope found. Expected name of the type adapter is com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
            at com.tickaroo.tikxml.TypeAdapters.get(TypeAdapters.java:112)
            at com.tickaroo.tikxml.TikXmlConfig.getTypeAdapter(TikXmlConfig.java:85)
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:128)
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:121)
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:45)
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:34)
            at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:355)
            at retrofit2.ServiceMethod.toCall(ServiceMethod.java:110) 
            at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184) 
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:167) 
            at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
            at io.reactivex.Observable.subscribe(Observable.java:10981) 
            at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
            at java.lang.Thread.run(Thread.java:818) 
         Caused by: java.lang.ClassNotFoundException: com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:308)
            at java.lang.Class.forName(Class.java:272)
            at com.tickaroo.tikxml.TypeAdapters.get(TypeAdapters.java:88)
            at com.tickaroo.tikxml.TikXmlConfig.getTypeAdapter(TikXmlConfig.java:85) 
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:128) 
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:121) 
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:45) 
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:34) 
            at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:355) 
            at retrofit2.ServiceMethod.toCall(ServiceMethod.java:110) 
            at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184) 
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:167) 
            at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
            at io.reactivex.Observable.subscribe(Observable.java:10981) 
            at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
            at java.lang.Thread.run(Thread.java:818) 
         Caused by: java.lang.ClassNotFoundException: Didn't find class "com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter" on path: DexPathList[[zip file "/data/app/com.myapp-2/base.apk", zip file "/data/app/com.myapp-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.myapp-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
            at java.lang.Class.classForName(Native Method) 
            at java.lang.Class.forName(Class.java:308) 
            at java.lang.Class.forName(Class.java:272) 
            at com.tickaroo.tikxml.TypeAdapters.get(TypeAdapters.java:88) 
            at com.tickaroo.tikxml.TikXmlConfig.getTypeAdapter(TikXmlConfig.java:85) 
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:128) 
            at com.tickaroo.tikxml.TikXml.write(TikXml.java:121) 
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:45) 
            at com.tickaroo.tikxml.retrofit.TikXmlRequestBodyConverter.convert(TikXmlRequestBodyConverter.java:34) 
            at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:355) 
            at retrofit2.ServiceMethod.toCall(ServiceMethod.java:110) 
            at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184) 
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:167) 
            at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
            at io.reactivex.Observable.subscribe(Observable.java:10981) 
            at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38) 
            at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
            at java.lang.Thread.run(Thread.java:818) 
        	Suppressed: java.lang.ClassNotFoundException: com.myapp.data.net.rest.request.post_auth_request.PostAuthRequestEnvelope$$TypeAdapter
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
            		... 23 more
         Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
    

    I have been trying to figure out what is going wrong for a couple days, but still no result=((

    opened by alex-podolian 23
  • Specify order of elements/attributes

    Specify order of elements/attributes

    I sometimes need to be able to set a specific order of elements when serializing XML. Unless I've missed a method to achieve that right now, it would be helpful to introduce an annotation similar to the Simple framework's @Order annotation.

    opened by red-coracle 19
  • TypeAdapterNotFoundException

    TypeAdapterNotFoundException

    I am using this library with Retrofit2 and receiving error:

    com.tickaroo.tikxml.TypeAdapterNotFoundException: No TypeAdapter for class App

    This my XML:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <app>
        <version>5</version>
    </app>
    

    this is my App class for which I am expecting the converter to convert XML to this App object:

    @Xml(name = "app")
    public class App {
        @PropertyElement
        public int version;
    }
    

    I am building the Retrofit TikXML converter factory like this:

    new Retrofit.Builder()
    .addConverterFactory(TikXmlConverterFactory.create());
    

    Here is the interface for Retrofit that calls the URL to fetch and parse data. I am using with RxJava2:

    @GET("/apps/config.xml")
        Single<App> getApp();
    

    Am I missing something?

    opened by zishanj 16
  • [WIP] Convert project to gradle build system

    [WIP] Convert project to gradle build system

    Almost everything is working, but publishing to maven repository and pom.xml customization is little riddle for me.

    I will update this soon, if you think this is good idea.

    opened by WeaponMan 14
  • Default constructor fix

    Default constructor fix

    I have today problem with error: Class X must provide an public empty (parameter-less) constructor

    when the class has valid empty constructor inherited from java.lang.Object.

    Example:

    @Xml
    class AAction {
    }
    
    @Xml
    class BAction {
    }
    
    @Xml(name = "event")
    public class Event {
        @Path("action")
        @Element(typesByElement = {
         @ElementNameMatcher(name = "aaction", type = AAction.class),
                @ElementNameMatcher(name = "baction", type = BAction,class)
        })
        public Object action;
    }
    
    opened by WeaponMan 11
  • TypeAdapter Not found exception

    TypeAdapter Not found exception

    I am working on Android project.

    @Xml(name = "Info") public class Info {

    @Attribute(name="type")
    String type;
    @Attribute(name="id")
    String id;
    @Attribute(name = "date")
    String date;
    

    }

    Added below dependencies in build file -------------------------------------------------------------- compile "com.tickaroo.tikxml:annotation:0.8.13" compile "com.tickaroo.tikxml:core:0.8.13" annotationProcessor "com.tickaroo.tikxml:processor:0.8.13"

    compile 'com.squareup.retrofit2:retrofit:2.4.0'
    compile "com.tickaroo.tikxml:retrofit-converter:0.8.13"
    

    Added below proguard rules ------------------------------------------ -keep class com.tickaroo.tikxml.** { *; } -keep @com.tickaroo.tikxml.annotation.Xml public class * -keep class **$$TypeAdapter { *; }

    -keepclasseswithmembernames class * { @com.tickaroo.tikxml.* ; } -keepclasseswithmembernames class * { @com.tickaroo.tikxml.* ; }

    Still, Application is not generating Type adapter class for Info class. Am I missing any thing else?

    opened by SindhuKonda 8
  • [WIP] Make possible to collect skipped elements/bodyTexts/atrributes to list

    [WIP] Make possible to collect skipped elements/bodyTexts/atrributes to list

    Build on top of gradle pull request. We have have customer at work and I must provide some log to show how many xml was skipped. I am not sure if you accept this idea. Please take look at the changes.

    opened by WeaponMan 8
  • exception while reading rss feed

    exception while reading rss feed

    I get this exception with custom converter in retrofit:

    java.lang.AssertionError: Unknown XmlToken: Peeked = 0 at com.tickaroo.tikxml.XmlReader.peek(XmlReader.java:149) at com.tickaroo.tikxml.XmlReader.beginElement(XmlReader.java:341) at com.tickaroo.tikxml.TikXml.read(TikXml.java:110)

    opened by namdroid 7
  • Unterminated comment at path /

    Unterminated comment at path /

    I am receiving a response with the following structure:

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE response SYSTEM 'response.dtd'>
    <response version='1.0'>
        <id>60</id>
        <errorcode>0</errorcode>
         <response>
             <result>
     	     <element>1</element>
     	     <errorcode>0</errorcode>
     	     <value>{&quot;links&quot;:{&quot;url&quot;:&quot;http://url.com&quot;},&quot;data&quot;:{&quot;no&quot;:null,&quot;id&quot;:&quot;someId&quot;}}</value>
            </result>
        </response>
    </response>
    

    The value element contains what is suppose to be JSON, containing a few properties such as url. Note that the example url provided above is not what is actually returned. Unfortunately as the URL contains sensitive data, I can not post it here.

    When this response is received, the following exception occurs:

    java.io.IOException: Unterminated comment at path /
         at com.tickaroo.tikxml.XmlReader.syntaxError(XmlReader.java:848)
         at com.tickaroo.tikxml.XmlReader.nextNonWhitespace(XmlReader.java:808)
         at com.tickaroo.tikxml.XmlReader.doPeek(XmlReader.java:253)
         at com.tickaroo.tikxml.XmlReader.beginElement(XmlReader.java:326)
         at com.tickaroo.tikxml.TikXml.read(TikXml.java:110)
    

    Here is a snippet of the relevant source code:

    if (peek == '!' && fillBuffer(4)) {           
      // skip xml comments <!-- comment -->       
      // consume opening comment chars            
      buffer.readByte(); // '<'                   
      buffer.readByte(); // '!'                   
      buffer.readByte(); // '-'                   
      buffer.readByte(); // '-'                   
      if (!skipTo("-->")) {                       
        throw syntaxError("Unterminated comment");
      }
    
      // ...
    }                                           
    

    It appears that the parser thinks a comment begins somewhere in the response and attempts to skip it, however fails when it does not find a String matching -->.

    I had planned to use a custom converter for the element containing the JSON, however the exception occurs before any of the code in the custom converter is called.

    I do not see the beginning of a comment (<!--) anywhere in the response. Why is this exception occurring, and how can it be fixed?

    opened by Orbyt 7
  • Support for empty lists

    Support for empty lists

    @Xml(name = "list")
    data class TaskList(
        @Attribute
        var id: String,
    
        @Element
        var taskseries: List<TaskSeries>
    )
    

    Fails on

        <list id="45104215"/>
    

    With

    java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter taskseries
    

    Is the only solution to make the list nullable? I consider this an empty list rather than a null list.

    opened by yschimke 1
  • addTypeConverter

    addTypeConverter

    The tikxml is working with retrofit but its not converting the "&amp;" in the xml. I'm trying to follow the docs to add the HtmlEscapeStringConverter

    TikXml.Builder()
                   .addTypeConverter(String.class, new HtmlEscapeStringConverter()) // HtmlEscapeStringConverter encode / decode html characters. This class ships as optional dependency
                   .build();
    

    it also seems to expect a name for "String.class" parameter and has an issue with "no value passed for parameter 'converterForClass' but i think that has to do with this next part:

    i also put in to my build.gradle file just at top level (also tried under application):

     kapt {
        arguments {
            primitiveTypeConverters "java.lang.String, int, java.lang.Integer"
        }
    }
    

    and this is the error im receiving

    Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
    > Could not create task ':app:kaptDebugKotlin'.
       > Could not find method primitiveTypeConverters() for arguments [java.lang.String] on extension 'kapt' of type org.jetbrains.kotlin.gradle.plugin.KaptExtension
    

    Im using version:

        // TikXML
        implementation 'com.tickaroo.tikxml:annotation:0.8.13'
        implementation 'com.tickaroo.tikxml:core:0.8.13'
        implementation 'com.tickaroo.tikxml:retrofit-converter:0.8.13'
        implementation 'com.tickaroo.tikxml:converter-htmlescape:0.8.13'
        kapt 'com.tickaroo.tikxml:processor:0.8.13'
    

    I also tried using 0.8.15 and the newer Snapshot versions but gradle couldn't find them even tho i did

    repositories {
      mavenCentral()
      maven {
        url = 'http://oss.sonatype.org/content/repositories/snapshots'
        allowInsecureProtocol = true
      }
    }
    

    Any help on getting the TypeConverter to work. I seen a few issues that maybe this was fixed in the newer SNAPSHOT versions, if so can you show me how to get the use the snapshot versions cause gradle can't seem to find them.

    opened by DanGrewal1 0
  • Support for iso-8859-1

    Support for iso-8859-1

    I try to parse an XML that comes from an iso-8859-1 API (somes strings have french accents).

    Unfortunately, tikXml seems only to work with UTF-8.

    I tried to use a TypeConverter :

    `class StringUT8Converter : TypeConverter {

    override fun read(value: String): String {
        return String(value.toByteArray(Charsets.ISO_8859_1), Charsets.UTF_8)
    }
    
    override fun write(value: String): String {
        return String(value.toByteArray(Charsets.UTF_8), Charsets.ISO_8859_1)
    
    }
    

    } ` but it doesn't work.

    Do you think you can include other encodings than UTF-8 (for poor old webservices 😝 )?

    Thx

    opened by qLag 7
  • Dynamic root tag name

    Dynamic root tag name

    I was looking for a simple solution on how to proceed when there are different responses.

    <response1>
      <foo>foo</foo>
    </response1>
    
    <response2>
      <bar>bar</bar>
    </response2>
    

    I could find some info about dynamic element within root, but not the root itself. Is this not supported by this library?

    Feature Request 
    opened by heyarny 6
  • The Future of TikXML

    The Future of TikXML

    As you all have noticed TikXML is not in a good shape anymore. This has various reasons but the main reason probably is that I'm not working for Tickaroo anymore (since more than 2 years), the company where we have started this project. When I left Tickaroo, Tikxml was working good enough and kind of has been seen as feature completed as it worked good enough for the use case at Tickaroo.

    Right now there are some real issues that need to be fixed:

    • Gradle: We migrated the project from maven to gradle. While doing that unfortunately and unnoticed we have broken our CI pipeline. That means no tests were actually run on new PR that have been merged in the meantime although CI did mark the PR as green and we assumed the tests passed. Truth is though that it didn't run the full test suite. That caused some PR's to introduce bugs like #128 #123. Furthermore, it also broke publishing artifacts for some reasons. That is why some artifacts of 0.8.15 are missing.
    • Continious Deployment: Even if Gradle would work our current CI System (Travis CI) has issues with uploading artifacts in parallel (I'm not talking about SNAPSHOTs, I'm talking about real releases). In the past I made much better experience with Circle CI. Therefore, we should migrate everything (Signing keys and stuff like) to Circle CI.
    • We have to fix some real issues like #128 and #123 but this is only possible after we have fixed the 2 points above first.

    That is why 0.8.13 is the last "working" and "stable" release as it has been published in the good old maven days but it lacks some improvements that have been added since then

    When will be release 1.0 be published?

    Obviously we have to fix the points above first but then:

    • Remove @ElementNameMatcher: @Bodo1981 (works at Tickaroo) did already some work on introducing a way to not have to annotate all subclasses in a hierarchy with @ElementNameMatcher but let the Annotation processor figure that out automatically. This adds a much better developer experience as Tickaroo has a lot of multiple data classes that inherit from one base class and every time you add new content you have to add or adjust ``@ElementNameMatcher` all over the place.

    Therefore I would say this is the one missing feature that needs to be added to ship 1.0.

    What comes after 1.0 or in other words what is not included in 1.0 release:

    • Incremental annotation processing: @Bodo1981 already looked into this because it could increase build times BUT it also depends how the removal of @ElementNameMatcher is implemented actually. Also, at Tickaroo most of the model data classes annotated with TikXML (as far as I know) live in one gradle module. Therefore gradle will recompile the whole gradle module anyway independently of incremental or not incremental annotation processor and causing other depending gradle modules to recompile as well. Therefore in the context of Tickaroo incremental annotation processing doesn't have highest priority because it is not the bottleneck BUT of course we acknowledge that others would benefit from incremental annotation porcessing. So I think it makes sense to add support for incremental annotation processing, just not before 1.0 release.
    • Better Kotlin support: TikXML started more than 5 years ago. Back then it has been designed for Java. Once Tickaroo started adopting Kotlin we basically added a quick workaround to TikXML that generates java wrappers under the hood to parse XML and set's the values on the real kotlin class. This is very memory inefficient as for a short period of time you will have 1 kotlin data object and 1 java object in memory representing actually the same piece of parsed xml. This causes gc to run more often as the java object can be garbage collected right after parsing (but TikXML is still much faster than other reflection based xml parsers out there, see benchmarks).
    • Revisit AutoValue support: Autovalue is supported basically be the same workaround as kotlin support (having 2 copies in memory and copying fields from a java pojo to autovalue builder). Again, very memory inefficient but I would also like to challenge if support for AutoValue makes sense in the age of kotlin.
    • Kotlin Multiplatform: No support for that planned right now (and it also looks that kotlinx serialization has no plans to add support for xml so there might be need for it) but if we would ever like to add support for Kotlin Multiplatform we would have to move away from Annotation Processing to Kotlin Compiler Plugin. This also should be taken into account while discussing incremental annotation processing.
    • Increase parsing speed: There is still a lot way of how to improve parsing with smarter data structures like Tries that could speed up parsing further.

    I can take care of Continious Deployment point above and migrate things to CircleCI. The goal is to be able to release SNAPSHOTS and RELEASES from CircleCI whenever we push something to master branch (like accepting a PR) without having to do release management by 1 of the Tickaroo employees who know about the signing credentials.

    For the other points, however, we need your help as we can't do that alone (I certainly cannot dedicate way more time for this project than I did in the past as I personally don't have too much need for TikXML and I don't work for Tickaroo anymore and have a lot of other open source projects going on in addition to ... you know ... life :smile: ). Any contribution is very much welcome and I wanted to thank all contributors so far especially @iNoles and @WeaponMan !

    help wanted discussion 
    opened by sockeqwe 4
Releases(0.8.15)
Owner
Tickaroo
Tickaroo
Apk parser for java

APK parser lib, for decoding binary XML files, getting APK meta info. Table of Contents Features Get APK-parser Usage 1. APK Info 2. Get Binary XML an

Hsiafan 1.1k Dec 18, 2022
Parser and Expression Evaluator for Logic Statements

LogicParser Parser and Expression Evaluator for Logic Statements: The steps behind the whole process of evaluating a given logic statement encompass:

Bărbuț-Dică Sami 1 Dec 8, 2021
🧹 Error correcting parser plugin

Tidyparse The main goal of this project is to speed up the process of learning a new language by suggesting ways to fix source code. Tidyparse expects

breandan 5 Dec 15, 2022
UE Capability parser used by smartphonecombo.it and cacombos.com

UE Capability Parser Warning Work In progress UE Capability parser used by smartphonecombo.it and cacombos.com $ java -jar uecapabilityparser.jar --he

Andrea Mennillo 4 Oct 16, 2022
recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

Sebastian Kaspari 565 Jan 2, 2023
A low intrusive, configurable android library that converts layout XML files into Java code to improve performance

qxml English 一个低侵入,可配置的 Android 库,用于将 layout xml 文件转换为 Java 代码以提高性能。 与X2C的对比 X2C: 使用注解处理器生成View类,使用时需要在类中添加注解,并替换setContentView方法,侵入性较强; 对于布局属性的支持不够完美

null 74 Oct 6, 2022
Map strings from csv to xml file

CsvToXmlMapper While translating your app, your translator provides you with a .csv file containing the translated strings and you wonder how boring a

Abhriya Roy 6 Sep 25, 2021
A modern contacts Android API.

A modern contacts Android API.

Alex Styl 410 Jan 3, 2023
Modern Kotlin version of com.example.semitop7.FireTVStyle keyboard

ftv-style-keyboard Modern Kotlin version of com.example.semitop7.FireTVStyle keyboard Manual activation on FireTV via adb shell: adb shell ime enable

nikk 1 Oct 4, 2022
A modern Wadler/Leijen Prettyprinter

Kotlin port of the Haskell prettyprinter library.

Ben Samuel 2 Dec 14, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
Gesture detector framework for multitouch handling on Android, based on Android's ScaleGestureDetector

Android Gesture Detectors Framework Introduction Since I was amazed Android has a ScaleGestureDetector since API level 8 but (still) no such thing as

null 1.1k Nov 30, 2022
Use Android as Rubber Ducky against another Android device

Use Android as Rubber Ducky against another Android device

null 1.4k Jan 9, 2023
Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Shahid Iqbal 4 Nov 29, 2022
A util for setting status bar style on Android App.

StatusBarUtil A util for setting status bar style on Android App. It can work above API 19(KitKat 4.4). 中文版点我 Sample Download StatusBarUtil-Demo Chang

Jaeger 8.8k Jan 6, 2023
A logger with a small, extensible API which provides utility on top of Android's normal Log class.

This is a logger with a small, extensible API which provides utility on top of Android's normal Log class. I copy this class into all the little apps

Jake Wharton 9.8k Dec 30, 2022
Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.

Disk LRU Cache A cache that uses a bounded amount of space on a filesystem. Each cache entry has a string key and a fixed number of values. Each key m

Jake Wharton 5.7k Dec 31, 2022
a simple cache for android and java

ASimpleCache ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 1、它可以缓存什么东西? 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 b

Michael Yang 3.7k Dec 14, 2022