├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── doc └── Kerkee_思维导图.jpg ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kerkee ├── .cproject ├── .project ├── AndroidManifest.xml ├── build.gradle ├── build.xml ├── ic_launcher-web.png ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── iniparser │ │ ├── INSTALL │ │ ├── Makefile │ │ ├── doc │ │ │ ├── Makefile │ │ │ ├── iniparser.dox │ │ │ └── iniparser.main │ │ ├── html │ │ │ ├── doxygen.css │ │ │ ├── doxygen.png │ │ │ ├── globals_func.html │ │ │ ├── index.html │ │ │ ├── iniparser_8h.html │ │ │ ├── iniparser_8main.html │ │ │ ├── tab_b.gif │ │ │ ├── tab_l.gif │ │ │ ├── tab_r.gif │ │ │ └── tabs.css │ │ ├── src │ │ │ ├── Android.mk │ │ │ ├── dictionary.c │ │ │ ├── dictionary.h │ │ │ ├── iniparser.c │ │ │ └── iniparser.h │ │ └── test │ │ │ ├── Makefile │ │ │ ├── iniexample.c │ │ │ ├── parse.c │ │ │ ├── twisted-errors.ini │ │ │ ├── twisted-genhuge.py │ │ │ ├── twisted-ofkey.ini │ │ │ ├── twisted-ofval.ini │ │ │ └── twisted.ini │ └── util │ │ ├── Android.mk │ │ ├── Common.h │ │ ├── FileSys.c │ │ ├── FileSys.h │ │ ├── NativeUtil.c │ │ ├── NativeUtil.h │ │ ├── md5.c │ │ ├── md5.h │ │ ├── util.cpp │ │ └── util.h ├── libs │ ├── arm64-v8a │ │ ├── libiniparser.so │ │ └── libkerkee_util.so │ ├── armeabi-v7a │ │ ├── libiniparser.so │ │ └── libkerkee_util.so │ ├── x86 │ │ ├── libiniparser.so │ │ └── libkerkee_util.so │ └── x86_64 │ │ ├── libiniparser.so │ │ └── libkerkee_util.so ├── lint.xml ├── proguard-project.txt ├── release.gradle ├── release_maven.gradle └── src │ └── com │ └── kercer │ └── kerkee │ ├── bridge │ ├── KCApiBridge.java │ ├── KCApiBridgeManager.java │ ├── KCArg.java │ ├── KCArgList.java │ ├── KCClass.java │ ├── KCClassParser.java │ ├── KCJSCompileExecutor.java │ ├── KCJSDefine.java │ ├── KCJSError.java │ ├── KCJSExecutor.java │ ├── KCJSObject.java │ ├── KCMethod.java │ ├── KCRegister.java │ ├── KerkeeMethod.java │ ├── event │ │ └── KCEvent.java │ ├── type │ │ ├── KCCallback.java │ │ ├── KCJSCallback.java │ │ ├── KCJSJsonArray.java │ │ ├── KCJSJsonObject.java │ │ ├── KCJSNull.java │ │ ├── KCJSNumber.java │ │ ├── KCJSString.java │ │ ├── KCJSType.java │ │ └── KCReturnCallback.java │ └── xhr │ │ ├── KCXMLHttpRequest.java │ │ └── KCXMLHttpRequestManager.java │ ├── browser │ └── KCJSBridge.java │ ├── downloader │ ├── KCContentLengthInputStream.java │ ├── KCDefaultDownloader.java │ └── KCDownloader.java │ ├── frame │ └── iniparser │ │ └── KCIniparser.java │ ├── imagesetter │ ├── KCDefaultImageStream.java │ ├── KCWebImage.java │ ├── KCWebImageCache.java │ ├── KCWebImageDownloader.java │ ├── KCWebImageHandler.java │ ├── KCWebImageListener.java │ ├── KCWebImageSetter.java │ └── KCWebImageSetterTask.java │ ├── manifest │ ├── KCFetchManifest.java │ ├── KCManifestObject.java │ └── KCManifestParser.java │ ├── net │ ├── KCHTTPDPooled.java │ └── KCHttpServer.java │ ├── util │ ├── KCCusBuffer.java │ ├── KCNativeUtil.java │ └── KCUtil.java │ └── webview │ ├── KCUrlMapper.java │ ├── KCWebChromeClient.java │ ├── KCWebPath.java │ ├── KCWebView.java │ └── KCWebViewClient.java ├── kerkee_example ├── .project ├── AndroidManifest.xml ├── assets │ └── html │ │ ├── conf │ │ ├── urlmapping.conf │ │ └── version.conf │ │ ├── icon.png │ │ ├── kerkee.js │ │ ├── manifest │ │ ├── modules │ │ ├── clientApi │ │ │ ├── clientInfo.js │ │ │ ├── clientUI.js │ │ │ ├── manifest │ │ │ ├── objExampleApi.js │ │ │ ├── testApi.js │ │ │ └── util.js │ │ ├── manifest │ │ └── test │ │ │ ├── manifest │ │ │ ├── test.html │ │ │ ├── test.js │ │ │ └── testDo.js │ │ ├── test.html │ │ └── vendor │ │ ├── api │ │ ├── device │ │ │ └── platform.js │ │ ├── helper │ │ │ └── util.js │ │ └── nativeUI │ │ │ └── widget.js │ │ ├── core │ │ └── require.js │ │ ├── lib │ │ ├── template.js │ │ └── zepto.min.js │ │ └── plugin │ │ └── domReady.js ├── build.gradle ├── ic_launcher-web.png ├── lint.xml ├── proguard-project.txt ├── res │ ├── drawable-hdpi │ │ ├── browser_btn_back.png │ │ ├── browser_btn_back_dis.png │ │ ├── browser_btn_back_pressed.png │ │ ├── browser_btn_forward.png │ │ ├── browser_btn_forward_dis.png │ │ ├── browser_btn_forward_pressed.png │ │ ├── browser_btn_refresh.png │ │ ├── browser_btn_refresh_pressed.png │ │ ├── browser_btn_stop.png │ │ ├── browser_btn_stop_pressed.png │ │ ├── btn_bookmark.png │ │ ├── btn_bookmark_pressed.png │ │ ├── btn_browser_bookmark_normal.png │ │ ├── edit_panel_bg.9.png │ │ ├── ic_launcher.png │ │ ├── nav_icon_goto.png │ │ ├── nav_icon_goto_press.png │ │ └── top_nav_bg.9.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ ├── drawable │ │ ├── btn_browser_control_back_selector.xml │ │ ├── btn_browser_control_bookmark_selector.xml │ │ ├── btn_browser_control_forward_selector.xml │ │ ├── btn_browser_control_refresh_selector.xml │ │ ├── btn_browser_control_stop_selector.xml │ │ └── btn_header_bar_back_selector.xml │ ├── layout │ │ ├── activity_main.xml │ │ ├── browser.xml │ │ ├── fragment_main.xml │ │ └── header_nav_bar.xml │ ├── menu │ │ └── main.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ ├── values-w820dp │ │ └── dimens.xml │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── com │ └── kercer │ └── kerkee │ ├── activity │ └── KCMainActivity.java │ ├── api │ ├── KCApiClientInfo.java │ ├── KCApiClientUI.java │ ├── KCApiJSBridgeClient.java │ ├── KCApiJSObjExample.java │ ├── KCApiPlatform.java │ ├── KCApiTestModule.java │ ├── KCApiWidget.java │ ├── KCJSObjDefine.java │ └── KCRegistMgr.java │ └── browser │ ├── KCDefaultBrowser.java │ └── KCPage.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gen/ 3 | # Android/IJ 4 | obj/ 5 | proguard/ 6 | ##libs/ 7 | .classpath 8 | ##.project 9 | ##.cproject 10 | .settings 11 | pkgs/ 12 | release.keystore 13 | out 14 | *.out 15 | artifacts 16 | project.properties 17 | .svn 18 | build/ 19 | 20 | local.properties 21 | *.iml 22 | .idea/ 23 | .gradle 24 | gradlew* 25 | gradle 26 | Release 27 | Debug 28 | 29 | # Node 30 | node_modules 31 | *.log 32 | .nvm 33 | 34 | ## generic files to ignore 35 | *~ 36 | *.lock 37 | *.DS_Store 38 | *.swp 39 | *.out 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 简介 3 | --- 4 | 5 | # kerkee [ ![Download](https://api.bintray.com/packages/zihong/maven/kerkee/images/download.svg) ](https://bintray.com/zihong/maven/kerkee/_latestVersion) 6 | 7 | ### kerkee框架的诞生背景 8 | Hybrid App兼具了Native App的所有优势,也兼具了Web App使用HTML5跨平台开发低成本的优势。以及具有使用Native扩展Web接口以弥补web无法调用平台性API等优势。Hybrid App也是未来客户端技术的发展趋势。HTML5的出现,市面上已有很多应用(如淘宝、百度搜索、高德地图)使用了Hybrid App的开发模式,但遇到了一些瓶颈(如性能不如预期,无法操作浏览器内部数据流程,无法自定义请求的需求),用户体验没有预期的好。 9 | 基于此,一种新一开发模式诞生了!kerkee框架是市面上唯一的多主体共存的灵活混合型开发模型。 10 | 11 | ### kerkee框架是什么 12 | kerkee是一个多主体共存型Hybrid框架,具有跨平台、用户体验好、性能高、扩展性好、灵活性强、易维护、规范化、集成云服务、具有Debug环境、彻底解决跨域问题。 13 | 14 | ### kerkee官网 15 | - **官网:** [http://www.kerkee.com](http://www.kerkee.com) 16 | 17 | - **github:** [https://github.com/kercer](https://github.com/kercer) 18 | 19 | - **QQ交流群:** 110710084 20 | 21 | 22 | ### 使用kerkee案例 23 | kerkee的Hybrid架构思想已使用在两款亿级用户量及多款千万级用户量的APP上 24 | 25 | - UC游戏大厅 26 | - 九游游戏中心 27 | - 天翼导航 28 | - 搜狐新闻客户端 29 | - 搜狐News SDK(已应用到搜狐视频客户端中) 30 | - 斗米客户端(商户端、用户端、斗米工作助手) 31 | - 汽车之家 32 | 33 | 34 | ### 基于kerkee框架的开发模式 35 | 36 | 从开发者角度来说,它支持三种的团队开发模式: 37 | 38 | >1. **针对Web开发者** 39 |
这种模式其中的一个场景是:只会Web开发,却不会Native开发的开发者提供了一系列的平台型接口。这种方式具有开发周期短,跨平台等优点。 40 | >1. **针对Native开发者** 41 |
这种开发模式的其中一个场景是:Native开发者想要截获Web页面的数据或者对数据进行自己的处理,或者Web页面中的行为进行修改。在这个时候,Kerkee框架将会为他们带来便利。 42 | >1. **针对Web开发者和Native团队共同合作的开发团队** 43 |
对于这种模式的团队,kerkee框架具体更开放更透明的协作,并且严格地隔离各自职责。各得Web团队和Native团队把主要精力定位到各自的模块上,有利于各自的模块优化到极致。 44 | 45 | ### kerkee框架特性和能解决的问题 46 | >1. **跨平台** 47 |
kerkee是Hybrid App框架,业务HTML5开发,HTML5具备了跨平台的特性,因此Kerkee也具备了跨平台的特性。 48 | >1. **用户体验好** 49 |
所有的web接口都可在Native自定义实现,即Web UI或数据操作上若满足不了用户体验,皆可通原生的代码进行实现,以达到较佳的用户体验。 50 | >1. **性能高** 51 |
在性能方面,kerkee框架做了大量的优化,底层网络层、IO操作等皆采用C/C++实现,并且重写了WebView,对Web中资源(如图片资源等)的控制,以事件驱动模型实现资源请求,并且实现一套针对Web的缓存策略,完全抛离webview那一套数据流程的操作。使开发者具有更透明的数据操作,以达到更佳的性能,并且突破了原有开发模式下的性能瓶颈。 52 | >1. **扩展性好** 53 |
kerkee框架采用插件式模块化设计,每个模块即为一个webapp,在需要时可自由扩展。 54 | >1. **灵活性强** 55 |
kerkee内部实现runtime,自动把js接口转化了native接口,Web层与Native层严格隔离达到无耦合状态,开发者对整个流程和接口都是开放透明,无特殊约束。 56 | >1. **易维护** 57 |
kerkee框架使客户端严格模块化,使用了接口式的交互模型,具有动态更新特性,易于维护,便以运营。 58 | >1. **规范化** 59 |
kerkee框架符合W3C标准,重新实现了XMLHttpRequest、WebSocket、LocalStorage、Application Cache等HTML5特性。Web前端开发者只需按W3C标准编写代码即可,即一次编写,到处运行的原则,无任何第三方库依赖。 60 | >1. **Debug工具** 61 |
kerkee内部集成Debug环境,web端log将会打印到控制台或文件中 62 | >1. **彻底解决跨域** 63 |
kerkee框架采用一套特殊机制,解决了跨域问题,也就是说开发者可以操作互联网上任何一个Web页面的数据。 64 | >1. **使客户端架构更清晰** 65 |
kerkee框架会使得客户端的架构更为清晰。整体结构,自上而下分层如下图所示: 66 |
[![client](http://src.linzihong.com/clientframe.jpg)](http://src.linzihong.com/clientframe.jpg) 67 | 68 | >1. **使用简便** 69 |
对于开发者来说,使用简便。 70 |
Web开发者:无需添加其他代码,只需要按W3C规范实现代码即可。若要调用Native接口,只需要调用框架中对应的fuction即可。 71 |
Native开发者:只需要把对应的类注册到Kerkee中即可,代码量不超过5行便可使用Kerkee框架 -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | // mavenCentral() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.3.2' 11 | 12 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2' 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | google() 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /doc/Kerkee_思维导图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/doc/Kerkee_思维导图.jpg -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Wed Apr 17 11:25:37 CST 2019 8 | #for NDK-build 9 | Android.useDeprecatedNdk=true 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Nov 08 18:13:21 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /kerkee/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /kerkee/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kerkee 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | com.android.ide.eclipse.adt.ResourceManagerBuilder 16 | 17 | 18 | 19 | 20 | com.android.ide.eclipse.adt.PreCompilerBuilder 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javabuilder 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.ApkBuilder 31 | 32 | 33 | 34 | 35 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 36 | full,incremental, 37 | 38 | 39 | 40 | 41 | 42 | com.android.ide.eclipse.adt.AndroidNature 43 | org.eclipse.jdt.core.javanature 44 | org.eclipse.cdt.core.cnature 45 | org.eclipse.cdt.core.ccnature 46 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 47 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 48 | 49 | 50 | -------------------------------------------------------------------------------- /kerkee/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /kerkee/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /kerkee/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/ic_launcher-web.png -------------------------------------------------------------------------------- /kerkee/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | subdirs := $(LOCAL_PATH)/util/Android.mk 5 | subdirs += $(LOCAL_PATH)/iniparser/src/Android.mk 6 | 7 | 8 | include $(subdirs) 9 | -------------------------------------------------------------------------------- /kerkee/jni/Application.mk: -------------------------------------------------------------------------------- 1 | #APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64 2 | APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 3 | APP_PLATFORM := android-14 4 | APP_ALLOW_MISSING_DEPS=true -------------------------------------------------------------------------------- /kerkee/jni/iniparser/INSTALL: -------------------------------------------------------------------------------- 1 | 2 | iniParser installation instructions 3 | ----------------------------------- 4 | 5 | - Modify the Makefile to suit your environment. 6 | - Type 'make' to make the library. 7 | - Type 'make check' to make the test program. 8 | - Type 'test/iniexample' to launch the test program. 9 | - Type 'test/parse' to launch torture tests. 10 | 11 | 12 | 13 | Enjoy! 14 | N. Devillard 15 | Wed Mar 2 21:14:17 CET 2011 16 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # iniparser Makefile 3 | # 4 | 5 | # Compiler settings 6 | CC ?= gcc 7 | CFLAGS ?= -O2 8 | CFLAGS += -fPIC -Wall -ansi -std=c99 -pedantic 9 | 10 | # Ar settings to build the library 11 | AR ?= ar 12 | ARFLAGS = rcv 13 | 14 | SHLD = ${CC} ${CFLAGS} 15 | LDSHFLAGS = -shared -Wl,-Bsymbolic 16 | LDFLAGS += -Wl,-rpath -Wl,/usr/lib -Wl,-rpath,/usr/lib 17 | 18 | # Set RANLIB to ranlib on systems that require it (Sun OS < 4, Mac OSX) 19 | # RANLIB = ranlib 20 | RANLIB = true 21 | 22 | RM ?= rm -f 23 | 24 | 25 | # Implicit rules 26 | 27 | SUFFIXES = .o .c .h .a .so .sl 28 | 29 | COMPILE.c ?= $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 30 | 31 | ifndef V 32 | QUIET_AR = @echo "AR $@"; 33 | QUIET_CC = @echo "CC $@"; 34 | QUIET_LINK = @echo "LINK $@"; 35 | QUIET_RANLIB = @echo "RANLIB $@"; 36 | endif 37 | 38 | .c.o: 39 | $(QUIET_CC)$(COMPILE.c) $(OUTPUT_OPTION) $< 40 | 41 | 42 | SRCS = src/iniparser.c \ 43 | src/dictionary.c 44 | 45 | OBJS = $(SRCS:.c=.o) 46 | 47 | 48 | default: libiniparser.a libiniparser.so 49 | 50 | libiniparser.a: $(OBJS) 51 | $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^ 52 | $(QUIET_RANLIB)$(RANLIB) $@ 53 | 54 | libiniparser.so: $(OBJS) 55 | $(QUIET_LINK)$(SHLD) $(LDSHFLAGS) $(LDFLAGS) -o $@.0 $(OBJS) \ 56 | -Wl,-soname=`basename $@`.0 57 | 58 | clean: 59 | $(RM) $(OBJS) 60 | 61 | veryclean: 62 | $(RM) $(OBJS) libiniparser.a libiniparser.so* 63 | rm -rf ./html ; mkdir html 64 | cd test ; $(MAKE) veryclean 65 | 66 | docs: 67 | @(cd doc ; $(MAKE)) 68 | 69 | check: default 70 | @(cd test ; $(MAKE)) 71 | 72 | .PHONY: default clean veryclean docs check 73 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/doc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # iniparser doc Makefile 3 | # 4 | 5 | all: html 6 | 7 | html: 8 | doxygen iniparser.dox 9 | rm -f ../html/annotated.html 10 | rm -f ../html/classes.html 11 | rm -f ../html/doxygen.gif 12 | rm -f ../html/files.html 13 | rm -f ../html/functions.html 14 | rm -f ../html/globals.html 15 | rm -f ../html/iniparser_main.html 16 | 17 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/doc/iniparser.dox: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = iniparser 2 | PROJECT_NUMBER = 3.1 3 | OUTPUT_DIRECTORY = .. 4 | OUTPUT_LANGUAGE = English 5 | EXTRACT_ALL = YES 6 | EXTRACT_PRIVATE = NO 7 | EXTRACT_STATIC = NO 8 | HIDE_UNDOC_MEMBERS = NO 9 | BRIEF_MEMBER_DESC = YES 10 | REPEAT_BRIEF = YES 11 | ALWAYS_DETAILED_SEC = NO 12 | FULL_PATH_NAMES = NO 13 | STRIP_FROM_PATH = 14 | INTERNAL_DOCS = NO 15 | SOURCE_BROWSER = NO 16 | INLINE_SOURCES = NO 17 | STRIP_CODE_COMMENTS = YES 18 | CASE_SENSE_NAMES = YES 19 | HIDE_SCOPE_NAMES = NO 20 | VERBATIM_HEADERS = NO 21 | SHOW_INCLUDE_FILES = NO 22 | JAVADOC_AUTOBRIEF = NO 23 | INHERIT_DOCS = YES 24 | INLINE_INFO = YES 25 | SORT_MEMBER_DOCS = YES 26 | DISTRIBUTE_GROUP_DOC = NO 27 | TAB_SIZE = 4 28 | ENABLED_SECTIONS = 29 | GENERATE_TODOLIST = NO 30 | GENERATE_TESTLIST = NO 31 | ALIASES = 32 | MAX_INITIALIZER_LINES = 30 33 | OPTIMIZE_OUTPUT_FOR_C = YES 34 | QUIET = NO 35 | WARNINGS = YES 36 | WARN_IF_UNDOCUMENTED = YES 37 | WARN_FORMAT = "$file:$line: $text" 38 | WARN_LOGFILE = 39 | INPUT = iniparser.main ../src 40 | FILE_PATTERNS = iniparser.h 41 | RECURSIVE = NO 42 | EXCLUDE = 43 | EXCLUDE_PATTERNS = 44 | EXAMPLE_PATH = 45 | EXAMPLE_PATTERNS = 46 | IMAGE_PATH = 47 | INPUT_FILTER = 48 | FILTER_SOURCE_FILES = NO 49 | ALPHABETICAL_INDEX = YES 50 | COLS_IN_ALPHA_INDEX = 5 51 | IGNORE_PREFIX = 52 | GENERATE_HTML = YES 53 | HTML_OUTPUT = html 54 | HTML_HEADER = 55 | HTML_FOOTER = 56 | HTML_STYLESHEET = 57 | HTML_ALIGN_MEMBERS = YES 58 | GENERATE_HTMLHELP = NO 59 | DISABLE_INDEX = YES 60 | ENUM_VALUES_PER_LINE = 4 61 | GENERATE_TREEVIEW = NO 62 | TREEVIEW_WIDTH = 250 63 | 64 | GENERATE_LATEX = NO 65 | GENERATE_RTF = NO 66 | GENERATE_MAN = NO 67 | 68 | ENABLE_PREPROCESSING = NO 69 | MACRO_EXPANSION = NO 70 | EXPAND_ONLY_PREDEF = NO 71 | SEARCH_INCLUDES = NO 72 | INCLUDE_PATH = 73 | INCLUDE_FILE_PATTERNS = 74 | PREDEFINED = 75 | EXPAND_AS_DEFINED = 76 | TAGFILES = 77 | GENERATE_TAGFILE = 78 | ALLEXTERNALS = NO 79 | PERL_PATH = /usr/bin/perl 80 | HAVE_DOT = NO 81 | SEARCHENGINE = NO 82 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/doxygen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/jni/iniparser/html/doxygen.png -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/globals_func.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | iniparser: Data Fields 6 | 7 | 8 | 9 | 10 | 11 |
12 | 16 |
17 |
18 |   59 |
60 |
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  61 | 62 | doxygen 1.6.3
63 | 64 | 65 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/iniparser_8main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | iniparser: iniparser.main File Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 |

iniparser.main File Reference

13 |
14 |
15 |
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  16 | 17 | doxygen 1.6.3
18 | 19 | 20 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/tab_b.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/jni/iniparser/html/tab_b.gif -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/tab_l.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/jni/iniparser/html/tab_l.gif -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/tab_r.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/jni/iniparser/html/tab_r.gif -------------------------------------------------------------------------------- /kerkee/jni/iniparser/html/tabs.css: -------------------------------------------------------------------------------- 1 | /* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ 2 | 3 | DIV.tabs 4 | { 5 | float : left; 6 | width : 100%; 7 | background : url("tab_b.gif") repeat-x bottom; 8 | margin-bottom : 4px; 9 | } 10 | 11 | DIV.tabs UL 12 | { 13 | margin : 0px; 14 | padding-left : 10px; 15 | list-style : none; 16 | } 17 | 18 | DIV.tabs LI, DIV.tabs FORM 19 | { 20 | display : inline; 21 | margin : 0px; 22 | padding : 0px; 23 | } 24 | 25 | DIV.tabs FORM 26 | { 27 | float : right; 28 | } 29 | 30 | DIV.tabs A 31 | { 32 | float : left; 33 | background : url("tab_r.gif") no-repeat right top; 34 | border-bottom : 1px solid #84B0C7; 35 | font-size : 80%; 36 | font-weight : bold; 37 | text-decoration : none; 38 | } 39 | 40 | DIV.tabs A:hover 41 | { 42 | background-position: 100% -150px; 43 | } 44 | 45 | DIV.tabs A:link, DIV.tabs A:visited, 46 | DIV.tabs A:active, DIV.tabs A:hover 47 | { 48 | color: #1A419D; 49 | } 50 | 51 | DIV.tabs SPAN 52 | { 53 | float : left; 54 | display : block; 55 | background : url("tab_l.gif") no-repeat left top; 56 | padding : 5px 9px; 57 | white-space : nowrap; 58 | } 59 | 60 | DIV.tabs #MSearchBox 61 | { 62 | float : right; 63 | display : inline; 64 | font-size : 1em; 65 | } 66 | 67 | DIV.tabs TD 68 | { 69 | font-size : 80%; 70 | font-weight : bold; 71 | text-decoration : none; 72 | } 73 | 74 | 75 | 76 | /* Commented Backslash Hack hides rule from IE5-Mac \*/ 77 | DIV.tabs SPAN {float : none;} 78 | /* End IE5-Mac hack */ 79 | 80 | DIV.tabs A:hover SPAN 81 | { 82 | background-position: 0% -150px; 83 | } 84 | 85 | DIV.tabs LI.current A 86 | { 87 | background-position: 100% -150px; 88 | border-width : 0px; 89 | } 90 | 91 | DIV.tabs LI.current SPAN 92 | { 93 | background-position: 0% -150px; 94 | padding-bottom : 6px; 95 | } 96 | 97 | DIV.navpath 98 | { 99 | background : none; 100 | border : none; 101 | border-bottom : 1px solid #84B0C7; 102 | text-align : center; 103 | margin : 2px; 104 | padding : 2px; 105 | } 106 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/src/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := iniparser 6 | LOCAL_SRC_FILES := iniparser.c \ 7 | dictionary.c 8 | 9 | #LOCAL_LDLIBS += -llog 10 | 11 | include $(BUILD_SHARED_LIBRARY) 12 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # iniparser tests Makefile 3 | # 4 | 5 | CC = gcc 6 | CFLAGS = -g -I../src 7 | LFLAGS = -L.. -liniparser 8 | AR = ar 9 | ARFLAGS = rcv 10 | RM = rm -f 11 | 12 | 13 | default: all 14 | 15 | all: iniexample parse 16 | 17 | iniexample: iniexample.c 18 | $(CC) $(CFLAGS) -o iniexample iniexample.c -I../src -L.. -liniparser 19 | 20 | parse: parse.c 21 | $(CC) $(CFLAGS) -o parse parse.c -I../src -L.. -liniparser 22 | 23 | clean veryclean: 24 | $(RM) iniexample example.ini parse 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/iniexample.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "iniparser.h" 7 | 8 | void create_example_ini_file(void); 9 | int parse_ini_file(char * ini_name); 10 | 11 | int main(int argc, char * argv[]) 12 | { 13 | int status ; 14 | 15 | if (argc<2) { 16 | create_example_ini_file(); 17 | status = parse_ini_file("example.ini"); 18 | } else { 19 | status = parse_ini_file(argv[1]); 20 | } 21 | return status ; 22 | } 23 | 24 | void create_example_ini_file(void) 25 | { 26 | FILE * ini ; 27 | 28 | ini = fopen("example.ini", "w"); 29 | fprintf(ini, 30 | "#\n" 31 | "# This is an example of ini file\n" 32 | "#\n" 33 | "\n" 34 | "[Pizza]\n" 35 | "\n" 36 | "Ham = yes ;\n" 37 | "Mushrooms = TRUE ;\n" 38 | "Capres = 0 ;\n" 39 | "Cheese = Non ;\n" 40 | "\n" 41 | "\n" 42 | "[Wine]\n" 43 | "\n" 44 | "Grape = Cabernet Sauvignon ;\n" 45 | "Year = 1989 ;\n" 46 | "Country = Spain ;\n" 47 | "Alcohol = 12.5 ;\n" 48 | "\n"); 49 | fclose(ini); 50 | } 51 | 52 | 53 | int parse_ini_file(char * ini_name) 54 | { 55 | dictionary * ini ; 56 | 57 | /* Some temporary variables to hold query results */ 58 | int b ; 59 | int i ; 60 | double d ; 61 | char * s ; 62 | 63 | ini = iniparser_load(ini_name); 64 | if (ini==NULL) { 65 | fprintf(stderr, "cannot parse file: %s\n", ini_name); 66 | return -1 ; 67 | } 68 | iniparser_dump(ini, stderr); 69 | 70 | /* Get pizza attributes */ 71 | printf("Pizza:\n"); 72 | 73 | b = iniparser_getboolean(ini, "pizza:ham", -1); 74 | printf("Ham: [%d]\n", b); 75 | b = iniparser_getboolean(ini, "pizza:mushrooms", -1); 76 | printf("Mushrooms: [%d]\n", b); 77 | b = iniparser_getboolean(ini, "pizza:capres", -1); 78 | printf("Capres: [%d]\n", b); 79 | b = iniparser_getboolean(ini, "pizza:cheese", -1); 80 | printf("Cheese: [%d]\n", b); 81 | 82 | /* Get wine attributes */ 83 | printf("Wine:\n"); 84 | s = iniparser_getstring(ini, "wine:grape", NULL); 85 | printf("Grape: [%s]\n", s ? s : "UNDEF"); 86 | 87 | i = iniparser_getint(ini, "wine:year", -1); 88 | printf("Year: [%d]\n", i); 89 | 90 | s = iniparser_getstring(ini, "wine:country", NULL); 91 | printf("Country: [%s]\n", s ? s : "UNDEF"); 92 | 93 | d = iniparser_getdouble(ini, "wine:alcohol", -1.0); 94 | printf("Alcohol: [%g]\n", d); 95 | 96 | iniparser_freedict(ini); 97 | return 0 ; 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/parse.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "iniparser.h" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | dictionary * ini ; 11 | char * ini_name ; 12 | 13 | if (argc<2) { 14 | ini_name = "twisted.ini"; 15 | } else { 16 | ini_name = argv[1] ; 17 | } 18 | 19 | ini = iniparser_load(ini_name); 20 | iniparser_dump(ini, stdout); 21 | iniparser_freedict(ini); 22 | 23 | return 0 ; 24 | } 25 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/twisted-errors.ini: -------------------------------------------------------------------------------- 1 | # 2 | # All of these should trigger syntax errors 3 | # 4 | [section] 5 | hello 6 | world 7 | hello \ 8 | world 9 | a + b ; 10 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/twisted-genhuge.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import sys 4 | 5 | if __name__=="__main__": 6 | f=open('twisted-massive.ini', 'w') 7 | for i in range(100): 8 | f.write('[%03d]\n' % i) 9 | for j in range(100): 10 | f.write('key-%03d=1;\n' % j) 11 | f.close() 12 | 13 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/twisted-ofval.ini: -------------------------------------------------------------------------------- 1 | # Shitload data size 2 | [long] 3 | a=\ 4 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 5 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 6 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 7 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 8 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 9 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 10 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 11 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 12 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 13 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 14 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 15 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 16 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 17 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 18 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 19 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 20 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 21 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 22 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 23 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 24 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 25 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 26 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 27 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 28 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 29 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 30 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 31 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 32 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 33 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 34 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 35 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 36 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 37 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 38 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 39 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 40 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 41 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 42 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 43 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 44 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 45 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 46 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 47 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 48 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 49 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 50 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 51 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 52 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 53 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 54 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\ 55 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890; 56 | 57 | -------------------------------------------------------------------------------- /kerkee/jni/iniparser/test/twisted.ini: -------------------------------------------------------------------------------- 1 | # 2 | # Twisted.ini 3 | # This file is meant for regression tests 4 | 5 | # Different blank settings around the equal sign 6 | [blanks] 7 | a=1 8 | b=1; 9 | c=1; comment 10 | d=1# comment 11 | 12 | e =1 13 | f =1; 14 | g =1; comment 15 | h =1# comment 16 | 17 | i= 1 18 | j= 1; 19 | k= 1; comment 20 | l= 1# comment 21 | 22 | m = 1 23 | n = 1; 24 | o = 1; comment 25 | p = 1# comment 26 | 27 | q=1 ; 28 | r=1 ; comment 29 | s=1 ;comment 30 | t=1 #comment 31 | 32 | # Empty values 33 | [empty] 34 | a = '' 35 | b = "" 36 | 37 | c = '' ; 38 | d = "" ; 39 | 40 | e = '' ; comment 41 | f = "" ; comment 42 | 43 | g = 44 | h = ; 45 | i = ; comment 46 | j = # comment 47 | 48 | k= 49 | l=; 50 | m=;comment 51 | n=# 52 | 53 | # Peculiar values 54 | [peculiar] 55 | a=';'; 56 | b='#'# 57 | c=';';comment 58 | d='#'#comment 59 | e=\; 60 | f=\# 61 | g=\;comment 62 | h=\#comment 63 | i=;; 64 | j=## 65 | k=;;;;;;;;;; 66 | l=########## 67 | 68 | # Quotes 69 | [quotes] 70 | s1=' 71 | s2='' 72 | s3=''' 73 | s4='''' 74 | 75 | d1=" 76 | d2="" 77 | d3=""" 78 | d4="""" 79 | 80 | m1='"' 81 | m2="'" 82 | 83 | h1=hello'world 84 | h2='hello'world 85 | h3='hello'world' 86 | 87 | h4=hello"world 88 | h5="hello"world 89 | h6="hello"world" 90 | 91 | # Section names 92 | [a] 93 | [ b] 94 | [c ] 95 | [ d ] 96 | [ begin end ] 97 | [ open[ ] 98 | 99 | # Multi-line inputs 100 | [multi] 101 | a = begin\ 102 | end 103 | b = begin \ 104 | end 105 | c = begin \ 106 | end 107 | d = 1\ 108 | 2\ 109 | 3\ 110 | 4 111 | e = 1 \ 112 | 2 \ 113 | 3 \ 114 | 4 115 | f = 1 ; \ 116 | hidden = because of the preceding backslash multi-lining the comment ; 117 | visible = 1 118 | g = 1 #\ 119 | and now this comment is hidden too \ 120 | and this one too 121 | h = 1 122 | multi \ 123 | line \ 124 | key = 1 125 | multi \ 126 | line \ 127 | key = \ 128 | multi \ 129 | line \ 130 | value ; 131 | # end of file 132 | -------------------------------------------------------------------------------- /kerkee/jni/util/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := kerkee_util 6 | LOCAL_SRC_FILES := util.cpp \ 7 | NativeUtil.c \ 8 | FileSys.c \ 9 | md5.c 10 | 11 | LOCAL_LDLIBS += -llog 12 | 13 | include $(BUILD_SHARED_LIBRARY) 14 | -------------------------------------------------------------------------------- /kerkee/jni/util/Common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H 2 | #define _COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | typedef unsigned char KCUInt8; 9 | typedef unsigned short KCUInt16; 10 | typedef char KCInt8; 11 | typedef short KCInt16; 12 | typedef long KCInt; 13 | typedef unsigned int KCUInt; 14 | typedef long KCInt32; 15 | typedef unsigned long KCUInt32; 16 | typedef unsigned long KCDWORD; 17 | typedef int KCBool; 18 | 19 | #define FALSE 0 20 | #define TRUE 1 21 | 22 | #define MAX_PATH_LEN 256 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /kerkee/jni/util/FileSys.c: -------------------------------------------------------------------------------- 1 | #include "FileSys.h" 2 | 3 | static FILEOPENED fileopened[MAXOPENFILES] = { 0 }; 4 | static KCInt g_nOpenFiles = 0; 5 | 6 | KCInt FileOpen(const char *pFileName, KCUInt openMode) 7 | { 8 | char flag[5] = { 0 }; 9 | FILE *fp = NULL; 10 | int i = 0; 11 | 12 | if (g_nOpenFiles >= MAXOPENFILES) 13 | { 14 | return ERR_FILEOPEN_MUCH; 15 | } 16 | 17 | memset(flag, 0, 5); 18 | 19 | switch (openMode & FILEMODE_MASK) 20 | { 21 | case FILEMODE_READONLY: 22 | strcpy(flag, "rb"); 23 | break; 24 | case FILEMODE_WRITE: 25 | strcpy(flag, "wb"); 26 | break; 27 | case FILEMODE_READWRITE: 28 | strcpy(flag, "r+b"); 29 | break; 30 | case FILEMODE_CREATEWRITE: 31 | strcpy(flag, "w+b"); 32 | break; 33 | case FILEMODE_APPEND: 34 | strcpy(flag, "ab"); 35 | break; 36 | case FILEMODE_NOSHAREWRITE: 37 | strcpy(flag, "rb"); 38 | break; 39 | default: 40 | return -1; 41 | } 42 | 43 | fp = fopen(pFileName, flag); 44 | 45 | if (fp == NULL) 46 | { 47 | return ERR_FILEOPEN_FAIL; 48 | } 49 | else 50 | { 51 | for (i = 0; i < MAXOPENFILES; i++) 52 | { 53 | if ( NULL == fileopened[i].fp) 54 | { 55 | break; 56 | } 57 | } 58 | 59 | fileopened[i].fp = fp; 60 | strcpy(fileopened[i].filename, pFileName); 61 | g_nOpenFiles++; 62 | 63 | return (KCInt) fp; 64 | } 65 | } 66 | 67 | KCUInt FileLength(KCInt fd) 68 | { 69 | long p = 0; 70 | long temp = 0; 71 | 72 | temp = ftell((FILE*) fd); 73 | 74 | fseek((FILE*) fd, 0, SEEK_END); 75 | p = ftell((FILE*) fd); 76 | 77 | fseek((FILE*) fd, temp, SEEK_SET); 78 | 79 | return p; 80 | } 81 | 82 | KCInt FileSeek(KCInt fd, int offset, int origin) 83 | { 84 | fseek((FILE*) fd, offset, origin); 85 | 86 | return ftell((FILE*) fd); 87 | } 88 | 89 | KCInt32 FileRead(KCInt fd, KCUInt8 *buf, KCInt32 count) 90 | { 91 | return fread(buf, 1, count, (FILE*) fd); 92 | } 93 | 94 | KCInt32 FileWrite(KCInt fd, KCUInt8 *buf, KCInt32 count) 95 | { 96 | return fwrite(buf, 1, count, (FILE*) fd); 97 | } 98 | 99 | KCInt FileClose(KCInt fd) 100 | { 101 | int i = 0; 102 | long ns = 0; 103 | 104 | ns = fd; 105 | 106 | if (fd != 0) 107 | { 108 | if (fclose((FILE*) fd) == 0) 109 | { 110 | for (i = 0; i < 20; i++) 111 | { 112 | if (fileopened[i].fp == (FILE *) ns) 113 | { 114 | break; 115 | } 116 | } 117 | memset(&fileopened[i], 0, sizeof(FILEOPENED)); 118 | g_nOpenFiles--; 119 | return FILE_SUCCESS; 120 | } 121 | else 122 | { 123 | return ERR_FILECLOSE_FAIL; 124 | } 125 | } 126 | else 127 | { 128 | return FILE_FAIL; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /kerkee/jni/util/FileSys.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILESYS_H 2 | #define _FILESYS_H 3 | 4 | #include "Common.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | //file mode 11 | #define FILEMODE_MASK 0x07 12 | #define FILEMODE_READONLY 0x00 /*read only*/ 13 | #define FILEMODE_WRITE 0x01 /*write*/ 14 | #define FILEMODE_READWRITE 0x02 /*read,write*/ 15 | #define FILEMODE_APPEND 0x03 /*append*/ 16 | #define FILEMODE_CREATEWRITE 0x04 /*if file not exit,creat it first, then open with read and write mode*/ 17 | #define FILEMODE_NOSHAREWRITE 0x05 /*not shared for other user to write*/ 18 | 19 | #define FILESEEK_BEGIN 0 20 | #define FILESEEK_CURRENT 0 21 | #define FILESEEK_END 0 22 | 23 | 24 | #define MAXOPENFILES 20 25 | 26 | #define FILE_SUCCESS 0x0F000000 27 | #define FILE_FAIL 0x0F000001 28 | #define ERR_FILEOPEN_MUCH 0x0F000002 29 | #define ERR_FILEOPEN_FAIL 0x0F000003 30 | #define ERR_FILECLOSE_FAIL 0x0F000004 31 | 32 | typedef struct 33 | { 34 | FILE *fp; 35 | KCInt8 filename[256]; 36 | } FILEOPENED; 37 | 38 | KCInt FileOpen(const char *pFileName, KCUInt openMode); 39 | KCUInt FileLength(KCInt fd); 40 | KCInt FileSeek(KCInt fd, int offset, int origin); 41 | KCInt32 FileRead(KCInt fd, KCUInt8 *buf, KCInt32 count); 42 | KCInt32 FileWrite(KCInt fd, KCUInt8 *buf, KCInt32 count); 43 | KCInt FileClose(KCInt fd); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /kerkee/jni/util/NativeUtil.c: -------------------------------------------------------------------------------- 1 | #include "NativeUtil.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "md5.h" 10 | #ifndef ANDROID 11 | #include 12 | #else 13 | #include 14 | #define statvfs statfs 15 | #define fstatvfs fstatfs 16 | #endif 17 | 18 | int file_exists(const char *path) 19 | { 20 | // struct stat buffer; 21 | // return (stat(path, &buffer) == 0); 22 | if (access(path, F_OK) != -1) 23 | return 1; 24 | return 0; 25 | } 26 | 27 | // in bytes 28 | long free_disk_space(const char *path) 29 | { 30 | struct statvfs st; 31 | if (statvfs(path, &st) == 0) 32 | { 33 | return st.f_bsize * st.f_bavail; 34 | } 35 | return 0; 36 | } 37 | 38 | long last_access_time(const char *path) 39 | { 40 | struct stat st; 41 | if (stat(path, &st) == 0) 42 | { 43 | return st.st_atime; 44 | } 45 | return 0; 46 | } 47 | 48 | void last_access_time_batch(const char *path[], long buf[], int count) 49 | { 50 | memset(buf, 0, count * (sizeof *buf)); 51 | 52 | struct stat st; 53 | int i; 54 | 55 | for (i = 0; i < count; ++i) 56 | { 57 | if (stat(path[i], &st) == 0) 58 | { 59 | buf[i] = st.st_atime; 60 | } 61 | } 62 | } 63 | 64 | int copy_file(const char *src, const char *dest) 65 | { 66 | if(!file_exists(src)) 67 | return -1; 68 | FILE *fpSrc = fopen(src, "rb"); 69 | FILE *fpDest = fopen(dest, "wb"); 70 | if (NULL == fpSrc || NULL == fpDest) 71 | { 72 | fclose(fpSrc); 73 | fclose(fpDest); 74 | return -1; 75 | } 76 | 77 | long nBufSize = 256*1024; 78 | unsigned char buffer[nBufSize]; 79 | memset(buffer, 0, nBufSize); 80 | int lenR = 0; 81 | int lenW = 0; 82 | unsigned long long bytesCount = 0; 83 | while ((lenR = fread(buffer, sizeof(char), nBufSize, fpSrc)) > 0) 84 | { 85 | if ((lenW = fwrite(buffer, sizeof(char), lenR, fpDest)) != lenR) 86 | { 87 | fclose(fpSrc); 88 | fclose(fpDest); 89 | return -1; 90 | } 91 | 92 | bytesCount += lenR * sizeof(char); 93 | memset(buffer, 0, nBufSize); 94 | } 95 | 96 | // //use fputc to cpy file 97 | // int c = EOF; 98 | // while ((c = fgetc(fpSrc)) != EOF) 99 | // { 100 | // fputc(c, fpDest); 101 | // } 102 | 103 | fclose(fpSrc); 104 | fclose(fpDest); 105 | return bytesCount; 106 | } 107 | 108 | 109 | int rename_ex(const char *oldpath, const char *newpath) 110 | { 111 | return (rename(oldpath, newpath) == -1 ? 0 : 1); 112 | // __android_log_print(ANDROID_LOG_INFO, "DEBUG", ">>> rename: %s, %s", oldpath, newpath); 113 | // if (rename(oldpath, newpath) == -1) { 114 | // cannot use copy_file(), sometimes it crashes 115 | // __android_log_print(ANDROID_LOG_INFO, "DEBUG", ">>> copy file: %s, %s", oldpath, newpath); 116 | // copy_file(oldpath, newpath); 117 | // remove(oldpath); 118 | // } 119 | } 120 | 121 | int create_sparse_file(const char *path, long size) 122 | { 123 | int fd = open(path, O_WRONLY | O_CREAT); 124 | if (fd) 125 | { 126 | // __android_log_print(ANDROID_LOG_INFO, "DEBUG", ">>> creating sparse file: %s, %ld", path, size); 127 | return ftruncate(fd, size) == 0 ? 1 : 0; 128 | } 129 | return 0; 130 | } 131 | 132 | void md5(char *str, unsigned char *digest) 133 | { 134 | MD5_CTX md5; 135 | MD5_Init(&md5); 136 | MD5_Update(&md5, str, strlen(str)); 137 | MD5_Final(digest, &md5); 138 | } 139 | 140 | /** 141 | * get chars from string of mid 142 | * 143 | */ 144 | char * mid(char *aDes, char *aSrc, int aLen, int aIndex) 145 | { 146 | char *p = aSrc; 147 | char *q = aDes; 148 | int len = strlen(aSrc); 149 | if (aLen > len) 150 | aLen = len - aIndex; 151 | if (aIndex < 0) 152 | aIndex = 0; 153 | if (aIndex > len) 154 | return NULL ; 155 | p += aIndex; 156 | while (aLen--) 157 | *(q++) = *(p++); 158 | *(q++) = '\0'; 159 | return aDes; 160 | } 161 | 162 | -------------------------------------------------------------------------------- /kerkee/jni/util/NativeUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef NATIVEUTIL_H_ 2 | #define NATIVEUTIL_H_ 3 | 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | int file_exists (const char *path); 10 | long free_disk_space (const char *path); 11 | long last_access_time (const char *path); 12 | void last_access_time_batch (const char *path[], long buf[], int count); 13 | int copy_file (const char *src, const char *dest); 14 | int rename_ex (const char *oldpath, const char *newpath); 15 | int create_sparse_file(const char *path, long size); 16 | void md5(char *str, unsigned char *digest); 17 | char* mid(char *dst,char *src, int n,int m); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /kerkee/jni/util/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 3 | * MD5 Message-Digest Algorithm (RFC 1321). 4 | * 5 | * Homepage: 6 | * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 7 | * 8 | * Author: 9 | * Alexander Peslyak, better known as Solar Designer 10 | * 11 | * This software was written by Alexander Peslyak in 2001. No copyright is 12 | * claimed, and the software is hereby placed in the public domain. 13 | * In case this attempt to disclaim copyright and place the software in the 14 | * public domain is deemed null and void, then the software is 15 | * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 16 | * general public under the following terms: 17 | * 18 | * Redistribution and use in source and binary forms, with or without 19 | * modification, are permitted. 20 | * 21 | * There's ABSOLUTELY NO WARRANTY, express or implied. 22 | * 23 | * See md5.c for more information. 24 | */ 25 | 26 | #ifdef HAVE_OPENSSL 27 | #include 28 | #elif !defined(_MD5_H) 29 | #define _MD5_H 30 | 31 | /* Any 32-bit or wider unsigned integer data type will do */ 32 | typedef unsigned int MD5_u32plus; 33 | 34 | typedef struct { 35 | MD5_u32plus lo, hi; 36 | MD5_u32plus a, b, c, d; 37 | unsigned char buffer[64]; 38 | MD5_u32plus block[16]; 39 | } MD5_CTX; 40 | 41 | extern void MD5_Init(MD5_CTX *ctx); 42 | extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); 43 | extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /kerkee/jni/util/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * util.h 3 | * 4 | * Created on: 2014年6月25日 5 | * Author: zihong 6 | */ 7 | 8 | #ifndef UTIL_H_ 9 | #define UTIL_H_ 10 | 11 | 12 | 13 | 14 | 15 | #endif /* UTIL_H_ */ 16 | -------------------------------------------------------------------------------- /kerkee/libs/arm64-v8a/libiniparser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/arm64-v8a/libiniparser.so -------------------------------------------------------------------------------- /kerkee/libs/arm64-v8a/libkerkee_util.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/arm64-v8a/libkerkee_util.so -------------------------------------------------------------------------------- /kerkee/libs/armeabi-v7a/libiniparser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/armeabi-v7a/libiniparser.so -------------------------------------------------------------------------------- /kerkee/libs/armeabi-v7a/libkerkee_util.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/armeabi-v7a/libkerkee_util.so -------------------------------------------------------------------------------- /kerkee/libs/x86/libiniparser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/x86/libiniparser.so -------------------------------------------------------------------------------- /kerkee/libs/x86/libkerkee_util.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/x86/libkerkee_util.so -------------------------------------------------------------------------------- /kerkee/libs/x86_64/libiniparser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/x86_64/libiniparser.so -------------------------------------------------------------------------------- /kerkee/libs/x86_64/libkerkee_util.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee/libs/x86_64/libkerkee_util.so -------------------------------------------------------------------------------- /kerkee/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /kerkee/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # This is a configuration file for ProGuard. 2 | # http://proguard.sourceforge.net/index.html#manual/usage.html 3 | 4 | -dontusemixedcaseclassnames 5 | -dontskipnonpubliclibraryclasses 6 | -verbose 7 | 8 | # Optimization is turned off by default. Dex does not like code run 9 | # through the ProGuard optimize and preverify steps (and performs some 10 | # of these optimizations on its own). 11 | -dontoptimize 12 | -dontpreverify 13 | # Note that if you want to enable optimization, you cannot just 14 | # include optimization flags in your own project configuration file; 15 | # instead you will need to point to the 16 | # "proguard-android-optimize.txt" file instead of this one from your 17 | # project.properties file. 18 | 19 | -keepattributes *Annotation* 20 | -keep public class com.google.vending.licensing.ILicensingService 21 | -keep public class com.android.vending.licensing.ILicensingService 22 | 23 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 24 | -keepclasseswithmembernames class * { 25 | native ; 26 | } 27 | 28 | # keep setters in Views so that animations can still work. 29 | # see http://proguard.sourceforge.net/manual/examples.html#beans 30 | -keepclassmembers public class * extends android.view.View { 31 | void set*(***); 32 | *** get*(); 33 | } 34 | 35 | # We want to keep methods in Activity that could be used in the XML attribute onClick 36 | -keepclassmembers class * extends android.app.Activity { 37 | public void *(android.view.View); 38 | } 39 | 40 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 41 | -keepclassmembers enum * { 42 | public static **[] values(); 43 | public static ** valueOf(java.lang.String); 44 | } 45 | 46 | -keep class * implements android.os.Parcelable { 47 | public static final android.os.Parcelable$Creator *; 48 | } 49 | 50 | 51 | -keepclassmembers class **.R$* { 52 | public static ; 53 | } 54 | 55 | 56 | # The support library contains references to newer platform versions. 57 | # Don't warn about those in case this app is linking against an older 58 | # platform version. We know about them, and they are safe. 59 | -dontwarn android.support.** 60 | 61 | 62 | -keep public class com.kercer.**{ 63 | *; 64 | } 65 | 66 | -ignorewarnings 67 | -------------------------------------------------------------------------------- /kerkee/release.gradle: -------------------------------------------------------------------------------- 1 | //apply plugin: 'maven' 2 | //apply plugin: 'signing' 3 | 4 | apply plugin: 'com.github.dcendents.android-maven' 5 | apply plugin: 'com.jfrog.bintray' 6 | 7 | version = android.defaultConfig.versionName // #CONFIG# // project version 8 | 9 | def siteUrl = 'https://github.com/kercer/kerkee_android' // #CONFIG# // project homepage 10 | def gitUrl = 'https://github.com/kercer/kerkee_android.git' // #CONFIG# // project git 11 | group = "com.kercer" // #CONFIG# // Maven Group ID for the artifact (pageckage name is ok) 12 | 13 | install { 14 | repositories.mavenInstaller { 15 | // This generates POM.xml with proper parameters 16 | pom { 17 | project { 18 | packaging 'aar' 19 | name 'kerkee for android' // #CONFIG# // project title 20 | description 'kerkee is a hybrid app framework,This repository is kerkee for android' 21 | url siteUrl 22 | // Set your license 23 | licenses { 24 | license { 25 | name 'GNU GENERAL PUBLIC LICENSE, Version 3' 26 | url 'http://www.gnu.org/licenses/' 27 | } 28 | } 29 | developers { 30 | developer { 31 | id 'zihong' // #CONFIG# // your user id (you can write your nickname) 32 | name 'zihong' // #CONFIG# // your user name 33 | email 'zihong87@gmail.com' // #CONFIG# // your email 34 | } 35 | } 36 | scm { 37 | connection gitUrl 38 | developerConnection gitUrl 39 | url siteUrl 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | 47 | 48 | task javadoc(type: Javadoc) { 49 | source = android.sourceSets.main.java.srcDirs 50 | classpath += files(android.bootClasspath) 51 | classpath += files(project.getConfigurations().getByName('compile').asList()) 52 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 53 | // include '**/*.java' 54 | // exclude '**/BuildConfig.java' 55 | 56 | } 57 | 58 | task javadocJar(type: Jar, dependsOn: javadoc) { 59 | classifier = 'javadoc' 60 | from javadoc.destinationDir 61 | } 62 | 63 | task sourcesJar(type: Jar) { 64 | classifier = 'sources' 65 | from android.sourceSets.main.java.srcDirs 66 | // include '**/*.java' 67 | 68 | } 69 | 70 | android.libraryVariants.all { variant -> 71 | def name = variant.name.capitalize() 72 | task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) { 73 | from variant.javaCompile.destinationDir 74 | } 75 | } 76 | 77 | artifacts { 78 | archives javadocJar 79 | archives sourcesJar 80 | } 81 | 82 | Properties properties = new Properties() 83 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 84 | bintray { 85 | user = properties.getProperty("bintray.user") 86 | key = properties.getProperty("bintray.apikey") 87 | configurations = ['archives'] 88 | pkg { 89 | repo = "maven" 90 | name = "kerkee" // #CONFIG# project name in jcenter 91 | websiteUrl = siteUrl 92 | vcsUrl = gitUrl 93 | licenses = ["GPL-3.0"] 94 | publish = true 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /kerkee/release_maven.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | 4 | def repoUrl = 'http://scm.linzihong.com/nexus/content/repositories/releases/' 5 | def siteUrl = 'https://www.kerkee.com' // #CONFIG# // project homepage 6 | def gitUrl = 'https://github.com/kercer/kerkee_android.git' // #CONFIG# // project git 7 | def libName = 'kerkee' 8 | 9 | group = "com.kercer" 10 | //version = "1.3.0" //set in pom.project 11 | 12 | signing { 13 | required { /*has("release") &&*/ gradle.taskGraph.hasTask("uploadArchives") } 14 | sign configurations.archives 15 | } 16 | 17 | Properties properties = new Properties() 18 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 19 | 20 | uploadArchives { 21 | configuration = configurations.archives 22 | repositories.mavenDeployer { 23 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 24 | repository(url: repoUrl) { 25 | def user = properties.getProperty("maven.user") 26 | def pw = properties.getProperty("maven.password") 27 | authentication(userName: user, 28 | password: pw) 29 | } 30 | 31 | pom.project { 32 | name libName 33 | packaging 'aar' 34 | description libName 35 | url repoUrl 36 | // groupId 'com.kercer' 37 | artifactId libName //LibA 38 | version android.defaultConfig.versionName 39 | 40 | // Set your license 41 | licenses { 42 | license { 43 | name 'GNU GENERAL PUBLIC LICENSE, Version 3' 44 | url 'http://www.gnu.org/licenses/' 45 | } 46 | } 47 | 48 | developers { 49 | developer { 50 | id 'zihong' // #CONFIG# // your user id (you can write your nickname) 51 | name 'zihong' // #CONFIG# // your user name 52 | email 'zihong87@gmail.com' // #CONFIG# // your email 53 | } 54 | } 55 | 56 | scm { 57 | connection gitUrl 58 | developerConnection gitUrl 59 | url siteUrl 60 | } 61 | 62 | } 63 | } 64 | } 65 | 66 | 67 | task androidJavadocs(type: Javadoc) { 68 | options { 69 | linksOffline "http://d.android.com/reference", "${android.sdkDirectory}/docs/reference" 70 | 71 | } 72 | failOnError false 73 | source = source = android.sourceSets.main.java.srcDirs 74 | classpath += project.files(project.android.getBootClasspath().join(File.pathSeparator)) 75 | classpath += files(project.getConfigurations().getByName('compile').asList()) 76 | // include '**/*.java' 77 | // exclude '**/BuildConfig.java' 78 | } 79 | 80 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { 81 | classifier = 'javadoc' 82 | from androidJavadocs.destinationDir 83 | } 84 | 85 | task androidSourcesJar(type: Jar) { 86 | classifier = 'sources' 87 | from android.sourceSets.main.java.srcDirs 88 | // include '**/*.java' 89 | } 90 | 91 | android.libraryVariants.all { variant -> 92 | def name = variant.name.capitalize() 93 | task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) { 94 | from variant.javaCompile.destinationDir 95 | } 96 | } 97 | 98 | artifacts { 99 | archives androidSourcesJar 100 | archives androidJavadocsJar 101 | } 102 | 103 | //def isSnapshotBuild() { 104 | // return version.contains("SNAPSHOT") 105 | //} 106 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCApiBridgeManager.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.kercer.kercore.debug.KCLog; 6 | import com.kercer.kerkee.webview.KCWebView; 7 | 8 | import org.json.JSONObject; 9 | 10 | /** 11 | * 12 | * @author zihong 13 | * 14 | */ 15 | public class KCApiBridgeManager 16 | { 17 | 18 | public static void testJSBrige(final KCWebView aWebView, JSONObject jsonObject) 19 | { 20 | if (KCLog.DEBUG) 21 | KCLog.d(">>>>>> testJSBrige called: " + jsonObject.toString()); 22 | 23 | Toast.makeText(aWebView.getContext(), jsonObject.toString(), 24 | Toast.LENGTH_SHORT).show(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCArg.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public class KCArg 9 | { 10 | private String mName; 11 | private Object mObject; 12 | private Class mType; 13 | 14 | public KCArg(String aName, Object aValue, Class aType) 15 | { 16 | mName = aName; 17 | mObject = aValue; 18 | mType = aType; 19 | } 20 | 21 | public KCArg(String aName, Object aValue) 22 | { 23 | this(aName, aValue, aValue.getClass()); 24 | } 25 | 26 | public String getArgName() 27 | { 28 | return mName; 29 | } 30 | 31 | public Object getValue() 32 | { 33 | return mObject; 34 | } 35 | 36 | public Class getType() 37 | { 38 | return mType; 39 | } 40 | 41 | @Override 42 | public String toString() 43 | { 44 | return mName + ":" + mObject.toString(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCArgList.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import com.kercer.kerkee.bridge.type.KCJSCallback; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * 10 | * @author zihong 11 | * 12 | */ 13 | public class KCArgList 14 | { 15 | private List mArgs = new ArrayList(2); 16 | 17 | public int size() 18 | { 19 | return mArgs.size(); 20 | } 21 | 22 | public boolean addArg(KCArg aArg) 23 | { 24 | if (aArg == null) return false; 25 | mArgs.add(aArg); 26 | return true; 27 | } 28 | 29 | public boolean has(String aKey) 30 | { 31 | return getObject(aKey) != null ? true : false; 32 | } 33 | 34 | public KCArg get(int aIndex) 35 | { 36 | return mArgs.get(aIndex); 37 | } 38 | 39 | public Object getObject(String aKey) 40 | { 41 | Object obj = null; 42 | if (aKey != null) 43 | { 44 | int count = mArgs.size(); 45 | for (int i = 0; i < count; ++i) 46 | { 47 | KCArg arg = mArgs.get(i); 48 | if (arg != null && arg.getArgName().equals(aKey)) 49 | { 50 | obj = arg.getValue(); 51 | break; 52 | } 53 | } 54 | } 55 | 56 | return obj; 57 | } 58 | 59 | public Object getObject(int aIndex) 60 | { 61 | KCArg arg = get(aIndex); 62 | return arg != null ? arg.getValue() : null; 63 | } 64 | 65 | public String getString(String aKey) 66 | { 67 | Object value = getObject(aKey); 68 | return value == null ? null : value.toString(); 69 | } 70 | 71 | public String getString(int aIndex) 72 | { 73 | Object value = getObject(aIndex); 74 | return value == null ? null : value.toString(); 75 | } 76 | 77 | public KCJSCallback getCallback() 78 | { 79 | KCJSCallback callback = (KCJSCallback)getObject(KCJSDefine.kJS_callbackId); 80 | return callback; 81 | } 82 | 83 | // boolean isNull(int index) 84 | // { 85 | // 86 | // } 87 | 88 | public boolean getBoolean(int aIndex) 89 | { 90 | String obj = getString(aIndex); 91 | return Boolean.parseBoolean(obj); 92 | } 93 | public boolean getBoolean(String aKey) 94 | { 95 | String obj = getString(aKey); 96 | return Boolean.parseBoolean(obj); 97 | } 98 | 99 | double getDouble(int aIndex) 100 | { 101 | String obj = getString(aIndex); 102 | return Double.parseDouble(obj); 103 | } 104 | 105 | public int getInt(int aIndex) 106 | { 107 | String obj = getString(aIndex); 108 | return Integer.parseInt(obj); 109 | } 110 | public int getInt(String aKey) 111 | { 112 | String obj = getString(aKey); 113 | return Integer.parseInt(obj); 114 | } 115 | 116 | 117 | // Array getArray(int index); 118 | // Map getMap(int index); 119 | // KCType getType(int index); 120 | 121 | Class getType(int aIndex) 122 | { 123 | KCArg arg = get(aIndex); 124 | if (arg != null) 125 | return arg.getType(); 126 | return null; 127 | } 128 | 129 | Class[] getTypes() 130 | { 131 | int lengh = size(); 132 | Class[] types = new Class[lengh]; 133 | 134 | for (int i = 0; i < lengh; ++i) 135 | { 136 | KCArg arg = get(i); 137 | if (arg != null) 138 | types[i] = arg.getType(); 139 | } 140 | return types; 141 | } 142 | 143 | @Override 144 | public String toString() 145 | { 146 | return mArgs.toString(); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCClass.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | 8 | /** 9 | * 10 | * @author zihong 11 | * 12 | */ 13 | public class KCClass 14 | { 15 | private String mJSClzName; 16 | private Class mClz; 17 | //the key is method name 18 | private HashMap> mMethods = new HashMap>(); 19 | 20 | 21 | public KCClass(String aJSClzName, Class aClass) 22 | { 23 | mJSClzName = aJSClzName; 24 | mClz = aClass; 25 | } 26 | 27 | public static KCClass newClass(String aJSClzName, Class aClass) 28 | { 29 | return new KCClass(aJSClzName, aClass); 30 | } 31 | 32 | public Class getNavClass() 33 | { 34 | return mClz; 35 | } 36 | 37 | public String getJSClz() 38 | { 39 | return mJSClzName; 40 | } 41 | 42 | public void addJSMethod(String aMethodName, KCArgList aArgList) 43 | { 44 | // seachMethod(aMethodName, aArgList); 45 | } 46 | 47 | 48 | public List getMethods(String aName) 49 | { 50 | return mMethods.get(aName); 51 | } 52 | 53 | protected List getNativeMethods(String aName) 54 | { 55 | List list = new ArrayList(); 56 | Method[] nativeMethods = mClz.getMethods(); 57 | for(int i = 0; i < nativeMethods.length; ++i) 58 | { 59 | Method method = nativeMethods[i]; 60 | if (aName.equals(method.getName())) 61 | { 62 | list.add(method); 63 | } 64 | } 65 | 66 | return list; 67 | } 68 | 69 | protected Method seachMethod(String aMethodName, KCArgList aArgList) 70 | { 71 | Method method = null; 72 | List nativeMethodsList = getNativeMethods(aMethodName); 73 | int count = nativeMethodsList.size(); 74 | for(int i = 0; i < count; ++i) 75 | { 76 | Method nativeMethod = nativeMethodsList.get(i); 77 | Class[] parameterTypes = nativeMethod.getParameterTypes(); 78 | 79 | //TODO 80 | } 81 | 82 | return method; 83 | } 84 | 85 | protected void loadMethods() 86 | { 87 | Method[] targetMethods = mClz.getDeclaredMethods(); 88 | for (int i = 0; i < targetMethods.length; i++) 89 | { 90 | Method targetMethod = targetMethods[i]; 91 | if (targetMethod.getAnnotation(KerkeeMethod.class) != null) 92 | { 93 | loadMethod(targetMethod); 94 | } 95 | } 96 | } 97 | 98 | protected KCMethod loadMethod(Method aMethod) 99 | { 100 | String methodName = aMethod.getName(); 101 | List listMethods = getMethods(methodName); 102 | if (listMethods == null) 103 | { 104 | listMethods = new ArrayList(); 105 | } 106 | 107 | KCMethod jsMethod = null; 108 | for(int i = 0; i < listMethods.size(); ++i) 109 | { 110 | KCMethod tmpMethod = listMethods.get(i); 111 | if (tmpMethod == null) continue; 112 | if (tmpMethod.isSameMethod(aMethod)) 113 | { 114 | jsMethod = tmpMethod; 115 | } 116 | } 117 | 118 | if (jsMethod == null) 119 | { 120 | jsMethod = new KCMethod(this, aMethod); 121 | listMethods.add(jsMethod); 122 | mMethods.put(methodName, listMethods); 123 | } 124 | return jsMethod; 125 | } 126 | 127 | protected KCMethod loadMethod(String aMethodName, Class... aParameterTypes) throws NoSuchMethodException 128 | { 129 | List listMethods = getMethods(aMethodName); 130 | if (listMethods == null) 131 | { 132 | listMethods = new ArrayList(); 133 | } 134 | 135 | KCMethod jsMethod = null; 136 | for(int i = 0; i < listMethods.size(); ++i) 137 | { 138 | KCMethod tmpMethod = listMethods.get(i); 139 | if (tmpMethod == null) continue; 140 | if (tmpMethod.isSameArgList(aParameterTypes)) 141 | { 142 | jsMethod = tmpMethod; 143 | } 144 | } 145 | 146 | if (jsMethod == null) 147 | { 148 | Method tmp = mClz.getMethod(aMethodName, aParameterTypes); 149 | jsMethod = new KCMethod(this, tmp); 150 | listMethods.add(jsMethod); 151 | mMethods.put(aMethodName, listMethods); 152 | } 153 | return jsMethod; 154 | } 155 | 156 | public KCMethod getMethod(String aMethodName, Class... aParameterTypes) throws NoSuchMethodException 157 | { 158 | return loadMethod(aMethodName, aParameterTypes); 159 | } 160 | 161 | public KCMethod getMethod(String aMethodName, KCArgList aArgList) throws NoSuchMethodException 162 | { 163 | if (aArgList == null || aMethodName == null) return null; 164 | Class[] argListTypes = aArgList.getTypes(); 165 | KCMethod jsMethod = getMethod(aMethodName, argListTypes); 166 | return jsMethod; 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCClassParser.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import com.kercer.kercore.debug.KCLog; 4 | import com.kercer.kerkee.bridge.type.KCJSCallback; 5 | import com.kercer.kerkee.bridge.type.KCJSNull; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | import java.util.Iterator; 11 | 12 | /** 13 | * 14 | * @author zihong 15 | * 16 | */ 17 | public class KCClassParser 18 | { 19 | public final static String CLZ = "clz"; 20 | public final static String ARGS = "args"; 21 | public final static String METHOD = "method"; 22 | 23 | private JSONObject mArgsJSON; 24 | 25 | private String mJSClzName; 26 | private String mJSMethodName; 27 | private KCArgList mArgList = new KCArgList(); 28 | 29 | public String getJSClzName() 30 | { 31 | return mJSClzName; 32 | } 33 | 34 | public String getJSMethodName() 35 | { 36 | return mJSMethodName; 37 | } 38 | 39 | public KCArgList getArgList() 40 | { 41 | return mArgList; 42 | } 43 | 44 | public JSONObject getArgsJSON() 45 | { 46 | return mArgsJSON; 47 | } 48 | 49 | protected boolean isNull(Object aObj) 50 | { 51 | return aObj == null || aObj == JSONObject.NULL; 52 | } 53 | 54 | @SuppressWarnings("rawtypes") 55 | public KCClassParser(String jsonStr) 56 | { 57 | try 58 | { 59 | JSONObject json = new JSONObject(jsonStr); 60 | mJSClzName = json.get(CLZ).toString(); 61 | mJSMethodName = json.get(METHOD).toString(); 62 | if (json.has(ARGS)) 63 | { 64 | mArgsJSON = json.getJSONObject(ARGS); 65 | Iterator it = mArgsJSON.keys(); 66 | while (it.hasNext()) 67 | { 68 | String key = (String) it.next(); 69 | if (key != null) 70 | { 71 | Object value = mArgsJSON.get(key); 72 | if(KCJSNull.isNull(value)) 73 | value = new KCJSNull(); 74 | KCArg arg = null; 75 | 76 | if(key.equals(KCJSDefine.kJS_callbackId)) 77 | { 78 | arg = new KCArg(key, new KCJSCallback(value.toString()), KCJSCallback.class); 79 | } 80 | else 81 | { 82 | arg = new KCArg(key, value); 83 | } 84 | mArgList.addArg(arg); 85 | } 86 | } 87 | } 88 | } 89 | catch (JSONException e) 90 | { 91 | KCLog.e(e); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCJSCompileExecutor.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import android.annotation.SuppressLint; 4 | 5 | import com.kercer.kercore.debug.KCLog; 6 | import com.kercer.kerkee.bridge.type.KCCallback; 7 | import com.kercer.kerkee.webview.KCWebView; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | /** 13 | * 14 | * @author zihong 15 | * 16 | */ 17 | 18 | @SuppressLint("UseSparseArrays") 19 | public class KCJSCompileExecutor 20 | { 21 | private static HashMap mCallBackMap = new HashMap(); 22 | private static Integer mIdentity = 0; 23 | 24 | @Deprecated 25 | public static void compileJS(final KCWebView aWebview, String aJS, KCCallback aReturnCallback) 26 | { 27 | compileJS(aWebview, aReturnCallback, aJS); 28 | } 29 | 30 | public static void compileJS(final KCWebView aWebview, KCCallback aReturnCallback, String aJS) 31 | { 32 | mIdentity ++; 33 | mCallBackMap.put(mIdentity, aReturnCallback); 34 | aWebview.addJSCompileIdentity(mIdentity); 35 | 36 | String escapedJavascript = aJS.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\"", "\\\\\""); 37 | String finalCode = 38 | "ApiBridge.compile(" + mIdentity + 39 | ", \"" + escapedJavascript + "\");"; 40 | KCLog.v(finalCode); 41 | 42 | KCJSExecutor.callJSOnMainThread(aWebview, finalCode); 43 | } 44 | 45 | public static void compileFunction(final KCWebView aWebview, KCCallback aReturnCallback, String aJSFunctionName, Object... aJSArgs) 46 | { 47 | compileJS(aWebview, aReturnCallback, KCMethod.toJS(aJSFunctionName, aJSArgs)); 48 | } 49 | 50 | public static void release(List aIdentities) 51 | { 52 | if (aIdentities == null) return; 53 | for (Integer identity: aIdentities) 54 | { 55 | if (identity != null) 56 | mCallBackMap.remove(identity); 57 | } 58 | } 59 | 60 | protected static void didCompile(KCWebView aWebView, Integer aIdentity, Object aReturnValue, String aError) 61 | { 62 | aWebView.removeJSCompileIdentity(aIdentity); 63 | KCCallback callback = mCallBackMap.remove(aIdentity); 64 | if (callback != null) 65 | { 66 | callback.callback(aReturnValue, new KCJSError(aError)); 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCJSDefine.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public class KCJSDefine 9 | { 10 | //class key 11 | public final static String kJS_ApiBridge = "ApiBridge"; 12 | public final static String kJS_jsBridgeClient = "jsBridgeClient"; 13 | public final static String kJS_XMLHttpRequest = "XMLHttpRequest"; 14 | public final static String kJS_event = "event"; 15 | 16 | //arg key 17 | public final static String kJS_callbackId = "callbackId"; 18 | public final static String kJS_returnValue = "returnValue"; 19 | public final static String kJS_identity = "identity"; 20 | public final static String kJS_error = "error"; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCJSError.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | /** 4 | * Created by zihong on 15/10/19. 5 | */ 6 | public class KCJSError 7 | { 8 | protected String mName; 9 | protected String mMessage; 10 | protected int mErrorCode; 11 | 12 | public KCJSError(final String aMessage) 13 | { 14 | this(null, 0, aMessage); 15 | } 16 | public KCJSError(final String aName, final int aErrorCode, final String aMessage) 17 | { 18 | mName = aName; 19 | mMessage = aMessage; 20 | mErrorCode = aErrorCode; 21 | } 22 | 23 | public String toString() 24 | { 25 | return mMessage == null ? "" : mMessage; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCJSExecutor.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import android.os.Build; 4 | 5 | import com.kercer.kercore.task.KCTaskExecutor; 6 | import com.kercer.kercore.util.KCUtilText; 7 | import com.kercer.kerkee.util.KCUtil; 8 | import com.kercer.kerkee.webview.KCWebView; 9 | 10 | /** 11 | * Note:This problem has solved 12 | * Prior to Android 4.4, loadUrl with "javascript:" URLs basically sent everything after javascript: 13 | * directly to the JavaScript execution without re-coding anything. 14 | * In Android 4.4 with the new WebView, loadUrl with "javascript:" URLs will URL-decode the string before execution. 15 | * Where previously %-escapes where sent unchanged to the JavaScript, they will now be decoded first, 16 | * which can result in an accidental re-encoding of e.g. ISO-8859-1-based %-escapes into Unicode characters. 17 | * That means, if e.g. a pre-encoded URL containg encoded binary data or ISO-8859-1 is sent as argument to a JavaScript, 18 | * this might then be sent re-encoded as UTF-8 to the server, breaking things. 19 | * The work-around is to use the new evaluateJavascript method of Android 4.4 20 | * Nevertheless, this is an incompatible, and so it seems, undocumented change of a public API which 21 | * can introduce subtle bugs into existing applications. The change should be properly documented 22 | * in the JavaDoc of the method. 23 | * see:https://code.google.com/p/android/issues/detail?id=69969 24 | */ 25 | 26 | public class KCJSExecutor 27 | { 28 | 29 | public static void callJS(final KCWebView aWebView, final String aJS) 30 | { 31 | if (aWebView == null) return; 32 | 33 | /* 34 | Use webview to load a webpage which includes a JS function urlAdded(url); 35 | 36 | Call webview.loadUrl("javascript:urlAdded(\"http://redir.xxxxx.com/click.php?id=12345&originalUrlhttp%3A%2F%2Fm.ctrip.com%2Fhtml5%2F%3Fallianceid%3D1000%26sid%3D454555%26sourceid%3D1111\""); 37 | 38 | On android 4.4 device: 39 | urlAdded(url) got a parameter 40 | http://redir.xxxxx.com/click.php?id=12345&originalUrl=http://m.ctrip.com/html5/?allianceid=1000&sid=454555&sourceid=1111 41 | 42 | originalUrl is miss unescaped. 43 | 44 | pre-4.4 device: expected 45 | urlAdded(url) got a parameter 46 | http://redir.xxxxx.com/click.php?id=12345&originalUrlhttp%3A%2F%2Fm.ctrip.com%2Fhtml5%2F%3Fallianceid%3D1000%26sid%3D454555%26sourceid%3D1111 47 | */ 48 | 49 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 50 | { 51 | try 52 | { 53 | aWebView.evaluateJavascript(aJS, null); 54 | } 55 | catch (Exception e) 56 | { 57 | aWebView.loadUrlExt("javascript:" + aJS); 58 | } 59 | } 60 | else 61 | { 62 | aWebView.loadUrlExt("javascript:" + aJS); 63 | } 64 | } 65 | 66 | public static void callJSOnMainThread(final KCWebView aWebView, final String aJS) 67 | { 68 | if (aWebView == null || KCUtilText.isEmpty(aJS)) return; 69 | KCTaskExecutor.runTaskOnUiThread(new Runnable() 70 | { 71 | @Override 72 | public void run() 73 | { 74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 75 | { 76 | aWebView.evaluateJavascript(aJS, null); 77 | } 78 | else 79 | { 80 | aWebView.loadUrlExt("javascript:" + aJS); 81 | } 82 | } 83 | }); 84 | } 85 | 86 | 87 | public static void callJSFunction(final KCWebView aWebView, String aJSFunctionName, Object... aArgs) 88 | { 89 | callJS(aWebView, KCMethod.toJS(aJSFunctionName, aArgs)); 90 | } 91 | 92 | public static void callJSFunctionOnMainThread(final KCWebView aWebView, String aJSFunctionName, Object... aArgs) 93 | { 94 | callJSOnMainThread(aWebView, KCMethod.toJS(aJSFunctionName, aArgs)); 95 | } 96 | 97 | 98 | public static void callbackJS(final KCWebView aWebView, String aCallbackId, Object... aArgs) 99 | { 100 | String argsString = KCMethod.toJsArgsList(aArgs); 101 | StringBuilder sb = KCUtil.getThreadSafeStringBuilder().append("ApiBridge.onCallback("); 102 | sb.append(aCallbackId); 103 | if (argsString.length() > 0) 104 | { 105 | sb.append(","); 106 | sb.append(argsString); 107 | } 108 | sb.append(')'); 109 | 110 | callJSOnMainThread(aWebView, sb.toString()); 111 | } 112 | 113 | public static void callbackJS(KCWebView aWebview, String aCallbackId) 114 | { 115 | StringBuilder sb = KCUtil.getThreadSafeStringBuilder().append("ApiBridge.onCallback(").append(aCallbackId).append(')'); 116 | callJSOnMainThread(aWebview, sb.toString()); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCJSObject.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by zihong on 15/10/23. 9 | */ 10 | public abstract class KCJSObject 11 | { 12 | abstract public String getJSObjectName(); 13 | 14 | public final Map getMethods() 15 | { 16 | Map methods = new HashMap(); 17 | Method[] targetMethods = getClass().getDeclaredMethods(); 18 | for (int i = 0; i < targetMethods.length; i++) 19 | { 20 | Method targetMethod = targetMethods[i]; 21 | if (targetMethod.getAnnotation(KerkeeMethod.class) != null) 22 | { 23 | String methodName = targetMethod.getName(); 24 | if (methods.containsKey(methodName)) 25 | { 26 | // We do not support method overloading since js sees a function as an object regardless 27 | // of number of params. 28 | throw new IllegalArgumentException("Java Class " + getJSObjectName() + " method name already registered: " + methodName); 29 | } 30 | methods.put(methodName, new KCMethod(targetMethod)); 31 | } 32 | } 33 | return methods; 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KCRegister.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import com.kercer.kercore.task.KCTaskExecutor; 4 | import com.kercer.kerkee.bridge.event.KCEvent; 5 | import com.kercer.kerkee.bridge.xhr.KCXMLHttpRequestManager; 6 | 7 | import java.util.HashMap; 8 | 9 | /** 10 | * 11 | * @author zihong 12 | * 13 | */ 14 | public class KCRegister 15 | { 16 | private final static HashMap mClassMap = new HashMap(); 17 | // private final static HashMap mMethodCache = new HashMap(); //key is identity for KCMethod 18 | private final static HashMap mJSObjectMap = new HashMap(); 19 | 20 | static 21 | { 22 | mClassMap.put(KCJSDefine.kJS_ApiBridge, KCClass.newClass(KCJSDefine.kJS_ApiBridge, KCApiBridge.class)); 23 | mClassMap.put(KCJSDefine.kJS_jsBridgeClient, KCClass.newClass(KCJSDefine.kJS_jsBridgeClient, KCApiBridgeManager.class)); 24 | mClassMap.put(KCJSDefine.kJS_XMLHttpRequest, KCClass.newClass(KCJSDefine.kJS_XMLHttpRequest, KCXMLHttpRequestManager.class)); 25 | mClassMap.put(KCJSDefine.kJS_event, KCClass.newClass(KCJSDefine.kJS_event, KCEvent.class)); 26 | 27 | } 28 | 29 | public KCClass registObject(final KCJSObject aObject) 30 | { 31 | if (aObject == null) return null; 32 | String jsObjectName = aObject.getJSObjectName(); 33 | KCClass clz = null; 34 | if (jsObjectName != null) 35 | { 36 | mJSObjectMap.put(jsObjectName, aObject); 37 | clz = registClass(jsObjectName, aObject.getClass()); 38 | } 39 | 40 | return clz; 41 | } 42 | public KCClass removeObject(KCJSObject aObject) 43 | { 44 | if (aObject == null) return null; 45 | String jsObjectName = aObject.getJSObjectName(); 46 | KCClass clz = null; 47 | if(jsObjectName != null) 48 | { 49 | mJSObjectMap.remove(jsObjectName); 50 | clz = removeClass(jsObjectName); 51 | } 52 | return clz; 53 | } 54 | 55 | 56 | public KCClass registClass(KCClass aClass) 57 | { 58 | return registClass(aClass.getJSClz(), aClass.getNavClass()) ; 59 | } 60 | 61 | public KCClass registClass(String aJSObjectName, Class aClass) 62 | { 63 | if (aJSObjectName == null || aClass == null) return null; 64 | KCClass clz = KCClass.newClass(aJSObjectName, aClass); 65 | mClassMap.put(aJSObjectName, clz); 66 | // String js = String.format("if(%s && global.%s) global.%s=%s", aJSObjectName, aJSObjectName, aJSObjectName, aJSObjectName); 67 | // callJS(aWebView, js, true); 68 | 69 | loadMethodsAsyn(clz); 70 | 71 | return clz; 72 | } 73 | 74 | private void loadMethodsAsyn(final KCClass aClass) 75 | { 76 | KCTaskExecutor.executeTask(new Runnable() { 77 | @Override 78 | public void run() { 79 | aClass.loadMethods(); 80 | } 81 | }); 82 | } 83 | 84 | public KCClass removeClass(String aJSObjectName) 85 | { 86 | if (aJSObjectName == null) return null; 87 | return mClassMap.remove(aJSObjectName); 88 | } 89 | 90 | public KCClass getClass(String aClassName) 91 | { 92 | return mClassMap.get(aClassName); 93 | } 94 | 95 | public KCJSObject getJSObject(String aJSObjectName) 96 | { 97 | return mJSObjectMap.get(aJSObjectName); 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/KerkeeMethod.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge; 2 | 3 | import java.lang.annotation.Retention; 4 | 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | /** 8 | * Created by zihong on 15/10/23. 9 | * 10 | * Annotation which is used to mark methods 11 | */ 12 | 13 | @Retention(RUNTIME) 14 | public @interface KerkeeMethod { 15 | } 16 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/event/KCEvent.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.event; 2 | 3 | import com.kercer.kercore.util.KCUtilText; 4 | import com.kercer.kerkee.bridge.KCArgList; 5 | import com.kercer.kerkee.bridge.KCJSDefine; 6 | import com.kercer.kerkee.bridge.type.KCJSCallback; 7 | import com.kercer.kerkee.webview.KCWebView; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | public class KCEvent 13 | { 14 | private final static Map mEvents = new HashMap(); 15 | 16 | 17 | /***************************************************** 18 | * Native API,called by Native 19 | * 20 | ******************************************************/ 21 | 22 | public static Map events() 23 | { 24 | return mEvents; 25 | } 26 | 27 | public static KCJSCallback getCallback(String aEvent) 28 | { 29 | KCJSCallback callback = null; 30 | if (!KCUtilText.isEmpty(aEvent)) 31 | { 32 | Integer callbackID = mEvents.get(aEvent); 33 | callback = new KCJSCallback(callbackID.toString()); 34 | } 35 | return callback; 36 | } 37 | 38 | public static boolean hasEvent(String aEvent) 39 | { 40 | return mEvents.containsKey(aEvent); 41 | } 42 | 43 | public static boolean callEvent(KCWebView aWebView, String aEvent, Object... aArgs) 44 | { 45 | boolean isOk = false; 46 | KCJSCallback callback = getCallback(aEvent); 47 | if (callback != null) 48 | { 49 | callback.callbackToJS(aWebView, aArgs); 50 | isOk = true; 51 | } 52 | return isOk; 53 | } 54 | 55 | public static boolean callEvent(KCWebView aWebView, String aEvent) 56 | { 57 | boolean isOk = false; 58 | KCJSCallback callback = getCallback(aEvent); 59 | if (callback != null) 60 | { 61 | callback.callbackToJS(aWebView); 62 | isOk = true; 63 | } 64 | return isOk; 65 | } 66 | 67 | 68 | /***************************************************** 69 | * JS API,called by JS 70 | * 71 | ******************************************************/ 72 | 73 | 74 | /** 75 | * addEventListener called by js 76 | * @param aWebView 77 | * @param aArgList 78 | */ 79 | public static void addEventListener(final KCWebView aWebView, KCArgList aArgList) 80 | { 81 | String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 82 | Integer nCallbackId = Integer.valueOf(callbackId); 83 | String eventName = aArgList.getString(KCJSDefine.kJS_event); 84 | 85 | synchronized (mEvents) 86 | { 87 | mEvents.put(eventName, nCallbackId); 88 | } 89 | 90 | } 91 | 92 | 93 | } 94 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCCallback.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public interface KCCallback 9 | { 10 | public void callback(Object... args); 11 | } 12 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSCallback.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | import com.kercer.kerkee.bridge.KCJSExecutor; 4 | import com.kercer.kerkee.webview.KCWebView; 5 | 6 | public class KCJSCallback implements KCJSType 7 | { 8 | private String mCallbackId; 9 | 10 | public KCJSCallback(String aCallbackId) 11 | { 12 | mCallbackId = aCallbackId; 13 | } 14 | 15 | public String getCallbackId() 16 | { 17 | return mCallbackId; 18 | } 19 | 20 | 21 | public void callbackToJS(final KCWebView aWebView) 22 | { 23 | KCJSExecutor.callbackJS(aWebView, mCallbackId); 24 | } 25 | 26 | public void callbackToJS(final KCWebView aWebView, Object... aArgs) 27 | { 28 | KCJSExecutor.callbackJS(aWebView, mCallbackId, aArgs); 29 | } 30 | 31 | // public void callbackToJS(KCWebView aWebView, String aStr) 32 | // { 33 | // KCJSExecutor.callbackJS(aWebView, mCallbackId, aStr); 34 | // } 35 | // 36 | // public void callbackToJS(KCWebView aWebView, JSONObject aJSONObject) 37 | // { 38 | // KCJSExecutor.callbackJS(aWebView, mCallbackId, aJSONObject); 39 | // } 40 | // 41 | // public void callbackToJS(KCWebView aWebView, JSONArray aJSONArray) 42 | // { 43 | // KCJSExecutor.callbackJS(aWebView, mCallbackId, aJSONArray); 44 | // } 45 | 46 | public String toString() 47 | { 48 | return mCallbackId; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSJsonArray.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | import org.json.JSONArray; 4 | 5 | /** 6 | * Created by zihong on 15/12/3. 7 | */ 8 | public class KCJSJsonArray implements KCJSType 9 | { 10 | JSONArray mJsonArray; 11 | 12 | public KCJSJsonArray(JSONArray aJsonArray) 13 | { 14 | mJsonArray = aJsonArray; 15 | } 16 | 17 | public String toString() 18 | { 19 | return mJsonArray != null ? mJsonArray.toString() : null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSJsonObject.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by zihong on 15/12/3. 9 | */ 10 | public class KCJSJsonObject implements KCJSType 11 | { 12 | JSONObject mJsonObject; 13 | 14 | public KCJSJsonObject() 15 | { 16 | mJsonObject = new JSONObject(); 17 | } 18 | public KCJSJsonObject(JSONObject aJsonObject) 19 | { 20 | mJsonObject = aJsonObject; 21 | } 22 | 23 | public KCJSJsonObject(Map aCopyFrom) 24 | { 25 | mJsonObject = new JSONObject(aCopyFrom); 26 | } 27 | 28 | public String toString() 29 | { 30 | return mJsonObject != null ? mJsonObject.toString() : null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSNull.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | import org.json.JSONObject; 4 | 5 | /** 6 | * Created by zihong on 15/10/28. 7 | */ 8 | public class KCJSNull implements KCJSType 9 | { 10 | public static final KCJSNull NULL = new KCJSNull(); 11 | 12 | public static boolean isNull(Object value) 13 | { 14 | return value == null || value == NULL || value == JSONObject.NULL; 15 | } 16 | 17 | @Override public boolean equals(Object o) 18 | { 19 | return o == this || o == null; // API specifies this broken equals implementation 20 | } 21 | @Override public String toString() 22 | { 23 | return null; 24 | } 25 | 26 | @Override 27 | public int hashCode() 28 | { 29 | return super.hashCode(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSNumber.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | /** 4 | * Created by zihong on 15/12/3. 5 | */ 6 | public class KCJSNumber implements KCJSType 7 | { 8 | private Number mNumber; 9 | 10 | public KCJSNumber(int aValue) 11 | { 12 | mNumber = new Integer(aValue); 13 | } 14 | 15 | public KCJSNumber(double aValue) 16 | { 17 | mNumber = new Double(aValue); 18 | } 19 | 20 | public KCJSNumber(float aValue) 21 | { 22 | mNumber = new Float(aValue); 23 | } 24 | 25 | public String toString() 26 | { 27 | return mNumber.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSString.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | /** 4 | * Created by zihong on 15/12/3. 5 | */ 6 | public class KCJSString implements KCJSType 7 | { 8 | private String mString = ""; 9 | public KCJSString(String aString) 10 | { 11 | if(aString != null) 12 | mString = aString; 13 | } 14 | 15 | public static KCJSString string(final String aString) 16 | { 17 | return new KCJSString(aString); 18 | } 19 | 20 | public String toString() 21 | { 22 | return mString; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCJSType.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | /** 4 | * Created by zihong on 15/10/23. 5 | */ 6 | public interface KCJSType 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/bridge/type/KCReturnCallback.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.bridge.type; 2 | 3 | import com.kercer.kerkee.bridge.KCJSError; 4 | 5 | public abstract class KCReturnCallback implements KCCallback 6 | { 7 | @Override 8 | public void callback(Object... args) 9 | { 10 | Object object = null; 11 | KCJSError error = null; 12 | if (args.length > 0) 13 | { 14 | object = args[0]; 15 | } 16 | 17 | if (args.length > 1) 18 | { 19 | error = (KCJSError) args[1]; 20 | } 21 | 22 | returnCallback(object, error); 23 | } 24 | 25 | abstract public void returnCallback(Object aObject, KCJSError aError); 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/browser/KCJSBridge.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.browser; 2 | 3 | import android.view.ViewGroup; 4 | 5 | import com.kercer.kerkee.bridge.KCApiBridge; 6 | import com.kercer.kerkee.bridge.KCClass; 7 | import com.kercer.kerkee.bridge.KCJSDefine; 8 | import com.kercer.kerkee.bridge.KCJSExecutor; 9 | import com.kercer.kerkee.bridge.KCJSObject; 10 | import com.kercer.kerkee.webview.KCWebView; 11 | 12 | import org.json.JSONArray; 13 | import org.json.JSONObject; 14 | 15 | /** 16 | * 17 | * @author zihong 18 | * 19 | */ 20 | public class KCJSBridge 21 | { 22 | 23 | public KCJSBridge() 24 | { 25 | // File wwwRoot = new File(getResRootPath() + "/"); 26 | // if(!KCHttpServer.isRunning()) 27 | // KCHttpServer.startServer(KCHttpServer.getPort(), wwwRoot); 28 | } 29 | 30 | 31 | 32 | /********************************************************/ 33 | /* 34 | * js opt 35 | */ 36 | /********************************************************/ 37 | 38 | public static KCClass registJSBridgeClient(Class aClass) 39 | { 40 | return registClass(KCJSDefine.kJS_jsBridgeClient, aClass); 41 | } 42 | 43 | public static KCClass registClass(KCClass aClass) 44 | { 45 | return KCApiBridge.getRegister().registClass(aClass); 46 | } 47 | 48 | public static KCClass registClass(String aJSObjectName, Class aClass) 49 | { 50 | return KCApiBridge.getRegister().registClass(aJSObjectName, aClass); 51 | } 52 | 53 | public static KCClass registObject(final KCJSObject aObject) 54 | { 55 | return KCApiBridge.getRegister().registObject(aObject); 56 | } 57 | public KCClass removeObject(KCJSObject aObject) 58 | { 59 | return KCApiBridge.getRegister().removeObject(aObject); 60 | } 61 | 62 | 63 | public static void removeClass(String aJSObjectName) 64 | { 65 | KCApiBridge.getRegister().removeClass(aJSObjectName); 66 | } 67 | 68 | 69 | /********************************************************/ 70 | /* 71 | * js call, you call us KCJSExecutor 72 | */ 73 | /********************************************************/ 74 | public static void callJSOnMainThread(final KCWebView aWebview, final String aJS) 75 | { 76 | KCJSExecutor.callJSOnMainThread(aWebview, aJS); 77 | } 78 | 79 | public static void callJS(final KCWebView aWebview, final String aJS) 80 | { 81 | KCJSExecutor.callJS(aWebview, aJS); 82 | } 83 | 84 | public static void callJSFunctionOnMainThread(final KCWebView aWebview, String aFunName, String aArgs) 85 | { 86 | KCJSExecutor.callJSFunctionOnMainThread(aWebview, aFunName, aArgs); 87 | } 88 | 89 | public static void callbackJS(KCWebView aWebview, String aCallbackId) 90 | { 91 | KCJSExecutor.callbackJS(aWebview, aCallbackId); 92 | } 93 | 94 | public static void callbackJS(KCWebView aWebview, String aCallbackId, String aStr) 95 | { 96 | KCJSExecutor.callbackJS(aWebview, aCallbackId, aStr); 97 | } 98 | 99 | public static void callbackJS(KCWebView aWebview, String aCallbackId, JSONObject aJSONObject) 100 | { 101 | KCJSExecutor.callbackJS(aWebview, aCallbackId, aJSONObject); 102 | } 103 | 104 | public static void callbackJS(KCWebView aWebview, String aCallbackId, JSONArray aJSONArray) 105 | { 106 | KCJSExecutor.callbackJS(aWebview, aCallbackId, aJSONArray); 107 | } 108 | 109 | 110 | /********************************************************/ 111 | /* 112 | * config 113 | */ 114 | /********************************************************/ 115 | public static void openGlobalJSLog(boolean aIsOpenJSLog) 116 | { 117 | KCApiBridge.openGlobalJSLog(aIsOpenJSLog); 118 | } 119 | 120 | public static void setIsOpenJSLog(KCWebView aWebview, boolean aIsOpenJSLog) 121 | { 122 | KCApiBridge.setIsOpenJSLog(aWebview, aIsOpenJSLog); 123 | } 124 | 125 | 126 | public static void destroyWebview(KCWebView aWebview) 127 | { 128 | if(aWebview != null) 129 | { 130 | aWebview.loadUrl("about:blank"); 131 | 132 | ViewGroup vg = (ViewGroup) aWebview.getParent(); 133 | if (vg != null) 134 | vg.removeView(aWebview); 135 | aWebview.clearCache(true); 136 | aWebview.destroy(); 137 | aWebview = null; 138 | } 139 | 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/downloader/KCContentLengthInputStream.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.downloader; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * Decorator for {@link java.io.InputStream InputStream}. Provides possibility to return defined stream length by 8 | * {@link #available()} method. 9 | * 10 | * @author zihong 11 | */ 12 | public class KCContentLengthInputStream extends InputStream 13 | { 14 | private final InputStream stream; 15 | private final int length; 16 | 17 | public KCContentLengthInputStream(InputStream stream, int length) 18 | { 19 | this.stream = stream; 20 | this.length = length; 21 | } 22 | 23 | @Override 24 | public int available() 25 | { 26 | return length; 27 | } 28 | 29 | @Override 30 | public void close() throws IOException 31 | { 32 | stream.close(); 33 | } 34 | 35 | @Override 36 | public void mark(int readLimit) 37 | { 38 | stream.mark(readLimit); 39 | } 40 | 41 | @Override 42 | public int read() throws IOException 43 | { 44 | return stream.read(); 45 | } 46 | 47 | @Override 48 | public int read(byte[] buffer) throws IOException 49 | { 50 | return stream.read(buffer); 51 | } 52 | 53 | @Override 54 | public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException 55 | { 56 | return stream.read(buffer, byteOffset, byteCount); 57 | } 58 | 59 | @Override 60 | public void reset() throws IOException 61 | { 62 | stream.reset(); 63 | } 64 | 65 | @Override 66 | public long skip(long byteCount) throws IOException 67 | { 68 | return stream.skip(byteCount); 69 | } 70 | 71 | @Override 72 | public boolean markSupported() 73 | { 74 | return stream.markSupported(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/downloader/KCDownloader.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.downloader; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.Locale; 6 | 7 | /** 8 | * Provides retrieving of {@link InputStream} of image by URI. 9 | * Implementations have to be thread-safe. 10 | * 11 | * @author zihong 12 | */ 13 | public interface KCDownloader 14 | { 15 | 16 | /** 17 | * Retrieves {@link InputStream} of image by URI. 18 | * 19 | * @param imageUri Image URI 20 | * @param extra Auxiliary object 21 | * DisplayImageOptions.extraForDownloader(Object)}; can be null 22 | * @return {@link InputStream} of image 23 | * @throws IOException if some I/O error occurs during getting image stream 24 | * @throws UnsupportedOperationException if image URI has unsupported scheme(protocol) 25 | */ 26 | InputStream getStream(String imageUri, Object extra) throws IOException; 27 | 28 | /** Represents supported schemes(protocols) of URI. Provides convenient methods for work with schemes and URIs. */ 29 | public enum KCScheme 30 | { 31 | HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"), ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN(""); 32 | 33 | private String scheme; 34 | private String uriPrefix; 35 | 36 | KCScheme(String scheme) 37 | { 38 | this.scheme = scheme; 39 | uriPrefix = scheme + "://"; 40 | } 41 | 42 | /** 43 | * Defines scheme of incoming URI 44 | * 45 | * @param uri URI for scheme detection 46 | * @return Scheme of incoming URI 47 | */ 48 | public static KCScheme ofUri(String uri) 49 | { 50 | if (uri != null) 51 | { 52 | for (KCScheme s : values()) 53 | { 54 | if (s.belongsTo(uri)) 55 | { 56 | return s; 57 | } 58 | } 59 | } 60 | return UNKNOWN; 61 | } 62 | 63 | private boolean belongsTo(String uri) 64 | { 65 | return uri.toLowerCase(Locale.US).startsWith(uriPrefix); 66 | } 67 | 68 | /** Appends scheme to incoming path */ 69 | public String wrap(String path) 70 | { 71 | return uriPrefix + path; 72 | } 73 | 74 | /** Removed scheme part ("scheme://") from incoming URI */ 75 | public String crop(String uri) 76 | { 77 | if (!belongsTo(uri)) 78 | { 79 | throw new IllegalArgumentException(String.format("URI [%1$s] doesn't have expected scheme [%2$s]", uri, scheme)); 80 | } 81 | return uri.substring(uriPrefix.length()); 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/frame/iniparser/KCIniparser.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.frame.iniparser; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public class KCIniparser 9 | { 10 | static 11 | { 12 | System.loadLibrary("iniparser"); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCDefaultImageStream.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.InputStream; 5 | 6 | import android.content.Context; 7 | import android.util.Base64; 8 | 9 | public class KCDefaultImageStream 10 | { 11 | 12 | //data:image/png;base64, 13 | //Transparent image 14 | private final static String mDefaultImageBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAaSURBVHjaYvz//z8DMYCJgUgwqpA6CgECDADVEgMRar6RXAAAAABJRU5ErkJggg=="; 15 | private byte[] data = new byte[0]; 16 | 17 | public KCDefaultImageStream(Context aContext) 18 | { 19 | data = Base64.decode(mDefaultImageBase64, Base64.DEFAULT); 20 | } 21 | 22 | public InputStream getInputStream() 23 | { 24 | return new ByteArrayInputStream(data); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImage.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import java.io.InputStream; 4 | 5 | public class KCWebImage 6 | { 7 | private InputStream mInputStream; 8 | 9 | public void setInputStream(final InputStream aInputStream) 10 | { 11 | mInputStream = aInputStream; 12 | } 13 | 14 | public InputStream getInputStream() 15 | { 16 | return mInputStream; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImageCache.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import android.content.Context; 4 | import android.os.FileObserver; 5 | 6 | import com.kercer.kercore.debug.KCLog; 7 | import com.kercer.kercore.io.KCUtilFile; 8 | import com.kercer.kernet.uri.KCURI; 9 | 10 | import java.io.File; 11 | import java.io.FilenameFilter; 12 | import java.io.IOException; 13 | import java.util.List; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | 16 | /** 17 | * 18 | * @author zihong 19 | * 20 | */ 21 | public class KCWebImageCache 22 | { 23 | Context mContext; 24 | 25 | private final ConcurrentHashMap mImageFileMap = new ConcurrentHashMap(); 26 | private final static String DUMMY_STRING = ""; 27 | // A reference to the DirWatcher MUST be kept so it will receive events. 28 | // see: http://stackoverflow.com/a/13521540/668963 29 | private KCDirWatcher mDirWatcher; 30 | 31 | File mWebImageDir; 32 | 33 | public KCWebImageCache(Context aContext) 34 | { 35 | super(); 36 | mContext = aContext; 37 | } 38 | 39 | public void loadCache(FilenameFilter aFilenameFilter) 40 | { 41 | 42 | File webImageDir = null; 43 | try 44 | { 45 | webImageDir = getCacheDir(); 46 | List fileList = KCUtilFile.getFiles(webImageDir.getAbsolutePath(), true, true, aFilenameFilter); 47 | for (int i = 0; i < fileList.size(); ++i) 48 | { 49 | mImageFileMap.put(fileList.get(i), DUMMY_STRING); 50 | } 51 | } 52 | catch (Exception e) 53 | { 54 | KCLog.e(e); 55 | } 56 | 57 | if (webImageDir != null) 58 | { 59 | try 60 | { 61 | mDirWatcher = new KCDirWatcher(webImageDir.getAbsolutePath(), FileObserver.DELETE | FileObserver.DELETE_SELF); 62 | mDirWatcher.startWatching(); 63 | } 64 | catch (Exception e) 65 | { 66 | KCLog.e(e); 67 | } 68 | } 69 | } 70 | 71 | 72 | class KCDirWatcher extends FileObserver 73 | { 74 | public KCDirWatcher(String dir, int mask) throws IOException 75 | { 76 | super(dir, mask); 77 | } 78 | 79 | @Override 80 | public void onEvent(int event, String path) 81 | { 82 | if (event == DELETE) 83 | { 84 | // mImageFileMap.remove(mParentDir + "/" + path); 85 | mImageFileMap.remove("/" + path); 86 | } 87 | else if (event == DELETE_SELF) 88 | { 89 | mImageFileMap.clear(); 90 | stopWatching(); 91 | getCacheDir(); //check dir 92 | startWatching(); 93 | } 94 | } 95 | } 96 | 97 | private void checkTerminalPath(final File aPath) 98 | { 99 | aPath.mkdirs(); //If the terminal directory already exists, answer false 100 | } 101 | 102 | public File getCacheDir() 103 | { 104 | if (mWebImageDir == null) 105 | { 106 | File baseDir = mContext.getExternalCacheDir(); 107 | if (baseDir == null) 108 | { 109 | baseDir = new File(mContext.getFilesDir(), "cache"); 110 | } 111 | baseDir.mkdirs(); 112 | mWebImageDir = new File(baseDir, "webimages"); 113 | } 114 | checkTerminalPath(mWebImageDir); 115 | return mWebImageDir; 116 | } 117 | 118 | public void setCacheDir(File aDir) 119 | { 120 | if (aDir != null) 121 | { 122 | mWebImageDir = aDir; 123 | checkTerminalPath(aDir); 124 | } 125 | } 126 | 127 | public static File getInternalCacheDirectory(Context context) 128 | { 129 | File internalCacheDirectory = new File(context.getCacheDir(), "temp-images"); 130 | if (!internalCacheDirectory.exists()) 131 | { 132 | if (!internalCacheDirectory.mkdir()) 133 | { 134 | KCLog.i("Failed creating temporary storage directory, this is probably not good"); 135 | } 136 | } 137 | return internalCacheDirectory; 138 | } 139 | 140 | 141 | public void add(KCURI aUri) 142 | { 143 | mImageFileMap.put(aUri.getPath(), DUMMY_STRING); 144 | } 145 | 146 | public void remove(KCURI aUri) 147 | { 148 | mImageFileMap.remove(aUri.getPath()); 149 | } 150 | 151 | public boolean containsCache(KCURI aUri) 152 | { 153 | return mImageFileMap.containsKey(aUri.getPath()); 154 | } 155 | 156 | 157 | } 158 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImageHandler.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Created by liwei on 16/8/11. 7 | */ 8 | public class KCWebImageHandler implements KCWebImageListener { 9 | private HashMap urls = new HashMap<>(); 10 | private KCWebImageListener mWebImageListener; 11 | 12 | public KCWebImageHandler(KCWebImageListener mWebImageListener) { 13 | this.mWebImageListener = mWebImageListener; 14 | } 15 | 16 | public KCWebImageHandler add(String url){ 17 | if (!urls.containsKey(url)) 18 | urls.put(url,url); 19 | return this; 20 | } 21 | 22 | @Override 23 | public void onAllImageFinish(){ 24 | if (mWebImageListener!=null) 25 | mWebImageListener.onAllImageFinish(); 26 | } 27 | 28 | @Override 29 | public void onImageFinish(String url) 30 | { 31 | if (urls.containsKey(url)) 32 | urls.remove(url); 33 | if (mWebImageListener!=null) 34 | mWebImageListener.onImageFinish(url); 35 | if (urls.size()<=0) 36 | onAllImageFinish(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImageListener.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | /** 4 | * 当前webview 加载图片完成回调接口 5 | * 内部使用 6 | * Created by liwei on 16/8/11. 7 | */ 8 | public interface KCWebImageListener { 9 | void onImageFinish(String url); 10 | void onAllImageFinish(); 11 | } 12 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImageSetter.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import com.kercer.kercore.debug.KCLog; 4 | 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | 8 | /** 9 | * 10 | * @author zihong 11 | * 12 | */ 13 | public class KCWebImageSetter extends Thread 14 | { 15 | private static final long SHUTDOWN_TIMEOUT_IN_MS = 100; 16 | private final Queue pendingTasks; 17 | private boolean isRunning; 18 | 19 | public KCWebImageSetter() 20 | { 21 | super("KCWebImageLoader"); 22 | pendingTasks = new LinkedList(); 23 | } 24 | 25 | @Override 26 | public void run() 27 | { 28 | KCLog.i("Starting up task " + getName()); 29 | KCWebImageSetterTask task; 30 | isRunning = true; 31 | while (isRunning) 32 | { 33 | synchronized (pendingTasks) 34 | { 35 | while (pendingTasks.isEmpty() && isRunning) 36 | { 37 | try 38 | { 39 | pendingTasks.wait(); 40 | } 41 | catch (InterruptedException e) 42 | { 43 | isRunning = false; 44 | break; 45 | } 46 | } 47 | 48 | try 49 | { 50 | if (!canExecute(pendingTasks)) 51 | continue; 52 | task = getNextTask(pendingTasks); 53 | } 54 | catch (Exception e) 55 | { 56 | continue; 57 | } 58 | } 59 | 60 | try 61 | { 62 | if (task != null) 63 | { 64 | task.executeTask(); 65 | } 66 | } 67 | catch (Exception e) 68 | { 69 | } 70 | } 71 | 72 | KCLog.i("Shutting down task " + getName()); 73 | } 74 | 75 | @Override 76 | public void interrupt() 77 | { 78 | super.interrupt(); 79 | isRunning = false; 80 | } 81 | 82 | public void addTask(KCWebImageSetterTask aTask) 83 | { 84 | synchronized (pendingTasks) 85 | { 86 | pendingTasks.add(aTask); 87 | pendingTasks.notifyAll(); 88 | // KCLog.i("addTask succeeded:" + aTask.mUrl); 89 | } 90 | } 91 | 92 | private boolean canExecute(Queue aTaskQueue) 93 | { 94 | KCWebImageSetterTask task = aTaskQueue.peek(); 95 | return (task == null) ? false : task.canExecute(); 96 | } 97 | 98 | private KCWebImageSetterTask getNextTask(Queue aTaskQueue) 99 | { 100 | // Pop the first element from the pending request queue 101 | KCWebImageSetterTask task = aTaskQueue.poll(); 102 | 103 | return task; 104 | } 105 | 106 | public void shutdown() 107 | { 108 | try 109 | { 110 | interrupt(); 111 | join(SHUTDOWN_TIMEOUT_IN_MS); 112 | } 113 | catch (InterruptedException e) 114 | { 115 | } 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/imagesetter/KCWebImageSetterTask.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.imagesetter; 2 | 3 | import com.kercer.kerkee.bridge.KCJSExecutor; 4 | import com.kercer.kerkee.webview.KCWebView; 5 | import com.kercer.kernet.uri.KCURI; 6 | 7 | /** 8 | * 9 | * @author zihong 10 | * 11 | */ 12 | public class KCWebImageSetterTask 13 | { 14 | public KCWebView mWebView; 15 | public KCURI mUri; //[scheme:][//authority][path][?query][#fragment] 16 | public String mUrl; 17 | 18 | public KCWebImageSetterTask(KCWebView aWebView, String aUrl, KCURI aUri) 19 | { 20 | mWebView = aWebView; 21 | mUrl = aUrl; 22 | mUri = aUri; 23 | } 24 | 25 | public static KCWebImageSetterTask create(KCWebView aWebView, String aUrl, KCURI aUri) 26 | { 27 | KCWebImageSetterTask task = new KCWebImageSetterTask(aWebView, aUrl, aUri); 28 | return task; 29 | } 30 | 31 | public boolean canExecute() 32 | { 33 | return mWebView.isDocumentReady(); 34 | } 35 | 36 | public void executeTask() 37 | { 38 | final String srcSuffix = mUrl.substring(mUrl.lastIndexOf('/') + 1); 39 | KCJSExecutor.callJSOnMainThread(mWebView, "jsBridgeClient.onSetImage('" + srcSuffix + "','" + mUri.toString() + "')"); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/manifest/KCManifestObject.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.manifest; 2 | 3 | import com.kercer.kercore.util.KCUtilText; 4 | import com.kercer.kernet.uri.KCURI; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class KCManifestObject 9 | { 10 | 11 | private String mVersion; // version 12 | private String[] mSubManifests; // sub manifests list 13 | private String[] mExtras; //extras files, don't delete files 14 | private ArrayList mCacheList; 15 | private String mDekRelativePath; //dek relative to manifest path, if dek path is url, it's null 16 | private String mRequiredVersion; //required version 17 | private ArrayList mCacheDirs; //cache dirs, contains mCacheList' dir, not contains Extras and suManifests dir 18 | 19 | //if mDekRelativePath's scheme is not null, set it in Parser 20 | //if from server,set it in KCFetchManifest; 21 | //if from local,set it in KCManifestParser 22 | private String mDownloadUrl; 23 | //dek & manifest file Dir, if parser from server, the VAR is null 24 | private String mDestDir; 25 | 26 | public KCURI mBaseUri; //root uri 27 | public String mRelativePath; //relative to base uri 28 | 29 | 30 | public KCManifestObject() 31 | { 32 | mRequiredVersion = KCUtilText.EMPTY_STR; 33 | mVersion = KCUtilText.EMPTY_STR; 34 | mDekRelativePath = KCUtilText.EMPTY_STR; 35 | } 36 | 37 | public String getVersion() 38 | { 39 | return mVersion; 40 | } 41 | 42 | public void setVersion(String aVersion) 43 | { 44 | this.mVersion = aVersion; 45 | } 46 | 47 | public String getRequiredVersion() 48 | { 49 | return mRequiredVersion; 50 | } 51 | 52 | public void setRequiredVersion(String aVersion) 53 | { 54 | this.mRequiredVersion = aVersion; 55 | } 56 | 57 | public void setSubManifests(String[] aSubManifests) 58 | { 59 | this.mSubManifests = aSubManifests; 60 | } 61 | 62 | public String[] getSubManifests() 63 | { 64 | return mSubManifests; 65 | } 66 | 67 | public void setExtras(String[] aExtras) 68 | { 69 | this.mExtras = aExtras; 70 | } 71 | 72 | public String[] getExtras() 73 | { 74 | return mExtras; 75 | } 76 | 77 | public ArrayList getCacheList() 78 | { 79 | return mCacheList; 80 | } 81 | 82 | public void setCacheList(ArrayList aCacheList) 83 | { 84 | this.mCacheList = aCacheList; 85 | } 86 | 87 | public ArrayList getCacheDirs() 88 | { 89 | return mCacheDirs; 90 | } 91 | 92 | public void setCacheDirs(ArrayList aCacheDirs) 93 | { 94 | this.mCacheDirs = aCacheDirs; 95 | } 96 | 97 | public String getDekRelativePath() 98 | { 99 | if (KCUtilText.isStringEmpty(mDekRelativePath)) 100 | mDekRelativePath = "/update_" + this.mVersion + ".dek"; 101 | return mDekRelativePath; 102 | } 103 | 104 | public void setDekRelativePath(String aRelativePath) 105 | { 106 | this.mDekRelativePath = aRelativePath; 107 | } 108 | 109 | public void setDownloadUrl(String aDownloadUrl) 110 | { 111 | this.mDownloadUrl = aDownloadUrl; 112 | } 113 | 114 | public String getDownloadUrl() 115 | { 116 | return mDownloadUrl; 117 | } 118 | 119 | public void setDestDir(String aDestDir) 120 | { 121 | this.mDestDir = aDestDir; 122 | } 123 | 124 | public String getDestDir() 125 | { 126 | return mDestDir; 127 | } 128 | 129 | 130 | 131 | } 132 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/manifest/KCManifestParser.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.manifest; 2 | 3 | import com.kercer.kercore.debug.KCLog; 4 | import com.kercer.kercore.util.KCUtilText; 5 | import com.kercer.kernet.uri.KCURI; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.File; 9 | import java.io.InputStream; 10 | import java.io.InputStreamReader; 11 | import java.util.ArrayList; 12 | 13 | public class KCManifestParser 14 | { 15 | 16 | public final static String VERSION = "Version:"; 17 | public final static String LIST = "List:"; 18 | public final static String REQUIREDVERSION = "RequiredVersion:"; 19 | public final static String DEK = "Dek:"; 20 | public final static String CACHE = "CACHE:"; 21 | public final static String POUND_SIGN = "#"; 22 | public final static String COLON = ":"; 23 | public final static String SPACE = " "; 24 | public final static String COMMA = ","; 25 | public final static String EXTRA = "Extra:"; 26 | 27 | public static KCManifestObject ParserManifest(InputStream aIn) 28 | { 29 | if (aIn != null) 30 | { 31 | try 32 | { 33 | 34 | String line; 35 | String trimline; 36 | String value; 37 | 38 | int cachelineIndex = -1; 39 | int lineIndex = 0; 40 | 41 | BufferedReader reader = new BufferedReader(new InputStreamReader(aIn), 1024); 42 | 43 | KCManifestObject mo = new KCManifestObject(); 44 | ArrayList cacheList = null; 45 | ArrayList cacheDirs = null; 46 | while ((line = reader.readLine()) != null) 47 | { 48 | lineIndex++; 49 | trimline = line.replaceAll(" +", ""); 50 | if (KCUtilText.isStringEmpty(trimline)) 51 | continue; 52 | if (trimline.startsWith(POUND_SIGN)) 53 | { 54 | if (trimline.contains(POUND_SIGN + VERSION)) 55 | { 56 | value = getCommentValue(VERSION, trimline); 57 | mo.setVersion(value); 58 | } 59 | else if (trimline.contains(POUND_SIGN + LIST)) 60 | { 61 | value = getCommentValue(LIST, trimline); 62 | if (!KCUtilText.isStringEmpty(value)) 63 | { 64 | mo.setSubManifests(value.split(COMMA)); 65 | } 66 | } 67 | else if (trimline.contains(POUND_SIGN + EXTRA)) 68 | { 69 | value = getCommentValue(POUND_SIGN + EXTRA, trimline); 70 | if (!KCUtilText.isStringEmpty(value)) 71 | { 72 | mo.setExtras(value.split(COMMA)); 73 | } 74 | } 75 | else if (trimline.contains(POUND_SIGN + REQUIREDVERSION)) 76 | { 77 | value = getCommentValue(REQUIREDVERSION, trimline); 78 | mo.setRequiredVersion(value); 79 | } 80 | else if (trimline.contains(POUND_SIGN + DEK)) 81 | { 82 | value = getCommentValue(DEK, trimline); 83 | KCURI uri = KCURI.parse(value); 84 | if (uri.getScheme() == null) 85 | { 86 | String relativePath = uri.getPath(); 87 | mo.setDekRelativePath(relativePath); 88 | } 89 | else if(uri.getScheme() != null && uri.getHost() != null) 90 | { 91 | mo.setDownloadUrl(uri.toString()); 92 | } 93 | 94 | } 95 | cachelineIndex = -1; 96 | 97 | } 98 | else if (trimline.startsWith(CACHE)) 99 | { 100 | cachelineIndex = lineIndex; 101 | cacheList = new ArrayList(); 102 | cacheDirs = new ArrayList(); 103 | 104 | } 105 | else if (trimline.endsWith(COLON)) 106 | { 107 | cachelineIndex = -1; 108 | } 109 | if (cachelineIndex != -1 && !trimline.equals(CACHE)) 110 | { 111 | if (isInExtra(mo, trimline)) 112 | { 113 | continue; 114 | } 115 | cacheList.add(trimline); 116 | String dir = File.separator; 117 | if (trimline.contains(File.separator)) 118 | { 119 | dir = trimline.substring(0, trimline.lastIndexOf(File.separator) + 1); 120 | } 121 | if (!isInSubManifest(mo, dir) || File.separator.equals(dir)) 122 | { 123 | if (!cacheDirs.contains(dir)) 124 | cacheDirs.add(dir); 125 | 126 | } 127 | } 128 | } 129 | 130 | if (cacheList != null) 131 | { 132 | mo.setCacheList(cacheList); 133 | } 134 | if (cacheDirs != null) 135 | { 136 | mo.setCacheDirs(cacheDirs); 137 | } 138 | reader.close(); 139 | return mo; 140 | } 141 | catch (Exception e) 142 | { 143 | KCLog.e(e); 144 | } 145 | } 146 | return null; 147 | } 148 | 149 | private static boolean isInExtra(KCManifestObject aMO, String aFileName) 150 | { 151 | String[] extras = aMO.getExtras(); 152 | if (extras != null) 153 | { 154 | for (int i = 0; i < extras.length; i++) 155 | { 156 | if (aFileName.contains(extras[i])) 157 | { 158 | return true; 159 | } 160 | } 161 | } 162 | return false; 163 | } 164 | 165 | private static boolean isInSubManifest(KCManifestObject aMO, String aDir) 166 | { 167 | String[] subManifests = aMO.getSubManifests(); 168 | if (subManifests != null) 169 | { 170 | for (int i = 0; i < subManifests.length; i++) 171 | { 172 | if (subManifests[i].contains(aDir)) 173 | { 174 | return true; 175 | } 176 | } 177 | } 178 | return false; 179 | } 180 | 181 | public static String getCommentValue(String aKey, String aLine) 182 | { 183 | int startIndex = aLine.indexOf(aKey) + aKey.length(); 184 | return aLine.substring(startIndex).trim(); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/net/KCHttpServer.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.net; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | /** 7 | * 8 | * @author zihong 9 | * 10 | */ 11 | public class KCHttpServer 12 | { 13 | // server 14 | public static KCHTTPDPooled mHttpServer; 15 | public static int mPort = 0; 16 | public static File mWWWRoot; 17 | public static boolean mIsRunning = false; 18 | 19 | public static void startServer(int aPort, File aWWWRoot) 20 | { 21 | if (aWWWRoot == null) return; 22 | 23 | mPort = aPort; 24 | mWWWRoot = aWWWRoot; 25 | if (mHttpServer == null) 26 | mHttpServer = new KCHTTPDPooled(aWWWRoot); 27 | 28 | boolean startSuccess = mHttpServer.start(mPort); 29 | for (int i = 0; !startSuccess && i < 10; ++i) 30 | { 31 | startSuccess = mHttpServer.start(0); 32 | } 33 | 34 | if (startSuccess) 35 | { 36 | mPort = mHttpServer.getPort(); 37 | mIsRunning = true; 38 | } 39 | 40 | } 41 | 42 | public static void stopServer() 43 | { 44 | if (mHttpServer != null) 45 | mHttpServer.stop(); 46 | } 47 | 48 | public static int getPort() 49 | { 50 | return mPort; 51 | } 52 | 53 | public static String getLocalHostUrl() 54 | { 55 | if (mHttpServer == null) 56 | return null; 57 | return mHttpServer.getServerName(); 58 | } 59 | 60 | public static File getRootDir() 61 | { 62 | return mWWWRoot; 63 | } 64 | 65 | public static boolean isRunning() 66 | { 67 | return mIsRunning; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/util/KCCusBuffer.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.util; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public class KCCusBuffer 9 | { 10 | private byte[] buffer; 11 | private int nBufferLen; 12 | 13 | public KCCusBuffer() 14 | { 15 | } 16 | 17 | public byte[] getBuffer() 18 | { 19 | return buffer; 20 | } 21 | 22 | public void setBuffer(byte[] buffer) 23 | { 24 | this.buffer = buffer; 25 | } 26 | 27 | public int getnBufferLen() 28 | { 29 | return nBufferLen; 30 | } 31 | 32 | public void setnBufferLen(int nBufferLen) 33 | { 34 | this.nBufferLen = nBufferLen; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/util/KCNativeUtil.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.util; 2 | 3 | /** 4 | * 5 | * @author zihong 6 | * 7 | */ 8 | public class KCNativeUtil 9 | { 10 | static 11 | { 12 | System.loadLibrary("kerkee_util"); 13 | } 14 | 15 | // this function is twice as fast as new File().exists() 16 | // public native static boolean fileExists (String path); 17 | public native static boolean fileExists(String path); 18 | 19 | public native static long freeDiskSpace(String path); 20 | 21 | public native static long lastAccessTime(String path); 22 | 23 | // this method sometimes causes JNI crash on "libc#fwrite" 24 | //fixed,but must be a lot of testing 25 | // @Deprecated 26 | public native static boolean copyFile(String srcPath, String destPath); 27 | 28 | // this method causes UnsatisfiedLinkError on some devices. 29 | @Deprecated 30 | public native static boolean renameExt(String oldPath, String newPath); 31 | 32 | public native static boolean createSparseFile(String path, long size); 33 | 34 | public native static void testCrash(); 35 | 36 | public native static String getMd5(String para); 37 | 38 | public native static String getMd5Treated(String para); 39 | 40 | /* 41 | * FileSys 42 | */ 43 | public native static int fileOpen(String pFileName, int openMode); 44 | public native static int fileLength(int fp); 45 | public native static int fileSeek(int fp, int offset, int origin); 46 | public native static KCCusBuffer fileRead(int fp, int nCount); 47 | public native static int fileWrite(int fp, byte[] buf, int nCount); 48 | public native static int fileClose(int fp); 49 | } 50 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/util/KCUtil.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.util; 2 | 3 | import com.kercer.kercore.debug.KCLog; 4 | 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * 9 | * @author zihong 10 | * 11 | */ 12 | public class KCUtil 13 | { 14 | private final static ThreadLocal threadSafeStrBuilder = new ThreadLocal(); 15 | private final static ThreadLocal threadSafeByteBuf = new ThreadLocal(); 16 | 17 | private final static Pattern PATTERN_PLUS = Pattern.compile("\\+"); 18 | 19 | public static StringBuilder getThreadSafeStringBuilder() 20 | { 21 | StringBuilder sb = threadSafeStrBuilder.get(); 22 | if (sb == null) 23 | { 24 | sb = new StringBuilder(); 25 | threadSafeStrBuilder.set(sb); 26 | } 27 | sb.delete(0, sb.length()); 28 | return sb; 29 | } 30 | 31 | public static byte[] getThreadSafeByteBuffer() 32 | { 33 | byte[] buf = threadSafeByteBuf.get(); 34 | if (buf == null) 35 | { 36 | buf = new byte[1024 * 4]; // 4kb 37 | threadSafeByteBuf.set(buf); 38 | } 39 | return buf; 40 | } 41 | 42 | 43 | public static String getMD5String(String str) 44 | { 45 | try 46 | { 47 | return KCNativeUtil.getMd5(str); 48 | } 49 | catch (Exception e) 50 | { 51 | KCLog.e(e); 52 | } 53 | return null; 54 | } 55 | 56 | 57 | public static String replacePlusWithPercent20(String url) 58 | { 59 | if (url.contains("+")) 60 | { 61 | url = PATTERN_PLUS.matcher(url).replaceAll("%20"); 62 | } 63 | return url; 64 | } 65 | 66 | 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/webview/KCWebChromeClient.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.webview; 2 | 3 | import com.kercer.kerkee.bridge.KCApiBridge; 4 | 5 | import android.webkit.ConsoleMessage; 6 | import android.webkit.JsPromptResult; 7 | import android.webkit.WebChromeClient; 8 | import android.webkit.WebView; 9 | 10 | /** 11 | * 12 | * @author zihong 13 | * 14 | */ 15 | public class KCWebChromeClient extends WebChromeClient 16 | { 17 | private static KCWebChromeClient mInstance; 18 | private boolean mEnableConsoleLog; 19 | 20 | public KCWebChromeClient() 21 | { 22 | super(); 23 | } 24 | 25 | public static KCWebChromeClient getInstance() 26 | { 27 | if (mInstance == null) 28 | mInstance = new KCWebChromeClient(); 29 | return mInstance; 30 | } 31 | 32 | @Override 33 | public boolean onConsoleMessage(ConsoleMessage consoleMessage) 34 | { 35 | 36 | // we MUST return true we are done with debugging 37 | return !mEnableConsoleLog; // return false to enable console.log 38 | } 39 | 40 | @Override 41 | public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) 42 | { 43 | if(view instanceof KCWebView) { 44 | result.confirm(KCApiBridge.callNative((KCWebView) view, message)); 45 | } 46 | return true; 47 | 48 | } 49 | 50 | // @Override 51 | // public boolean onJsAlert(WebView view, String url, String message, JsResult result) 52 | // { 53 | // result.confirm(); 54 | // return true; 55 | // } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /kerkee/src/com/kercer/kerkee/webview/KCWebPath.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.webview; 2 | 3 | import android.content.Context; 4 | 5 | import com.kercer.kerkee.downloader.KCDownloader.KCScheme; 6 | 7 | /** 8 | * 9 | * @author zihong 10 | * 11 | */ 12 | public class KCWebPath 13 | { 14 | protected KCScheme mBridgeScheme; //the scheme is the same as KCApiBridge 15 | private String mRootPath = null; 16 | Context mContext; 17 | 18 | public KCWebPath(Context aContext) 19 | { 20 | mContext = aContext; 21 | } 22 | 23 | /** 24 | * 25 | * @param aPath webview root path,if path if null, default root path is context'files dir 26 | * 27 | */ 28 | public void setRootPath(String aPath) 29 | { 30 | mRootPath = aPath; 31 | } 32 | 33 | public String getRootPath() 34 | { 35 | if (mRootPath == null) 36 | { 37 | if(mContext.getFilesDir() != null) { 38 | mRootPath = mContext.getFilesDir().getAbsolutePath(); 39 | } else { 40 | mRootPath = mContext.getExternalFilesDir(null).getAbsolutePath(); 41 | } 42 | } 43 | return mRootPath; 44 | } 45 | 46 | public String getResRootPath() 47 | { 48 | return getRootPath() + "/html"; 49 | } 50 | 51 | public String getCfgPath() 52 | { 53 | return getResRootPath() + "/conf/urlmapping.conf"; 54 | } 55 | 56 | public String getJSBridgePath() 57 | { 58 | return getResRootPath() + getJSBridgeRelativePath(); 59 | } 60 | 61 | public String getJSBridgeRelativePath() 62 | { 63 | return "/kerkee.js"; 64 | } 65 | 66 | public String getWebImageCacheRelativePath() 67 | { 68 | return "/cache/webimages"; 69 | } 70 | 71 | public String getWebImageCachePath() 72 | { 73 | return getResRootPath() + getWebImageCacheRelativePath(); 74 | } 75 | 76 | public KCScheme getBridgeScheme() 77 | { 78 | return mBridgeScheme; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /kerkee_example/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kerkee_example 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /kerkee_example/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/conf/urlmapping.conf: -------------------------------------------------------------------------------- 1 | #路由映射表 UrlMapping 2 | 3 | #-----------------------------------------------# 4 | # 客户端需要用到的URL # 5 | #-----------------------------------------------# 6 | # test.html: 测试文件 7 | #-----------------------------------------------# 8 | 9 | /test.html /modules/test/test.html 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/conf/version.conf: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /kerkee_example/assets/html/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/assets/html/icon.png -------------------------------------------------------------------------------- /kerkee_example/assets/html/manifest: -------------------------------------------------------------------------------- 1 | # Version: 1.0.2 2 | 3 | # RequiredVersion:1.1.0 4 | 5 | # List: ./modules/manifest 6 | 7 | # Dek: http://www.linzihong.com/html.dek 8 | 9 | CACHE: 10 | 11 | NETWORK: 12 | * 13 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/clientApi/manifest: -------------------------------------------------------------------------------- 1 | # Version: 1.0.2 2 | 3 | # RequiredVersion:2.0.2 4 | 5 | # Dek: ./html.dek 6 | 7 | CACHE: 8 | 9 | NETWORK: 10 | * 11 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/clientApi/objExampleApi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Demo相关接口 3 | * @class objExampleApi 4 | * @extends Klass 5 | * @constructor 6 | * @module modules 7 | * @example 8 | * define('helper/objExampleApi',',function(platform){ 9 | * testApi.getTestInfo(); 10 | * }); 11 | * @since 1.0.0 12 | * @public 13 | */ 14 | 15 | define(["api/helper/util"], function (util) { 16 | 17 | var ObjExampleApi = (function () { 18 | 19 | //构建一个TestApi类,继承自基础类 20 | util.Klass().sub(ObjExampleApi); 21 | 22 | //构造函数 23 | function ObjExampleApi() { 24 | /** 25 | * 映射客户端类的名称 (必选) 26 | * @property nativeCls 27 | * @type string 28 | * @since 1.0.0 29 | * @default "jsBridgeClient" 30 | * @public 31 | */ 32 | 33 | /** 34 | * jsBridgeClient通信对象 (必选) 35 | * @property jsbc 36 | * @type string 37 | * @since 1.0.0 38 | * @default jsBridgeClient 39 | * @public 40 | */ 41 | 42 | /** 43 | * 模块信息描述 (可选) 44 | * @property name 45 | * @type string 46 | * @since 1.0.0 47 | * @public 48 | */ 49 | 50 | /** 51 | * 模块版本 (可选) 52 | * @property verison 53 | * @type int 54 | * @since 1.0.0 55 | * @public 56 | */ 57 | 58 | /** 59 | * 模块作者 (可选) 60 | * @property author 61 | * @type string 62 | * @since 1.0.0 63 | * @public 64 | */ 65 | 66 | ObjExampleApi.__super__.constructor.apply(this, arguments); 67 | } 68 | 69 | ObjExampleApi.include({ 70 | 71 | /** 72 | * 测试非静态的Native函数 73 | * @method objExampleNotStaticFunction 74 | * @public 75 | * @param {Function} callBack 回调函数 76 | * @param {String} testInfo 测试信息 77 | * @return {Object} 78 | * @example 79 | * objExampleApi.objExampleNotStaticFunction(function(data){ 80 | * console.log(data); 81 | * },"test"); 82 | * @since 1.0.0 83 | */ 84 | objExampleNotStaticFunction: function (callBack, testInfo) { 85 | this.sendData({ 86 | method: "objExampleNotStaticFunction", 87 | param: { 88 | "testInfo": testInfo 89 | }, 90 | callBack: callBack 91 | }); 92 | }, 93 | 94 | /** 95 | * 测试静态的Native函数 96 | * @method objExampleStaticFunction 97 | * @public 98 | * @param {Function} callBack 回调函数 99 | * @param {String} testInfo 测试信息 100 | * @return {Object} 101 | * @example 102 | * objExampleApi.objExampleStaticFunction(function(data){ 103 | * console.log(data); 104 | * },"test"); 105 | * @since 1.0.0 106 | */ 107 | objExampleStaticFunction: function (callBack, testInfo) { 108 | this.sendData({ 109 | method: "objExampleStaticFunction", 110 | param: { 111 | "testInfo": testInfo 112 | }, 113 | callBack: callBack 114 | }); 115 | } 116 | 117 | }); 118 | return ObjExampleApi; 119 | })(); 120 | 121 | return new ObjExampleApi({ 122 | name: "kerkee objExampleApi", 123 | author: "zihong", 124 | version: "1.0", 125 | jsbc: jsBridgeClient, 126 | nativeCls: "objExampleApi" 127 | }); 128 | 129 | }); -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/clientApi/testApi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Demo相关接口 3 | * @class TestApi 4 | * @extends Klass 5 | * @constructor 6 | * @module modules 7 | * @example 8 | * define('helper/testApi',',function(platform){ 9 | * testApi.getTestInfo(); 10 | * }); 11 | * @since 1.0.0 12 | * @public 13 | */ 14 | 15 | define(["api/helper/util"], function ( util) { 16 | 17 | var TestApi = (function () { 18 | 19 | //构建一个TestApi类,继承自基础类 20 | util.Klass().sub(TestApi); 21 | 22 | //构造函数 23 | function TestApi() { 24 | /** 25 | * 映射客户端类的名称 (必选) 26 | * @property nativeCls 27 | * @type string 28 | * @since 1.0.0 29 | * @default "jsBridgeClient" 30 | * @public 31 | */ 32 | 33 | /** 34 | * jsBridgeClient通信对象 (必选) 35 | * @property jsbc 36 | * @type string 37 | * @since 1.0.0 38 | * @default jsBridgeClient 39 | * @public 40 | */ 41 | 42 | /** 43 | * 模块信息描述 (可选) 44 | * @property name 45 | * @type string 46 | * @since 1.0.0 47 | * @public 48 | */ 49 | 50 | /** 51 | * 模块版本 (可选) 52 | * @property verison 53 | * @type int 54 | * @since 1.0.0 55 | * @public 56 | */ 57 | 58 | /** 59 | * 模块作者 (可选) 60 | * @property author 61 | * @type string 62 | * @since 1.0.0 63 | * @public 64 | */ 65 | 66 | TestApi.__super__.constructor.apply(this, arguments); 67 | } 68 | 69 | TestApi.include({ 70 | 71 | /** 72 | * 获取测试信息 73 | * @method getTestInfo 74 | * @public 75 | * @param {Function} callBack 回调函数 76 | * @param {String} testInfo 测试信息 77 | * @return {Object} 78 | * @example 79 | * testApi.getTestInfo(function(data){ 80 | * console.log(data); 81 | * },"test"); 82 | * @since 1.0.0 83 | */ 84 | getTestInfo: function (callBack, testInfo) { 85 | this.sendData({ 86 | method: "testInfo", 87 | param: { 88 | "testInfo": "I'm testInfo" 89 | }, 90 | callBack: callBack 91 | }); 92 | } 93 | 94 | 95 | }); 96 | return TestApi; 97 | })(); 98 | 99 | return new TestApi({ 100 | name: "kerkee testApi", 101 | author: "zihong", 102 | version: "1.0", 103 | jsbc: jsBridgeClient, 104 | nativeCls: "testModule" 105 | }); 106 | 107 | }); 108 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/manifest: -------------------------------------------------------------------------------- 1 | # Version: 1.0.2 2 | 3 | # RequiredVersion:2.0.2 4 | 5 | # List: ./test/manifest, ./clientApi/manifest 6 | 7 | # Dek: html.dek 8 | 9 | CACHE: 10 | 11 | NETWORK: 12 | * 13 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/test/manifest: -------------------------------------------------------------------------------- 1 | # Version: 1.0.2 2 | 3 | # RequiredVersion:2.0.2 4 | 5 | # Dek: ./html.dek 6 | 7 | CACHE: 8 | 9 | NETWORK: 10 | * 11 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //requirejs通用模块设置 4 | requirejs.config({ 5 | 6 | baseUrl:"../../modules", 7 | 8 | paths: { 9 | api:"../vendor/api", 10 | kerkee: "../kerkee", 11 | zepto:"../vendor/lib/zepto.min", 12 | template: '../vendor/lib/template', 13 | domReady: '../vendor/plugin/domReady' 14 | }, 15 | 16 | waitSeconds: 10, 17 | 18 | shim: { 19 | "kerkee": { 20 | exports: "kerkee" 21 | }, 22 | 23 | 'zepto':{ 24 | exports:'$' 25 | }, 26 | 27 | 'template': { 28 | exports: "template" 29 | } 30 | } 31 | }); 32 | 33 | //入口方法初始化 34 | require(["test/testDo"],function(testDo){ 35 | testDo.init(); 36 | }); 37 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/modules/test/testDo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by zihong on 2015/9/14. 3 | */ 4 | define([ 5 | 'zepto', 6 | 'template', 7 | 'clientApi/clientUI', 8 | 'clientApi/clientInfo', 9 | 'api/helper/util', 10 | 'api/nativeUI/widget', 11 | 'clientApi/testApi', 12 | 'clientApi/objExampleApi', 13 | 'domReady!' 14 | ], 15 | 16 | function ($,template,clientUI,clientInfo,util,widget,testApi,objExampleApi) { 17 | function TestDo(){ 18 | } 19 | 20 | TestDo.prototype.render=function(){ 21 | $('body').on('click','.toast',function(){ 22 | widget.toast('this is a test'); 23 | }); 24 | 25 | $('body').on('click','.alert',function(){ 26 | widget.alertDialog('this is a test','this is a test message',function(){ alert("callback normal"); },'OK'); 27 | }); 28 | 29 | // alertClientUI 30 | $('body').on('click','.alertClientUI',function(){ 31 | clientUI.clientToast('this is a test','warn'); 32 | }); 33 | 34 | $('body').on('click','.testInfo',function(){ 35 | alert(1); 36 | testApi.getTestInfo(function(data){ 37 | console.log("callback:"+data); 38 | },"test getTestInfo fun"); 39 | }); 40 | 41 | //objExampleNotStaticFunction 42 | $('body').on('click','.objExampleNotStaticFunction',function(){ 43 | objExampleApi.objExampleNotStaticFunction(function(data){ 44 | console.log("callback:"+data); 45 | },"objExampleApi.objExampleNotStaticFunction that click from js"); 46 | }); 47 | 48 | //objExampleStaticFunction 49 | $('body').on('click','.objExampleStaticFunction',function(){ 50 | objExampleApi.objExampleStaticFunction(function(data){ 51 | console.log("callback:"+data); 52 | },"objExampleApi.objExampleStaticFunction that click from js"); 53 | }); 54 | 55 | window.testReturnString = function (json){ 56 | 57 | // var test = {}; 58 | // test.a = "t1"; 59 | // test.b = "t2"; 60 | // test.c = "t3"; 61 | // test.d = "t4"; 62 | // alert(JSON.stringify(test)); 63 | alert(typeof(json)); 64 | alert(json); 65 | alert(JSON.stringify(json)); 66 | 67 | // return test; 68 | return "Im testReturnString"; 69 | }; 70 | }; 71 | 72 | TestDo.prototype.init=function(){ 73 | var t=this; 74 | testApi.start(function () { 75 | t.render(); 76 | }); 77 | }; 78 | 79 | return new TestDo(); 80 | }); 81 | -------------------------------------------------------------------------------- /kerkee_example/assets/html/vendor/api/device/platform.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 客户端基础信息获取 3 | * @class Platform 4 | * @extends Klass 5 | * @constructor 6 | * @module device 7 | * @example 8 | * define('api/client/Platform',function(platform){ 9 | * platform.getNetworkType(); 10 | * }); 11 | * @since 1.0.0 12 | * @public 13 | */ 14 | 15 | define(['api/helper/util'],function(util){ 16 | 17 | var Platform=(function(){ 18 | 19 | //构建一个Platform类,继承自基础类 20 | util.Klass().sub(Platform); 21 | 22 | //构造函数 23 | function Platform() { 24 | /** 25 | * 映射客户端类的名称 (必选) 26 | * @property nativeCls 27 | * @type string 28 | * @since 1.0.0 29 | * @default "platform" 30 | * @public 31 | */ 32 | 33 | /** 34 | * jsBridgeClient通信对象 (必选) 35 | * @property jsbc 36 | * @type string 37 | * @since 1.0.0 38 | * @default jsBridgeClient 39 | * @public 40 | */ 41 | 42 | /** 43 | * 模块信息描述 (可选) 44 | * @property name 45 | * @type string 46 | * @since 1.0.0 47 | * @public 48 | */ 49 | 50 | /** 51 | * 模块版本 (可选) 52 | * @property verison 53 | * @type int 54 | * @since 1.0.0 55 | * @public 56 | */ 57 | 58 | /** 59 | * 模块作者 (可选) 60 | * @property author 61 | * @type string 62 | * @since 1.0.0 63 | * @public 64 | */ 65 | 66 | Platform.__super__.constructor.apply(this, arguments); 67 | } 68 | 69 | Platform.include({ 70 | /** 71 | * 判断当前的网络状态 72 | * @method getNetwork 73 | * @public 74 | * @param {Function} callBack 回调函数 75 | * @return {Object} 76 | * { 77 | * "type":"wifi", 78 | * "p1":"NjAxMjIzODg3Nzc3NDIyOTU4Mg==" 79 | * } 80 | *

主要字段

81 | * 82 | * 83 | * 84 | * 85 | *
字段名称字段说明
type网络状态
p1设备p1值
86 | * @example 87 | * clientInfo.getNetwork(function(status){ 88 | * console.log(status.type); 89 | * }); 90 | * @since 1.0.0 91 | */ 92 | getNetworkType:function(callBack){ 93 | this.sendData({ 94 | method: "getNetworkType", 95 | param: { 96 | "info": "getNetworkType" 97 | }, 98 | callBack: callBack 99 | }); 100 | }, 101 | 102 | /** 103 | * 读取设备分辨率信息 104 | * @method getDevice 105 | * @public 106 | * @param {Function} callBack 回调函数 107 | * @return {Object} 108 | * { 109 | * "model":"Nexus 4", 110 | * "brand":"google", 111 | * "device":"mako", 112 | * "display":"768x1184", 113 | * "product":"occam", 114 | * "hardware":"mako", 115 | * "density":"2", 116 | * "densityDpi":"320", 117 | * } 118 | *

主要字段

119 | * 120 | * 121 | * 122 | * 123 | * 124 | * 125 | * 126 | * 127 | *
字段名称字段说明
model手机型号
brand手机出品商
device设备信息
hardware设备信息
density屏幕精度倍数
densityDpi屏幕精度
128 | * @example 129 | * clientInfo.getDevice(function(data){ 130 | * console.log(data); 131 | * } 132 | * @since 1.0.0 133 | */ 134 | getDevice:function(callBack){ 135 | this.sendData({ 136 | method: "getDevice", 137 | param: { 138 | "info": "getDevice" 139 | }, 140 | callBack: callBack 141 | }); 142 | } 143 | }); 144 | 145 | 146 | return Platform; 147 | })(); 148 | 149 | 150 | return new Platform({ 151 | name: "device infomation", 152 | author: "huangjian", 153 | version: "1.0", 154 | jsbc: jsBridgeClient, 155 | nativeCls: "platform" 156 | }); 157 | }); -------------------------------------------------------------------------------- /kerkee_example/assets/html/vendor/plugin/domReady.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | 'use strict'; 3 | 4 | var isTop, testDiv, scrollIntervalId, 5 | isBrowser = typeof window !== "undefined" && window.document, 6 | isPageLoaded = !isBrowser, 7 | doc = isBrowser ? document : null, 8 | readyCalls = []; 9 | 10 | function runCallbacks(callbacks) { 11 | var i; 12 | for (i = 0; i < callbacks.length; i += 1) { 13 | callbacks[i](doc); 14 | } 15 | } 16 | 17 | function callReady() { 18 | var callbacks = readyCalls; 19 | 20 | if (isPageLoaded) { 21 | //Call the DOM ready callbacks 22 | if (callbacks.length) { 23 | readyCalls = []; 24 | runCallbacks(callbacks); 25 | } 26 | } 27 | } 28 | 29 | /** 30 | * Sets the page as loaded. 31 | */ 32 | function pageLoaded() { 33 | if (!isPageLoaded) { 34 | isPageLoaded = true; 35 | if (scrollIntervalId) { 36 | clearInterval(scrollIntervalId); 37 | } 38 | 39 | callReady(); 40 | } 41 | } 42 | 43 | if (isBrowser) { 44 | if (document.addEventListener) { 45 | //Standards. Hooray! Assumption here that if standards based, 46 | //it knows about DOMContentLoaded. 47 | document.addEventListener("DOMContentLoaded", pageLoaded, false); 48 | window.addEventListener("load", pageLoaded, false); 49 | } else if (window.attachEvent) { 50 | window.attachEvent("onload", pageLoaded); 51 | 52 | testDiv = document.createElement('div'); 53 | try { 54 | isTop = window.frameElement === null; 55 | } catch (e) {} 56 | 57 | //DOMContentLoaded approximation that uses a doScroll, as found by 58 | //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/, 59 | //but modified by other contributors, including jdalton 60 | if (testDiv.doScroll && isTop && window.external) { 61 | scrollIntervalId = setInterval(function () { 62 | try { 63 | testDiv.doScroll(); 64 | pageLoaded(); 65 | } catch (e) {} 66 | }, 30); 67 | } 68 | } 69 | 70 | //Check if document already complete, and if so, just trigger page load 71 | //listeners. Latest webkit browsers also use "interactive", and 72 | //will fire the onDOMContentLoaded before "interactive" but not after 73 | //entering "interactive" or "complete". More details: 74 | //http://dev.w3.org/html5/spec/the-end.html#the-end 75 | //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded 76 | //Hmm, this is more complicated on further use, see "firing too early" 77 | //bug: https://github.com/requirejs/domReady/issues/1 78 | //so removing the || document.readyState === "interactive" test. 79 | //There is still a window.onload binding that should get fired if 80 | //DOMContentLoaded is missed. 81 | if (document.readyState === "complete") { 82 | pageLoaded(); 83 | } 84 | } 85 | 86 | /** START OF PUBLIC API **/ 87 | 88 | /** 89 | * Registers a callback for DOM ready. If DOM is already ready, the 90 | * callback is called immediately. 91 | * @param {Function} callback 92 | */ 93 | function domReady(callback) { 94 | if (isPageLoaded) { 95 | callback(doc); 96 | } else { 97 | readyCalls.push(callback); 98 | } 99 | return domReady; 100 | } 101 | 102 | domReady.version = '2.0.1'; 103 | 104 | /** 105 | * Loader Plugin API method 106 | */ 107 | domReady.load = function (name, req, onLoad, config) { 108 | if (config.isBuild) { 109 | onLoad(null); 110 | } else { 111 | domReady(onLoad); 112 | } 113 | }; 114 | 115 | /** END OF PUBLIC API **/ 116 | 117 | return domReady; 118 | }); 119 | -------------------------------------------------------------------------------- /kerkee_example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | 6 | defaultConfig { 7 | minSdkVersion 14 8 | targetSdkVersion 25 9 | versionCode 1 10 | versionName "1.0" 11 | resValue "string", "ker__authority", "com.kercer.kerkee_example" 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | sourceSets { 22 | main { 23 | manifest.srcFile 'AndroidManifest.xml' 24 | java.srcDirs = ['src'] 25 | resources.srcDirs = ['src'] 26 | aidl.srcDirs = ['src'] 27 | renderscript.srcDirs = ['src'] 28 | res.srcDirs = ['res'] 29 | assets.srcDirs = ['assets'] 30 | 31 | // jni.srcDirs = [] 32 | jniLibs.srcDirs = ['libs'] 33 | } 34 | 35 | // Move the tests to tests/java, tests/res, etc... 36 | androidTest.setRoot('tests') 37 | 38 | // Move the build types to build-types/ 39 | // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... 40 | // This moves them out of them default location under src//... which would 41 | // conflict with src/ being used by the main source set. 42 | // Adding new build types or product flavors should be accompanied 43 | // by a similar customization. 44 | debug.setRoot('build-types/debug') 45 | release.setRoot('build-types/release') 46 | } 47 | } 48 | 49 | dependencies { 50 | implementation fileTree(dir: 'libs', include: '*.jar') 51 | implementation project(':kerkee') 52 | // compile "com.kercer:kerkee:1.3.24" 53 | } 54 | -------------------------------------------------------------------------------- /kerkee_example/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/ic_launcher-web.png -------------------------------------------------------------------------------- /kerkee_example/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /kerkee_example/proguard-project.txt: -------------------------------------------------------------------------------- 1 | -dontoptimize 2 | -dontusemixedcaseclassnames 3 | -keepattributes *Annotation* 4 | -dontpreverify 5 | -verbose 6 | -dontwarn android.support.** 7 | -ignorewarnings 8 | 9 | 10 | -keep public class com.google.vending.licensing.ILicensingService 11 | 12 | -keep public class com.android.vending.licensing.ILicensingService 13 | 14 | # keep setters in Views so that animations can still work. 15 | # see http://proguard.sourceforge.net/manual/examples.html#beans 16 | -keepclassmembers public class * extends android.view.View { 17 | void set*(***); 18 | *** get*(); 19 | } 20 | 21 | # We want to keep methods in Activity that could be used in the XML attribute onClick 22 | -keepclassmembers class * extends android.app.Activity { 23 | public void *(android.view.View); 24 | } 25 | 26 | -keep class * extends android.os.Parcelable { 27 | public static final android.os.Parcelable$Creator *; 28 | } 29 | 30 | -keepclassmembers class **.R$* { 31 | public static ; 32 | } 33 | 34 | # for runtime library############ 35 | 36 | #-keep class com.sohu.android.plugin.** {*;} 37 | #-keep class com.sohu.push.** {*;} 38 | -keep public class com.kercer.**{ 39 | *; 40 | } 41 | 42 | -keep class * implements com.sohu.push.notification.NotificationFilter {public *;} 43 | 44 | 45 | # Also keep - Enumerations. Keep the special static methods that are required in 46 | # enumeration classes. 47 | -keepclassmembers enum * { 48 | public static **[] values(); 49 | public static ** valueOf(java.lang.String); 50 | } 51 | 52 | # Keep names - Native method names. Keep all native class/method names. 53 | -keepclasseswithmembers,allowshrinking class * { 54 | native ; 55 | } 56 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_back.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_back_dis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_back_dis.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_back_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_back_pressed.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_forward.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_forward_dis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_forward_dis.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_forward_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_forward_pressed.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_refresh.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_refresh_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_refresh_pressed.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_stop.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/browser_btn_stop_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/browser_btn_stop_pressed.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/btn_bookmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/btn_bookmark.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/btn_bookmark_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/btn_bookmark_pressed.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/btn_browser_bookmark_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/btn_browser_bookmark_normal.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/edit_panel_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/edit_panel_bg.9.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/nav_icon_goto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/nav_icon_goto.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/nav_icon_goto_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/nav_icon_goto_press.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-hdpi/top_nav_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-hdpi/top_nav_bg.9.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kercer/kerkee_android/a36aa3d6c3535dcb2d4f881631d4cf7dbe88032c/kerkee_example/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_browser_control_back_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_browser_control_bookmark_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_browser_control_forward_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_browser_control_refresh_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_browser_control_stop_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /kerkee_example/res/drawable/btn_header_bar_back_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /kerkee_example/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /kerkee_example/res/layout/browser.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 30 | 31 | 36 | 37 | 46 | 47 | 55 | 56 | 65 | 66 | 71 | 72 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /kerkee_example/res/layout/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /kerkee_example/res/layout/header_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 23 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /kerkee_example/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /kerkee_example/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /kerkee_example/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /kerkee_example/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 64dp 9 | 10 | 11 | -------------------------------------------------------------------------------- /kerkee_example/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ff000000 4 | #eeffffff 5 | #FFFF7200 6 | 7 | -------------------------------------------------------------------------------- /kerkee_example/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 45dip 8 | 44dip 9 | 18dip 10 | 11 | 12 | -------------------------------------------------------------------------------- /kerkee_example/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | kerkee 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /kerkee_example/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 33 | 34 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/activity/KCMainActivity.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.activity; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.Menu; 6 | import android.view.MenuItem; 7 | import android.view.View; 8 | 9 | import com.kercer.kercore.debug.KCLog; 10 | import com.kercer.kercore.io.KCAssetTool; 11 | import com.kercer.kerkee.api.KCRegistMgr; 12 | import com.kercer.kerkee.bridge.KCJSObject; 13 | import com.kercer.kerkee.bridge.KerkeeMethod; 14 | import com.kercer.kerkee.browser.KCDefaultBrowser; 15 | import com.kercer.kerkee.webview.KCWebPath; 16 | import com.kercer.kerkee_example.R; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | 21 | public class KCMainActivity extends Activity 22 | { 23 | public class KCTest extends KCJSObject 24 | { 25 | @Override 26 | public String getJSObjectName() 27 | { 28 | return "test"; 29 | } 30 | 31 | @KerkeeMethod 32 | public String testString() 33 | { 34 | return null; 35 | } 36 | 37 | } 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) 41 | { 42 | super.onCreate(savedInstanceState); 43 | // setContentView(R.layout.activity_main); 44 | 45 | //copy asset to html dir first 46 | //if you use zip, you can unzip to html dir 47 | if (!isExitAsset()) 48 | copyAssetHtmlDir(); 49 | 50 | 51 | //create browser that use KCWebview 52 | KCDefaultBrowser browser = new KCDefaultBrowser(this); 53 | View view = browser.getView(); 54 | setContentView(view); 55 | 56 | //regist classes to JSBridge,the relationship between binding js objects and native classes 57 | //and you can use default browser'b registJSBridgeClient function 58 | KCRegistMgr.registClass(); 59 | //you can registObject here; 60 | // KCJSBridge.registObject(new KCTest()); 61 | 62 | browser.loadTestPage(); 63 | // browser.loadUrl("http://www.baidu.com"); 64 | 65 | } 66 | 67 | 68 | 69 | 70 | private boolean isExitAsset() 71 | { 72 | KCWebPath webPath = new KCWebPath(this); 73 | String cfgPath = webPath.getCfgPath(); 74 | File file = new File(cfgPath); 75 | if (file.exists()) 76 | return true; 77 | return false; 78 | } 79 | 80 | private void copyAssetHtmlDir() 81 | { 82 | KCAssetTool assetTool = new KCAssetTool(this); 83 | try 84 | { 85 | assetTool.copyDir("html", new KCWebPath(this).getResRootPath()); 86 | } 87 | catch (IOException e) 88 | { 89 | KCLog.e(e); 90 | } 91 | } 92 | 93 | 94 | @Override 95 | public boolean onCreateOptionsMenu(Menu menu) 96 | { 97 | 98 | // Inflate the menu; this adds items to the action bar if it is present. 99 | getMenuInflater().inflate(R.menu.main, menu); 100 | return true; 101 | } 102 | 103 | @Override 104 | public boolean onOptionsItemSelected(MenuItem item) 105 | { 106 | // Handle action bar item clicks here. The action bar will 107 | // automatically handle clicks on the Home/Up button, so long 108 | // as you specify a parent activity in AndroidManifest.xml. 109 | int id = item.getItemId(); 110 | if (id == R.id.action_settings) 111 | { 112 | return true; 113 | } 114 | return super.onOptionsItemSelected(item); 115 | } 116 | 117 | public static void test(String a, int b, boolean c) 118 | { 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiClientInfo.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | public class KCApiClientInfo 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiClientUI.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | public class KCApiClientUI 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiJSBridgeClient.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.kercer.kercore.debug.KCLog; 6 | import com.kercer.kerkee.bridge.KCArgList; 7 | import com.kercer.kerkee.bridge.KCJSCompileExecutor; 8 | import com.kercer.kerkee.bridge.KCJSDefine; 9 | import com.kercer.kerkee.bridge.KCJSError; 10 | import com.kercer.kerkee.bridge.type.KCReturnCallback; 11 | import com.kercer.kerkee.browser.KCJSBridge; 12 | import com.kercer.kerkee.webview.KCWebView; 13 | 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | 17 | 18 | /** 19 | * This is a JS object API, the JS object is jsBridgeClient 20 | * @author zihong 21 | * 22 | */ 23 | public class KCApiJSBridgeClient 24 | { 25 | public static void testJSBrige(final KCWebView aWebView, KCArgList aArgList) 26 | { 27 | KCJSCompileExecutor.compileJS(aWebView , new KCReturnCallback() { 28 | @Override 29 | public void returnCallback(Object aObject, KCJSError aError) { 30 | KCLog.i(""); 31 | } 32 | }, "XMLHttpRequest"); 33 | 34 | //test get js object 35 | KCJSCompileExecutor.compileJS(aWebView, new KCReturnCallback() 36 | { 37 | @Override 38 | public void returnCallback(Object aObject, KCJSError aError) 39 | { 40 | KCLog.i(""); 41 | } 42 | }, "document.title"); 43 | 44 | // try { 45 | // JSONObject obj = new JSONObject("{key=a}"); 46 | // 47 | // ArrayList list = new ArrayList(); 48 | // list.add("12"); 49 | // list.add("aa"); 50 | // String s = list.toString(); 51 | // 52 | // JSONArray array = new JSONArray(list); 53 | // 54 | // String js = "testReturnString(1, 2)"; 55 | // 56 | // KCJSCompileExecutor.compileFunction(aWebView, new KCReturnCallback() { 57 | // @Override 58 | // public void returnCallback(Object aObject, KCJSError aError) { 59 | // KCLog.i("a"); 60 | // if (aError != null) { 61 | // KCLog.e(aError.toString()); 62 | // } 63 | // 64 | // } 65 | // }, "testReturnString", list); 66 | // 67 | // 68 | // } catch (JSONException e) { 69 | // e.printStackTrace(); 70 | // } 71 | 72 | 73 | 74 | 75 | String str = aArgList.toString(); 76 | Toast.makeText(aWebView.getContext(), str, 77 | Toast.LENGTH_SHORT).show(); 78 | if (KCLog.DEBUG) 79 | KCLog.d(">>>>>> NewApiTest testJSBrige called: " + aArgList.toString()); 80 | } 81 | 82 | public static void commonApi(final KCWebView aWebView, KCArgList aArgList) 83 | { 84 | if (KCLog.DEBUG) 85 | KCLog.d(">>>>>> NewApiTest commonApi called: " + aArgList.toString()); 86 | 87 | String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 88 | JSONObject jsonObject = null; 89 | try 90 | { 91 | jsonObject = new JSONObject("{'key'='value'}"); 92 | } 93 | catch (JSONException e) 94 | { 95 | KCLog.e(e); 96 | } 97 | KCJSBridge.callbackJS(aWebView, callbackId, jsonObject); 98 | } 99 | 100 | public static void onSetImage(final KCWebView aWebView, KCArgList aArgList) 101 | { 102 | if (KCLog.DEBUG) 103 | KCLog.d(">>>>>> NewApiTest onSetImage called: " + aArgList.toString()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiJSObjExample.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.kercer.kerkee.bridge.KCArgList; 6 | import com.kercer.kerkee.bridge.KCJSObject; 7 | import com.kercer.kerkee.bridge.type.KCJSCallback; 8 | import com.kercer.kerkee.webview.KCWebView; 9 | 10 | /** 11 | * Created by zihong on 16/3/7. 12 | */ 13 | public class KCApiJSObjExample extends KCJSObject 14 | { 15 | @Override 16 | public String getJSObjectName() 17 | { 18 | return KCJSObjDefine.kJS_JSObjExampleModule; 19 | } 20 | 21 | //成员方法 22 | public void objExampleNotStaticFunction(final KCWebView aWebView, KCArgList aArgList) 23 | { 24 | String strTestInfo = aArgList.getString("testInfo"); 25 | Toast.makeText(aWebView.getContext(), strTestInfo, Toast.LENGTH_SHORT).show(); 26 | 27 | KCJSCallback callback = aArgList.getCallback(); 28 | if (callback != null) 29 | { 30 | callback.callbackToJS(aWebView, "I'm callbackData"); 31 | } 32 | 33 | String strArgList = aArgList.toString(); 34 | Toast.makeText(aWebView.getContext(), strArgList, Toast.LENGTH_SHORT).show(); 35 | } 36 | 37 | //静态方法 38 | public static void objExampleStaticFunction(final KCWebView aWebView, KCArgList aArgList) 39 | { 40 | String strTestInfo = aArgList.getString("testInfo"); 41 | Toast.makeText(aWebView.getContext(), strTestInfo, Toast.LENGTH_SHORT).show(); 42 | 43 | KCJSCallback callback = aArgList.getCallback(); 44 | if (callback != null) 45 | { 46 | callback.callbackToJS(aWebView, "I'm callbackData"); 47 | } 48 | 49 | String strArgList = aArgList.toString(); 50 | Toast.makeText(aWebView.getContext(), strArgList, Toast.LENGTH_SHORT).show(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiPlatform.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | import android.os.Build; 7 | import android.telephony.TelephonyManager; 8 | import android.text.TextUtils; 9 | import android.util.DisplayMetrics; 10 | 11 | import com.kercer.kercore.debug.KCLog; 12 | import com.kercer.kerkee.bridge.KCArgList; 13 | import com.kercer.kerkee.bridge.KCJSDefine; 14 | import com.kercer.kerkee.browser.KCJSBridge; 15 | import com.kercer.kerkee.webview.KCWebView; 16 | 17 | import org.json.JSONException; 18 | import org.json.JSONObject; 19 | 20 | public class KCApiPlatform 21 | { 22 | /** 23 | * 没有网络 24 | */ 25 | public static final String NETWORKTYPE_INVALID = "invalid"; 26 | /** 27 | * wap网络 28 | */ 29 | public static final String NETWORKTYPE_WAP = "wap"; 30 | /** 31 | * 2G网络 32 | */ 33 | public static final String NETWORKTYPE_2G = "2g"; 34 | /** 35 | * 3G和3G以上网络,或统称为快速网络 36 | */ 37 | public static final String NETWORKTYPE_3G = "3g"; 38 | /** 39 | * wifi网络 40 | */ 41 | public static final String NETWORKTYPE_WIFI = "wifi"; 42 | 43 | public static void getDevice(final KCWebView aWebView, KCArgList aArgList) 44 | { 45 | if (KCLog.DEBUG) 46 | KCLog.d(">>>>>> NewApiTest getDevice called: " + aArgList.toString()); 47 | 48 | String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 49 | DisplayMetrics dm = new DisplayMetrics(); 50 | dm = aWebView.getContext().getResources().getDisplayMetrics(); 51 | int screenWidth = dm.widthPixels; 52 | int screenHeight = dm.heightPixels; 53 | JSONObject jsonObject = null; 54 | try 55 | { 56 | jsonObject = new JSONObject(); 57 | jsonObject.put("model", Build.MODEL); 58 | jsonObject.put("brand", Build.BRAND); 59 | jsonObject.put("device", Build.DEVICE); 60 | jsonObject.put("display", screenWidth + "X" + screenHeight); 61 | jsonObject.put("product", Build.PRODUCT); 62 | jsonObject.put("hardware", Build.HARDWARE); 63 | } 64 | catch (JSONException e) 65 | { 66 | KCLog.e(e); 67 | } 68 | KCJSBridge.callbackJS(aWebView, callbackId, jsonObject); 69 | } 70 | 71 | public static void getNetworkType(final KCWebView aWebView, KCArgList aArgList) 72 | { 73 | 74 | if (KCLog.DEBUG) 75 | KCLog.d(">>>>>> NewApiTest getNetworkType called: " + aArgList.toString()); 76 | 77 | String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 78 | 79 | ConnectivityManager manager = (ConnectivityManager) aWebView.getContext().getSystemService(Context.CONNECTIVITY_SERVICE); 80 | NetworkInfo networkInfo = manager.getActiveNetworkInfo(); 81 | 82 | String netTypeStr = NETWORKTYPE_INVALID; 83 | if (networkInfo != null && networkInfo.isConnected()) 84 | { 85 | String type = networkInfo.getTypeName(); 86 | 87 | if (type.equalsIgnoreCase("WIFI")) 88 | { 89 | netTypeStr = NETWORKTYPE_WIFI; 90 | } 91 | else if (type.equalsIgnoreCase("MOBILE")) 92 | { 93 | String proxyHost = android.net.Proxy.getDefaultHost(); 94 | 95 | netTypeStr = TextUtils.isEmpty(proxyHost) ? (isFastMobileNetwork(aWebView.getContext()) ? NETWORKTYPE_3G : NETWORKTYPE_2G) : NETWORKTYPE_WAP; 96 | } 97 | } 98 | else 99 | { 100 | netTypeStr = NETWORKTYPE_INVALID; 101 | } 102 | 103 | JSONObject jsonObject = null; 104 | try 105 | { 106 | jsonObject = new JSONObject(); 107 | jsonObject.put("network", netTypeStr); 108 | } 109 | catch (JSONException e) 110 | { 111 | KCLog.e(e); 112 | } 113 | KCJSBridge.callbackJS(aWebView, callbackId, jsonObject); 114 | 115 | } 116 | 117 | public static boolean isFastMobileNetwork(Context context) 118 | { 119 | TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 120 | switch (telephonyManager.getNetworkType()) 121 | { 122 | case TelephonyManager.NETWORK_TYPE_1xRTT: 123 | return false; // ~ 50-100 kbps 124 | case TelephonyManager.NETWORK_TYPE_CDMA: 125 | return false; // ~ 14-64 kbps 126 | case TelephonyManager.NETWORK_TYPE_EDGE: 127 | return false; // ~ 50-100 kbps 128 | case TelephonyManager.NETWORK_TYPE_EVDO_0: 129 | return true; // ~ 400-1000 kbps 130 | case TelephonyManager.NETWORK_TYPE_EVDO_A: 131 | return true; // ~ 600-1400 kbps 132 | case TelephonyManager.NETWORK_TYPE_GPRS: 133 | return false; // ~ 100 kbps 134 | case TelephonyManager.NETWORK_TYPE_HSDPA: 135 | return true; // ~ 2-14 Mbps 136 | case TelephonyManager.NETWORK_TYPE_HSPA: 137 | return true; // ~ 700-1700 kbps 138 | case TelephonyManager.NETWORK_TYPE_HSUPA: 139 | return true; // ~ 1-23 Mbps 140 | case TelephonyManager.NETWORK_TYPE_UMTS: 141 | return true; // ~ 400-7000 kbps 142 | case TelephonyManager.NETWORK_TYPE_EHRPD: 143 | return true; // ~ 1-2 Mbps 144 | case TelephonyManager.NETWORK_TYPE_EVDO_B: 145 | return true; // ~ 5 Mbps 146 | case TelephonyManager.NETWORK_TYPE_HSPAP: 147 | return true; // ~ 10-20 Mbps 148 | case TelephonyManager.NETWORK_TYPE_IDEN: 149 | return false; // ~25 kbps 150 | case TelephonyManager.NETWORK_TYPE_LTE: 151 | return true; // ~ 10+ Mbps 152 | case TelephonyManager.NETWORK_TYPE_UNKNOWN: 153 | return false; 154 | default: 155 | return false; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiTestModule.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.kercer.kerkee.bridge.KCArgList; 6 | import com.kercer.kerkee.webview.KCWebView; 7 | 8 | public class KCApiTestModule 9 | { 10 | public static void testInfo(final KCWebView aWebView, KCArgList aArgList) 11 | { 12 | String str = aArgList.getString("testInfo"); 13 | Toast.makeText(aWebView.getContext(), str, Toast.LENGTH_SHORT).show(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCApiWidget.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.DialogInterface; 5 | import android.widget.Toast; 6 | 7 | import com.kercer.kercore.debug.KCLog; 8 | import com.kercer.kerkee.bridge.KCArgList; 9 | import com.kercer.kerkee.bridge.KCJSDefine; 10 | import com.kercer.kerkee.browser.KCJSBridge; 11 | import com.kercer.kerkee.webview.KCWebView; 12 | 13 | import org.json.JSONException; 14 | import org.json.JSONObject; 15 | 16 | public class KCApiWidget 17 | { 18 | 19 | public static void toast(final KCWebView aWebView, KCArgList aArgList) 20 | { 21 | String str = aArgList.toString(); 22 | Toast.makeText(aWebView.getContext(), str, Toast.LENGTH_SHORT).show(); 23 | if (KCLog.DEBUG) 24 | KCLog.d(">>>>>> KCApiWidget toast called: " + aArgList.toString()); 25 | } 26 | 27 | public static void commonApi(final KCWebView aWebView, KCArgList aArgList) 28 | { 29 | if (KCLog.DEBUG) 30 | KCLog.d(">>>>>> KCApiWidget commonApi called: " + aArgList.toString()); 31 | String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 32 | JSONObject jsonObject = null; 33 | try 34 | { 35 | jsonObject = new JSONObject("{'key'='value'}"); 36 | } 37 | catch (JSONException e) 38 | { 39 | KCLog.e(e); 40 | } 41 | KCJSBridge.callbackJS(aWebView, callbackId, jsonObject); 42 | } 43 | 44 | public static void onSetImage(final KCWebView aWebView, KCArgList aArgList) 45 | { 46 | if (KCLog.DEBUG) 47 | KCLog.d(">>>>>> KCApiWidget onSetImage called: " + aArgList.toString()); 48 | } 49 | 50 | public static void showDialog(final KCWebView aWebView, KCArgList aArgList) 51 | { 52 | String jsonStr = aArgList.toString(); 53 | final String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 54 | KCLog.d(">>>>>> KCApiWidget showDialog called: " + callbackId + ",jsonStr>>>>>" + jsonStr); 55 | 56 | String title = aArgList.getString("title"); 57 | String message = aArgList.getString("message"); 58 | String okBtn = aArgList.getString("okBtn"); 59 | String cancelBtn = aArgList.getString("cancelBtn"); 60 | 61 | AlertDialog.Builder builder = new AlertDialog.Builder(aWebView.getContext()); 62 | builder.setTitle(title); 63 | builder.setMessage(message); 64 | builder.setPositiveButton(okBtn, new DialogInterface.OnClickListener() 65 | { 66 | public void onClick(DialogInterface dialog, int whichButton) 67 | { 68 | if (KCLog.DEBUG) 69 | { 70 | KCLog.d(">>>>>> KCApiWidget showDialog called: PositiveButton click"); 71 | } 72 | KCJSBridge.callbackJS(aWebView, callbackId, "1"); 73 | } 74 | }); 75 | 76 | builder.setNegativeButton(cancelBtn, new DialogInterface.OnClickListener() 77 | { 78 | public void onClick(DialogInterface dialog, int whichButton) 79 | { 80 | if (KCLog.DEBUG) 81 | KCLog.d(">>>>>> KCApiWidget showDialog called: NegativeButton click"); 82 | KCJSBridge.callbackJS(aWebView, callbackId, "0"); 83 | } 84 | }); 85 | 86 | builder.show(); 87 | } 88 | 89 | public static void alertDialog(final KCWebView aWebView, KCArgList aArgList) 90 | { 91 | String jsonStr = aArgList.toString(); 92 | final String callbackId = aArgList.getString(KCJSDefine.kJS_callbackId); 93 | KCLog.d(">>>>>> KCApiWidget showDialog called: " + callbackId); 94 | 95 | /* 96 | * if (KCLog.DEBUG) KCLog.d(">>>>>> NewApiTest showDialog called: " + jsonStr); 97 | */ 98 | 99 | String title = aArgList.getString("title"); 100 | String message = aArgList.getString("message"); 101 | String okBtn = aArgList.getString("okBtn"); 102 | String cancelBtn = aArgList.getString("cancelBtn"); 103 | 104 | AlertDialog.Builder builder = new AlertDialog.Builder(aWebView.getContext()); 105 | builder.setTitle(title); 106 | builder.setMessage(message); 107 | builder.setPositiveButton(okBtn, new DialogInterface.OnClickListener() 108 | { 109 | public void onClick(DialogInterface dialog, int whichButton) 110 | { 111 | if (KCLog.DEBUG) 112 | { 113 | KCLog.d(">>>>>> KCApiWidget showDialog called: PositiveButton click"); 114 | } 115 | KCJSBridge.callbackJS(aWebView, callbackId, "1"); 116 | } 117 | }); 118 | 119 | builder.show(); 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCJSObjDefine.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | public class KCJSObjDefine 4 | { 5 | public final static String kJSObj_platform = "platform"; 6 | public final static String kJSObj_widget = "widget"; 7 | 8 | public final static String kJSObj_testModule = "testModule"; 9 | 10 | public final static String kJS_JSObjExampleModule = "objExampleApi"; 11 | } 12 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/api/KCRegistMgr.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.api; 2 | 3 | import com.kercer.kerkee.browser.KCJSBridge; 4 | 5 | public class KCRegistMgr 6 | { 7 | static 8 | { 9 | KCJSBridge.registClass(KCJSObjDefine.kJSObj_platform, KCApiPlatform.class); 10 | KCJSBridge.registClass(KCJSObjDefine.kJSObj_widget, KCApiWidget.class); 11 | 12 | // 注册类,所注册的native code中的类的函数必是静态函数,js都能调到 13 | // 第一个参数为js的类名,第二个参数为native的类名 14 | KCJSBridge.registClass(KCJSObjDefine.kJSObj_testModule, KCApiTestModule.class); 15 | 16 | // 上层可以使用自己的类取代kerkee中的jsBridgeClient,对应的js对象类为jsBridgeClient 17 | // KCJSBridge.registClass(KCJSDefine.kJS_jsBridgeClient, KCApiJSBridgeClient.class);//与下一行效果一致 18 | KCJSBridge.registJSBridgeClient(KCApiJSBridgeClient.class); 19 | 20 | // 注册对象方式 21 | // KCApiJSObjExample必须继承KCJSObject,并实现getJSObjectName()方法,返回js类名 22 | // KCApiJSObjExample中的函数可以是静态函数也可以是成员函数,HybridRuntime会自动处理 23 | KCJSBridge.registObject(new KCApiJSObjExample()); 24 | } 25 | 26 | public static void registClass() 27 | { 28 | // call this func, java can call static block 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kerkee_example/src/com/kercer/kerkee/browser/KCPage.java: -------------------------------------------------------------------------------- 1 | package com.kercer.kerkee.browser; 2 | 3 | 4 | import android.content.Context; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | 8 | /** 9 | * 10 | * @author zihong 11 | * 12 | */ 13 | public class KCPage 14 | { 15 | protected Context mContext; 16 | private View mView; 17 | 18 | public KCPage(Context context, int layoutId) 19 | { 20 | mContext = context; 21 | mView = LayoutInflater.from(context).inflate(layoutId, null); 22 | init(); 23 | } 24 | 25 | public KCPage(Context context, View view) 26 | { 27 | mContext = context; 28 | mView = view; 29 | init(); 30 | } 31 | 32 | private void init() 33 | { 34 | } 35 | 36 | public View getView() 37 | { 38 | return mView; 39 | } 40 | 41 | public View findViewById(int id) 42 | { 43 | return mView.findViewById(id); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':kerkee_example' 2 | include ':kerkee' 3 | //include ':..:kernet_android:kernet' //debug 4 | //include ':..:kercore_android:kercore' //debug 5 | --------------------------------------------------------------------------------