├── .gitignore ├── LICENSE ├── README.md ├── app ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── weexbox │ │ └── example │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── weexbox-update │ │ │ ├── update-config.json │ │ │ ├── update-md5.json │ │ │ └── www.zip │ ├── java │ │ └── com │ │ │ └── weexbox │ │ │ └── example │ │ │ ├── App.kt │ │ │ ├── NormalActivity.kt │ │ │ └── WeexActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ └── loading.gif │ │ ├── layout │ │ ├── activity_normal.xml │ │ └── fragment_container.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── weexbox │ └── example │ └── ExampleUnitTest.kt ├── build.gradle ├── core ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── weexbox │ │ └── core │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── weexbox │ │ │ └── core │ │ │ ├── WeexBoxEngine.kt │ │ │ ├── activity │ │ │ └── PhotoActivity.java │ │ │ ├── adapter │ │ │ ├── ImageAdapter.java │ │ │ ├── MyAppGlideModule.java │ │ │ ├── PageAdapter.java │ │ │ ├── PhotoViewPager.java │ │ │ ├── WebSocketAdapter.kt │ │ │ └── WebSocketAdapterFactory.kt │ │ │ ├── component │ │ │ ├── BaseComponent.kt │ │ │ └── LottieComponent.kt │ │ │ ├── controller │ │ │ ├── WBBaseActivity.kt │ │ │ ├── WBBaseFragment.kt │ │ │ ├── WBWebViewActivity.kt │ │ │ ├── WBWeexActivity.kt │ │ │ └── WBWeexFragment.kt │ │ │ ├── event │ │ │ └── Event.kt │ │ │ ├── extension │ │ │ ├── Map+WeexBox.kt │ │ │ └── String+WeexBox.kt │ │ │ ├── interfaces │ │ │ ├── IFrameHttpRequest.java │ │ │ └── WebViewSetInterface.java │ │ │ ├── model │ │ │ ├── JsOptions.kt │ │ │ ├── Result.kt │ │ │ ├── UpdateConfig.kt │ │ │ ├── UpdateMd5.kt │ │ │ └── WbLibraryModule.java │ │ │ ├── module │ │ │ ├── BaseModule.kt │ │ │ ├── EventModule.kt │ │ │ ├── ExternalModule.kt │ │ │ ├── ModalModule.kt │ │ │ ├── NavigatorModule.kt │ │ │ ├── NetworkModule.kt │ │ │ ├── RouterModule.kt │ │ │ ├── StorageModule.kt │ │ │ └── WXNavigatorModule.kt │ │ │ ├── net │ │ │ ├── CookiesUtil.java │ │ │ ├── HttpParams.java │ │ │ ├── HttpRequestHelper.java │ │ │ ├── HttpUtil.java │ │ │ ├── callback │ │ │ │ ├── HttpBitmapCallback.java │ │ │ │ ├── HttpCallback.java │ │ │ │ ├── HttpEntityCallback.java │ │ │ │ ├── HttpFileCallback.java │ │ │ │ ├── HttpListEntityCallback.java │ │ │ │ └── HttpStringCallback.java │ │ │ └── entity │ │ │ │ ├── HttpBaseEntity.java │ │ │ │ └── INoneConfuse.java │ │ │ ├── network │ │ │ └── Network.kt │ │ │ ├── okhttp │ │ │ ├── OkHttpUtils.java │ │ │ ├── builder │ │ │ │ ├── GetBuilder.java │ │ │ │ ├── HasParamsable.java │ │ │ │ ├── HeadBuilder.java │ │ │ │ ├── OkHttpRequestBuilder.java │ │ │ │ ├── OtherRequestBuilder.java │ │ │ │ ├── PostFileBuilder.java │ │ │ │ ├── PostFormBuilder.java │ │ │ │ └── PostStringBuilder.java │ │ │ ├── callback │ │ │ │ ├── BitmapCallback.java │ │ │ │ ├── Callback.java │ │ │ │ ├── FileCallBack.java │ │ │ │ ├── GenericsCallback.java │ │ │ │ ├── IGenericsSerializator.java │ │ │ │ └── StringCallback.java │ │ │ ├── cookie │ │ │ │ ├── CookieJarImpl.java │ │ │ │ └── store │ │ │ │ │ ├── CookieStore.java │ │ │ │ │ ├── HasCookieStore.java │ │ │ │ │ ├── MemoryCookieStore.java │ │ │ │ │ ├── PersistentCookieStore.java │ │ │ │ │ └── SerializableHttpCookie.java │ │ │ ├── https │ │ │ │ └── HttpsUtils.java │ │ │ ├── log │ │ │ │ └── LoggerInterceptor.java │ │ │ ├── request │ │ │ │ ├── CountingRequestBody.java │ │ │ │ ├── GetRequest.java │ │ │ │ ├── OkHttpRequest.java │ │ │ │ ├── OtherRequest.java │ │ │ │ ├── PostFileRequest.java │ │ │ │ ├── PostFormRequest.java │ │ │ │ ├── PostStringRequest.java │ │ │ │ └── RequestCall.java │ │ │ └── utils │ │ │ │ ├── Exceptions.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── L.java │ │ │ │ └── Platform.java │ │ │ ├── router │ │ │ └── Router.kt │ │ │ ├── update │ │ │ └── UpdateManager.kt │ │ │ ├── util │ │ │ ├── AES128Util.java │ │ │ ├── ActivityManager.java │ │ │ ├── AndroidUtil.java │ │ │ ├── AnimationUtil.java │ │ │ ├── BitmapUtil.java │ │ │ ├── DeviceUtil.java │ │ │ ├── DisplayUtil.java │ │ │ ├── FileUtil.java │ │ │ ├── HotReload.kt │ │ │ ├── ImageUtil.java │ │ │ ├── LoadDialogHelper.java │ │ │ ├── LogUtil.java │ │ │ ├── SelectImageUtil.java │ │ │ ├── StatusBarUtil.java │ │ │ ├── TaskManager.java │ │ │ ├── ToastUtil.java │ │ │ └── VersionUtil.kt │ │ │ ├── webview │ │ │ ├── SonicJavaScriptInterface.java │ │ │ ├── SonicRuntimeImpl.java │ │ │ └── SonicSessionClientImpl.java │ │ │ └── widget │ │ │ ├── DrawableTextView.java │ │ │ ├── FloatingDraftButton.kt │ │ │ └── SimpleToolbar.java │ └── res │ │ ├── drawable-xhdpi │ │ ├── arrows_left.png │ │ ├── arrows_left2.png │ │ ├── arrows_right.png │ │ ├── camera.png │ │ ├── choose1.png │ │ ├── choose2.png │ │ ├── close1.png │ │ ├── close_page_icon.png │ │ ├── icon_go_back.png │ │ ├── logo.png │ │ ├── more.png │ │ ├── more2.png │ │ ├── open.png │ │ ├── refesh.png │ │ └── warn.png │ │ ├── drawable-xxhdpi │ │ ├── arrows_left.png │ │ ├── arrows_left2.png │ │ ├── arrows_right.png │ │ ├── choose1.png │ │ ├── choose2.png │ │ ├── close1.png │ │ ├── icon_go_back.png │ │ ├── more.png │ │ ├── more2.png │ │ └── warn.png │ │ ├── drawable-xxxhdpi │ │ ├── arrows_left.png │ │ ├── arrows_left2.png │ │ ├── arrows_right.png │ │ ├── choose1.png │ │ ├── choose2.png │ │ ├── close1.png │ │ ├── more.png │ │ ├── more2.png │ │ └── warn.png │ │ ├── drawable │ │ └── actionbar_bottom_line.xml │ │ ├── layout │ │ ├── activity_base.xml │ │ ├── activity_photoview.xml │ │ ├── activity_statusbar_layout.xml │ │ ├── activity_web_view.xml │ │ ├── activity_weex.xml │ │ ├── activity_weex_title_layout.xml │ │ ├── fragment_weex.xml │ │ └── layout_floating_button.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── network_security_config.xml │ └── test │ └── java │ └── com │ └── weexbox │ └── core │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | .idea/ 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WeexBox Android SDK https://aygtech.github.io/weexbox/guide/native-android.html 2 | 3 | # 介绍 4 | 5 | WeexBox 致力于打造一套简单、高效的基于 [weex](https://weex-project.io/cn/) 的APP混合开发解决方案。 6 | 7 | ## 开发 WeexBox 的初衷 8 | 9 | weex给了vue开发者一条全新的道路,让前端开发者在APP中大放异彩。 10 | 然而,weex也给前端开发者一个错觉,误以为整个APP都可以用weex来做,而不需要原生的支持。 11 | 事实是,想要开发出优秀体验的APP,前端是离不开原生的,而且是重度依赖的。 12 | 所以,前端需要与原生端紧密配合,我们称之为大前端的紧紧拥抱... 13 | weex的重心放在了js渲染UI的能力上,对原生的扩展并不多。 14 | 于是我们想通过 WeexBox 15 | 16 | - 扩展 weex 的能力 17 | - 把最佳实践带入进来,提供大前端正确拥抱的姿势 18 | - 开发一些实用工具,带来更棒的开发体验 19 | - 填掉 weex 的坑 20 | 21 | 最终,开发者能够专注写bug了~~~ 22 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 27 9 | compileOptions { 10 | sourceCompatibility JavaVersion.VERSION_1_8 11 | targetCompatibility JavaVersion.VERSION_1_8 12 | } 13 | defaultConfig { 14 | applicationId "com.weexbox.example" 15 | minSdkVersion 21 16 | targetSdkVersion 27 17 | versionCode 1 18 | versionName "1.0" 19 | 20 | ndk { 21 | abiFilters "armeabi-v7a", "x86" 22 | } 23 | } 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | packagingOptions { 31 | exclude 'META-INF/atomicfu.kotlin_module' 32 | } 33 | } 34 | 35 | dependencies { 36 | implementation fileTree(dir: 'libs', include: ['*.jar']) 37 | testImplementation 'junit:junit:4.12' 38 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 39 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 40 | 41 | implementation project(':core') 42 | } 43 | 44 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/weexbox/example/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.example 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getTargetContext() 20 | assertEquals("com.weexbox.example", appContext.packageName) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/assets/weexbox-update/update-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weexbox", 3 | "ios_min_version": "0.0.0", 4 | "android_min_version": "0.0.0", 5 | "release": "2019.08.05.18.44.01" 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/assets/weexbox-update/update-md5.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "md5": "7f2f967036c4b244ed184a4accac658f", 4 | "path": "page/about.js" 5 | }, 6 | { 7 | "md5": "195cee92f28f3d42bf61bb3f81a071e9", 8 | "path": "page/globalEvent.js" 9 | }, 10 | { 11 | "md5": "0fa0b3039e62656f996ee0b7a397e6be", 12 | "path": "page/home.js" 13 | }, 14 | { 15 | "md5": "86d1c6d2cb8373c1cf8cb94203080671", 16 | "path": "page/module.js" 17 | }, 18 | { 19 | "md5": "26a5eaeba2cf7d7017736c0a9cb1c663", 20 | "path": "page/page1.js" 21 | }, 22 | { 23 | "md5": "1f6882bb3cb1a50ed0878898bc162530", 24 | "path": "page/ts.js" 25 | }, 26 | { 27 | "md5": "4ec31effe29dd538d115f80ef994e356", 28 | "path": "page/use.js" 29 | }, 30 | { 31 | "md5": "aca13aa61970ec536eac116fc915a0f2", 32 | "path": "page/wb-event.js" 33 | }, 34 | { 35 | "md5": "086fcb7895bbd0d77889b58425c5bdcc", 36 | "path": "page/wb-external.js" 37 | }, 38 | { 39 | "md5": "e3820735a55f08c7a497c82c8a225511", 40 | "path": "page/wb-location.js" 41 | }, 42 | { 43 | "md5": "1b3c86313cdd570826a055fa9bc8b054", 44 | "path": "page/wb-lottie.js" 45 | }, 46 | { 47 | "md5": "cda30a7125dc518c808778d503f34b40", 48 | "path": "page/wb-modal.js" 49 | }, 50 | { 51 | "md5": "86acbb3c12df3ecf488dd1426d982d60", 52 | "path": "page/wb-navigator.js" 53 | }, 54 | { 55 | "md5": "bfe1167e725c1cde17aa096699eddff6", 56 | "path": "page/wb-network.js" 57 | }, 58 | { 59 | "md5": "cdb78ad52475149deef48d0e6d5f401e", 60 | "path": "page/wb-router-close.js" 61 | }, 62 | { 63 | "md5": "2a65c6072b2fdd18ac8039597d3a3f5d", 64 | "path": "page/wb-router.js" 65 | }, 66 | { 67 | "md5": "1c248ebd18bc3d697515c794a0863071", 68 | "path": "page/wb-webSocket.js" 69 | }, 70 | { 71 | "md5": "a767092977a691eb09d9ec9f1b479803", 72 | "path": "page/web.js" 73 | } 74 | ] 75 | -------------------------------------------------------------------------------- /app/src/main/assets/weexbox-update/www.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/app/src/main/assets/weexbox-update/www.zip -------------------------------------------------------------------------------- /app/src/main/java/com/weexbox/example/App.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.example 2 | 3 | import android.app.Application 4 | 5 | import com.weexbox.core.WeexBoxEngine 6 | import com.weexbox.core.router.Router 7 | import com.weexbox.core.update.UpdateManager 8 | 9 | class App : Application() { 10 | 11 | override fun onCreate() { 12 | super.onCreate() 13 | 14 | // 初始化 WeexBox 15 | WeexBoxEngine.setup(this, null) 16 | 17 | // 开启调试 18 | WeexBoxEngine.isDebug = true 19 | 20 | Router.register(Router.NAME_WEEX, WeexActivity::class.java) 21 | 22 | UpdateManager.serverUrl = "https://aygtech.github.io/weexbox" 23 | UpdateManager.update { state, progress, error, url -> } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/weexbox/example/NormalActivity.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.example 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.util.Log 6 | import android.view.View 7 | import com.weexbox.core.controller.WBBaseActivity 8 | import com.weexbox.core.controller.WBWeexFragment 9 | import com.weexbox.core.extension.toJsonMap 10 | import com.weexbox.core.model.Result 11 | import com.weexbox.core.router.Router 12 | import com.weexbox.core.util.ActivityManager 13 | import com.weexbox.core.util.ToastUtil 14 | import okhttp3.* 15 | import java.io.IOException 16 | import java.util.* 17 | import kotlin.concurrent.timerTask 18 | 19 | /** 20 | * Author: Mario 21 | * Time: 2018/11/23 2:10 PM 22 | * Description: This is NormalActivity 23 | */ 24 | 25 | class NormalActivity : WBBaseActivity() { 26 | 27 | override fun onCreate(savedInstanceState: Bundle?) { 28 | super.onCreate(savedInstanceState) 29 | 30 | setContentView(R.layout.activity_normal) 31 | 32 | val weexFragment = WBWeexFragment() 33 | weexFragment.router.url = "http://dotwe.org/raw/dist/791c8507ae8f35a9e134abe8a776588d.bundle.wx" 34 | // weexFragment.router.url = "module1/page1.js" 35 | supportFragmentManager.beginTransaction().replace(R.id.weex_fragment, weexFragment).commit() 36 | 37 | getActionbar().setTitleText( { 38 | val mOkHttpClient = OkHttpClient() 39 | var formEncodingBuilder = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), "") 40 | // formEncodingBuilder.add("mode", "2") 41 | // formEncodingBuilder.add("userName", "xixi") 42 | // formEncodingBuilder.add("password", "123123") 43 | 44 | var requestBuilder = Request.Builder() 45 | .addHeader("X-Requested-With", "XMLHttpRequest"); 46 | 47 | // if (info.headers != null && info?.headers?.size!! > 0) { 48 | // for (param in info?.headers!!) { 49 | // requestBuilder.addHeader(param.key, param.value) 50 | // } 51 | // } 52 | 53 | var request: Request? = null 54 | // if (info.method?.toUpperCase() == "POST") { 55 | request = requestBuilder.url("http://10.1.1.12:8888/msg/sms/authCode?phoneNumber=18975190024") 56 | .post(formEncodingBuilder) 57 | .build() 58 | // } else{ 59 | // request = requestBuilder.url(info.url!!) 60 | // .get() 61 | // .build() 62 | // } 63 | 64 | val call = mOkHttpClient.newCall(request) 65 | call.enqueue(object : Callback { 66 | override fun onFailure(call: Call, e: IOException) { 67 | Log.i("88888", "e = "+e.message) 68 | } 69 | 70 | override fun onResponse(call: Call, response: Response) { 71 | Log.i("88888", "res = "+response.body()?.string()) 72 | } 73 | }) 74 | }, "haode") 75 | // 76 | // 77 | // getActionbar().setRightButton ({ 78 | // 79 | // router.close(2, this) 80 | // 81 | // },"haha ") 82 | // 83 | // 84 | // val size = ActivityManager.getInstance().allActivities.size 85 | // if (size == 5){ 86 | // var timer = Timer() 87 | // timer.schedule(timerTask { router.close(2, this@NormalActivity) }, 3000) 88 | // timer.schedule(object : TimerTask(){ 89 | // override fun run() { 90 | // router.close(2, this@NormalActivity) 91 | // } 92 | // 93 | // }, 3000) 94 | // } 95 | } 96 | } -------------------------------------------------------------------------------- /app/src/main/java/com/weexbox/example/WeexActivity.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.example 2 | 3 | import android.os.Bundle 4 | import com.weexbox.core.controller.WBWeexActivity 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2018/11/28 11:19 AM 9 | * Description: This is WeexActivity 10 | */ 11 | 12 | class WeexActivity : WBWeexActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | 16 | router.url = "page/home.js" 17 | 18 | super.onCreate(savedInstanceState) 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/app/src/main/res/drawable/loading.gif -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Example 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/test/java/com/weexbox/example/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.example 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /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 | } 8 | 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.5.1' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" 12 | classpath "io.realm:realm-gradle-plugin:5.11.0" 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 14 | 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | maven { url "https://jitpack.io" } 25 | } 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-kapt' 4 | apply plugin: 'kotlin-android-extensions' 5 | apply plugin: 'realm-android' 6 | apply plugin: 'com.github.dcendents.android-maven' 7 | 8 | group = 'com.github.aygtech' 9 | 10 | android { 11 | 12 | compileSdkVersion 27 13 | compileOptions { 14 | sourceCompatibility JavaVersion.VERSION_1_8 15 | targetCompatibility JavaVersion.VERSION_1_8 16 | } 17 | 18 | defaultConfig { 19 | minSdkVersion 21 20 | targetSdkVersion 27 21 | versionCode 1 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: 'libs', include: ['*.jar']) 34 | 35 | // weexSDk依赖 36 | api 'com.taobao.android:weex_sdk:0.24.0' 37 | api 'com.alibaba:fastjson:1.1.71.android' 38 | api 'com.android.support:appcompat-v7:27.1.1' 39 | api 'com.android.support:recyclerview-v7:27.1.1' 40 | api 'com.android.support:support-v4:27.1.1' 41 | api 'com.android.support:design:27.1.1' 42 | api 'com.squareup.okhttp:okhttp-ws:2.3.0'//别升级,跟weexsdk相关 43 | api 'com.taobao.android:weex_inspector:0.24.2.4' 44 | // api 'com.taobao.android:weexplugin-loader:1.3' 45 | // annotationProcessor 'com.taobao.android:weexplugin-processor:1.3' 46 | // api 'com.taobao.android:weexplugin-annotation:1.3' 47 | 48 | api 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50' 49 | api 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1' 50 | api 'com.squareup.okhttp3:okhttp:3.14.0' 51 | api 'com.luffykou:android-common-utils:1.1.3' 52 | api 'com.github.bumptech.glide:glide:4.8.0' //别升级,升级了项目要更换代码 53 | kapt 'com.github.bumptech.glide:compiler:4.8.0' //别升级,升级了项目要更换代码 54 | 55 | api 'com.orhanobut:logger:2.2.0' 56 | api 'org.zeroturnaround:zt-zip:1.13' 57 | api 'com.squareup.retrofit2:retrofit:2.5.0' 58 | api 'com.alibaba.android:bindingx-core:1.1.4' 59 | api 'com.alibaba.android:bindingx_weex_plugin:1.1.1' 60 | api 'com.journeyapps:zxing-android-embedded:3.6.0' 61 | api 'org.greenrobot:eventbus:3.1.1' 62 | api 'com.github.chrisbanes:PhotoView:2.1.4'//别升级,依赖androidx 63 | api 'com.android.support.constraint:constraint-layout:1.1.3' 64 | api 'com.github.PhilJay:MPAndroidChart:v3.1.0' 65 | api 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3' 66 | api 'com.kaopiz:kprogresshud:1.2.0' 67 | api "com.tencent.sonic:sdk:3.1.0" 68 | api 'com.airbnb.android:lottie:2.7.0'//别升级,新版依赖androidx 69 | api 'com.contrarywind:Android-PickerView:4.1.8' 70 | } 71 | 72 | // build a jar with source files 73 | task sourcesJar(type: Jar) { 74 | from android.sourceSets.main.java.srcDirs 75 | classifier = 'sources' 76 | } 77 | 78 | artifacts { 79 | archives sourcesJar 80 | } -------------------------------------------------------------------------------- /core/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | #weex开始 2 | -keep class com.taobao.weex.WXDebugTool{*;} 3 | -keep class com.taobao.weex.devtools.common.LogUtil{*;} 4 | -keepclassmembers class ** { 5 | @com.taobao.weex.ui.component.WXComponentProp public *; 6 | } 7 | -keep class com.taobao.weex.bridge.**{*;} 8 | -keep class com.taobao.weex.dom.**{*;} 9 | -keep class com.taobao.weex.adapter.**{*;} 10 | -keep class com.taobao.weex.common.**{*;} 11 | -keep class * implements com.taobao.weex.IWXObject{*;} 12 | -keep class com.taobao.weex.ui.**{*;} 13 | -keep class com.taobao.weex.ui.component.**{*;} 14 | -keep class com.taobao.weex.utils.**{ 15 | public ; 16 | public ; 17 | } 18 | -keep class com.taobao.weex.view.**{*;} 19 | -keep class com.taobao.weex.module.**{*;} 20 | -keep public class * extends com.taobao.weex.common.WXModule{*;} 21 | -keep public class * extends com.taobao.weex.ui.component.WXComponent{*;} 22 | -keep class * implements com.taobao.weex.ui.IExternalComponentGetter{*;} 23 | #weex结束 24 | 25 | #okhttp 26 | -dontwarn okhttp3.** 27 | -keep class okhttp3.**{*;} 28 | 29 | #okio 30 | -dontwarn okio.** 31 | -keep class okio.**{*;} 32 | 33 | # FastJson 34 | -dontwarn com.alibaba.fastjson.** 35 | -keep class com.alibaba.fastjson.** { *; } 36 | 37 | #weexbox开始 38 | -dontwarn com.weexbox.core.** 39 | -keep class com.weexbox.core.**{*;} 40 | -keep class * implements com.weexbox.core.**{*;} 41 | #weexbox结束 -------------------------------------------------------------------------------- /core/src/androidTest/java/com/weexbox/core/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.weexbox.core.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 26 | 27 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/WeexBoxEngine.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core 2 | 3 | import android.app.Application 4 | import com.alibaba.android.bindingx.plugin.weex.BindingX 5 | import com.orhanobut.logger.AndroidLogAdapter 6 | import com.orhanobut.logger.Logger 7 | import com.taobao.weex.InitConfig 8 | import com.taobao.weex.WXEnvironment 9 | import com.taobao.weex.WXSDKEngine 10 | import com.weexbox.core.adapter.ImageAdapter 11 | import com.weexbox.core.adapter.WebSocketAdapterFactory 12 | import com.weexbox.core.component.LottieComponent 13 | import com.weexbox.core.controller.WBWebViewActivity 14 | import com.weexbox.core.controller.WBWeexActivity 15 | import com.weexbox.core.module.* 16 | import com.weexbox.core.router.Router 17 | import com.weexbox.core.util.BitmapUtil 18 | import io.realm.Realm 19 | 20 | 21 | /** 22 | * Author: Mario 23 | * Time: 2018/8/15 下午3:37 24 | * Description: This is WeexBoxEngine 25 | */ 26 | 27 | object WeexBoxEngine { 28 | 29 | lateinit var application: Application 30 | var loadingIconRes = "" 31 | 32 | var isDebug = false 33 | set(value) { 34 | field = value 35 | if (value) { 36 | WXEnvironment.setOpenDebugLog(true) 37 | WXEnvironment.setApkDebugable(true) 38 | } else { 39 | WXEnvironment.setOpenDebugLog(false) 40 | WXEnvironment.setApkDebugable(false) 41 | } 42 | } 43 | 44 | fun setup(application: Application, weexConfig: InitConfig? = null) { 45 | this.application = application 46 | 47 | //初始化图片框架 48 | BitmapUtil.setContext(application) 49 | 50 | Realm.init(application) 51 | Logger.addLogAdapter(AndroidLogAdapter()) 52 | initWeex(weexConfig) 53 | } 54 | 55 | private fun initWeex(config: InitConfig?) { 56 | WXSDKEngine.initialize(application, config 57 | ?: InitConfig.Builder().setImgAdapter(ImageAdapter()).setWebSocketAdapterFactory(WebSocketAdapterFactory()).build()) 58 | BindingX.register() 59 | registerModule() 60 | registerRouter() 61 | registerComponent() 62 | } 63 | 64 | private fun registerModule() { 65 | WXSDKEngine.registerModule("wb-router", RouterModule::class.java) 66 | WXSDKEngine.registerModule("wb-storage", StorageModule::class.java) 67 | WXSDKEngine.registerModule("wb-navigator", NavigatorModule::class.java) 68 | WXSDKEngine.registerModule("wb-network", NetworkModule::class.java) 69 | WXSDKEngine.registerModule("wb-modal", ModalModule::class.java) 70 | WXSDKEngine.registerModule("wb-external", ExternalModule::class.java) 71 | WXSDKEngine.registerModule("wb-event", EventModule::class.java) 72 | WXSDKEngine.registerModule("navigator", WXNavigatorModule::class.java) 73 | } 74 | 75 | private fun registerRouter() { 76 | Router.register(Router.NAME_WEEX, WBWeexActivity::class.java) 77 | Router.register(Router.NAME_WEB, WBWebViewActivity::class.java) 78 | } 79 | 80 | private fun registerComponent() { 81 | WXSDKEngine.registerComponent("wb-lottie", LottieComponent::class.java) 82 | } 83 | 84 | open fun disposeLoadingIcon(res: String) { 85 | loadingIconRes = res 86 | } 87 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/activity/PhotoActivity.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.view.ViewPager; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | import android.widget.LinearLayout; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import com.weexbox.core.R; 13 | import com.weexbox.core.adapter.PageAdapter; 14 | import com.weexbox.core.adapter.PhotoViewPager; 15 | import com.weexbox.core.controller.WBBaseActivity; 16 | import com.weexbox.core.util.ImageUtil; 17 | 18 | import java.io.File; 19 | import java.util.ArrayList; 20 | 21 | /** 22 | * Author:leon.wen 23 | * Time:2018/8/2 18:45 24 | * Description:This is PhotoActivity 25 | */ 26 | public class PhotoActivity extends WBBaseActivity { 27 | TextView page; 28 | RelativeLayout top; 29 | PhotoViewPager viewPager; 30 | TextView save; 31 | ImageView back; 32 | ArrayList imagesUrl; 33 | int current; 34 | PageAdapter pagerAdapter; 35 | public static OnItemClickListener onItemClickListener; 36 | public static View rightView; 37 | 38 | 39 | public void initData() { 40 | if (getIntent() != null) { 41 | Intent intent = getIntent(); 42 | imagesUrl = intent.getStringArrayListExtra("images"); 43 | current = intent.getIntExtra("position", 0); 44 | } 45 | pagerAdapter = new PageAdapter(imagesUrl, this); 46 | viewPager.setAdapter(pagerAdapter); 47 | viewPager.setCurrentItem(current); 48 | page.setText(current + 1 + "/" + imagesUrl.size()); 49 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 50 | @Override 51 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 52 | 53 | } 54 | 55 | @Override 56 | public void onPageSelected(int position) { 57 | current = position; 58 | page.setText(current + 1 + "/" + imagesUrl.size()); 59 | } 60 | 61 | @Override 62 | public void onPageScrollStateChanged(int state) { 63 | 64 | } 65 | }); 66 | 67 | 68 | } 69 | 70 | /** 71 | * 保存图片 72 | */ 73 | private void saveImage() { 74 | final String url = imagesUrl.get(current); 75 | getLoadDialogHelper().showLoad(PhotoActivity.this, true); 76 | ImageUtil.insertImageToSystemGallery(this, url, new ImageUtil.OnSaveImageListener() { 77 | @Override 78 | public void onSuccess(File file, int requestId) { 79 | getLoadDialogHelper().clear(); 80 | } 81 | 82 | @Override 83 | public void onFail(int requestId, int errorMyCode, int errorBackCode, String errorMessage, String data) { 84 | getLoadDialogHelper().clear(); 85 | } 86 | }); 87 | } 88 | 89 | @Override 90 | protected void onCreate(Bundle savedInstanceState) { 91 | super.onCreate(savedInstanceState); 92 | getRouter().setNavBarHidden(true); 93 | setContentView(R.layout.activity_photoview); 94 | page = findViewById(R.id.page); 95 | top = findViewById(R.id.top); 96 | viewPager = findViewById(R.id.viewPager); 97 | back = findViewById(R.id.back); 98 | save = findViewById(R.id.save); 99 | LinearLayout right_view = findViewById(R.id.right_view); 100 | if(rightView!=null){ 101 | save.setVisibility(View.GONE); 102 | right_view.addView(rightView); 103 | rightView.setOnClickListener(v -> { 104 | if (onItemClickListener != null) { 105 | onItemClickListener.rightBtnClick(v); 106 | } else { 107 | saveImage(); 108 | } 109 | }); 110 | } 111 | save.setOnClickListener(v -> { 112 | if (onItemClickListener != null) { 113 | onItemClickListener.rightBtnClick(v); 114 | } else { 115 | saveImage(); 116 | } 117 | }); 118 | back.setOnClickListener(v -> { 119 | if (onItemClickListener != null) { 120 | onItemClickListener.leftBtnClick(v); 121 | } 122 | finish(); 123 | overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 124 | }); 125 | initData(); 126 | } 127 | 128 | public interface OnItemClickListener { 129 | void leftBtnClick(View v); 130 | 131 | void rightBtnClick(View v); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/adapter/MyAppGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.adapter; 2 | 3 | import com.bumptech.glide.annotation.GlideModule; 4 | import com.bumptech.glide.module.AppGlideModule; 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2018/8/15 下午4:10 9 | * Description: This is MyAppGlideModule 10 | */ 11 | 12 | @GlideModule 13 | public final class MyAppGlideModule extends AppGlideModule { 14 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/adapter/PageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.adapter; 2 | 3 | import android.app.Activity; 4 | import android.support.v4.view.PagerAdapter; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.github.chrisbanes.photoview.OnPhotoTapListener; 11 | import com.github.chrisbanes.photoview.PhotoView; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Author:leon.wen 17 | * Time:2018/8/2 18:42 18 | * Description:This is PageAdapter 19 | */ 20 | public class PageAdapter extends PagerAdapter { 21 | List imagesUrl; 22 | Activity context; 23 | 24 | public PageAdapter(List imagesUrl, Activity context) { 25 | this.imagesUrl = imagesUrl; 26 | this.context = context; 27 | } 28 | 29 | @Override 30 | public int getCount() { 31 | return (imagesUrl == null || imagesUrl.size() == 0) ? 0 : imagesUrl.size(); 32 | } 33 | 34 | @Override 35 | public Object instantiateItem(ViewGroup container, int position) { 36 | String url = imagesUrl.get(position); 37 | 38 | PhotoView photoView = new PhotoView(context); 39 | photoView.setMaximumScale(8); 40 | photoView.setMinimumScale(0.5f); 41 | Glide.with(context) 42 | .load(url) 43 | .into(photoView); 44 | container.addView(photoView); 45 | // photoView.setOnPhotoTapListener(new OnPhotoTapListener() { 46 | // @Override 47 | // public void onPhotoTap(ImageView view, float v, float v1) { 48 | // context.finish(); 49 | // context.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 50 | // } 51 | // }); 52 | return photoView; 53 | } 54 | 55 | @Override 56 | public void destroyItem(ViewGroup container, int position, Object object) { 57 | container.removeView((View) object); 58 | } 59 | 60 | @Override 61 | public boolean isViewFromObject(View view, Object object) { 62 | return view == object; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/adapter/PhotoViewPager.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.ViewPager; 5 | import android.util.AttributeSet; 6 | import android.view.MotionEvent; 7 | 8 | /** 9 | * Author:leon.wen 10 | * Time:2018/8/2 18:40 11 | * Description:This is PhotoViewPager 12 | */ 13 | public class PhotoViewPager extends ViewPager { 14 | public PhotoViewPager(Context context) { 15 | super(context); 16 | } 17 | 18 | public PhotoViewPager(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | } 21 | 22 | @Override 23 | public boolean onInterceptTouchEvent(MotionEvent ev) { 24 | try { 25 | return super.onInterceptTouchEvent(ev); 26 | } catch (IllegalArgumentException e) { 27 | e.printStackTrace(); 28 | return false; 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/adapter/WebSocketAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.adapter 2 | 3 | import com.orhanobut.logger.Logger 4 | import com.squareup.okhttp.OkHttpClient 5 | import com.squareup.okhttp.Request 6 | import com.squareup.okhttp.Response 7 | import com.squareup.okhttp.ws.WebSocket 8 | import com.squareup.okhttp.ws.WebSocketCall 9 | import com.squareup.okhttp.ws.WebSocketListener 10 | import com.taobao.weex.appfram.websocket.IWebSocketAdapter 11 | import com.taobao.weex.appfram.websocket.WebSocketCloseCodes 12 | import okio.Buffer 13 | import okio.BufferedSource 14 | import java.io.EOFException 15 | import java.io.IOException 16 | import java.util.HashMap 17 | 18 | /** 19 | * Author: Mario 20 | * Time: 2019/2/25 4:03 PM 21 | * Description: This is WebSocketAdapter 22 | */ 23 | 24 | class WebSocketAdapter: IWebSocketAdapter { 25 | 26 | private var ws: WebSocket? = null 27 | private var eventListener: IWebSocketAdapter.EventListener? = null 28 | 29 | override fun connect(url: String?, protocol: String?, listener: IWebSocketAdapter.EventListener?) { 30 | this.eventListener = listener 31 | val okHttpClient = OkHttpClient() 32 | val builder = Request.Builder() 33 | if (protocol != null) { 34 | builder.addHeader(IWebSocketAdapter.HEADER_SEC_WEBSOCKET_PROTOCOL, protocol) 35 | } 36 | builder.url(url) 37 | val wsRequest = builder.build() 38 | val webSocketCall = WebSocketCall.create(okHttpClient, wsRequest) 39 | try { 40 | val field = WebSocketCall::class.java.getDeclaredField("request") 41 | field.isAccessible = true 42 | val realRequest = field.get(webSocketCall) as Request 43 | val wsHeaders = realRequest.headers() 44 | val headers = HashMap() 45 | for (name in wsHeaders.names()) { 46 | headers[name] = wsHeaders.values(name).toString() 47 | } 48 | } catch (e: Exception) { 49 | e.printStackTrace() 50 | } 51 | 52 | webSocketCall.enqueue(object : WebSocketListener { 53 | @Throws(IOException::class) 54 | override fun onOpen(webSocket: WebSocket, request: Request, response: Response) { 55 | ws = webSocket 56 | eventListener?.onOpen() 57 | val wsHeaders = response.headers() 58 | val headers = HashMap() 59 | for (name in wsHeaders.names()) { 60 | headers[name] = wsHeaders.values(name).toString() 61 | } 62 | } 63 | 64 | @Throws(IOException::class) 65 | override fun onMessage(payload: BufferedSource, type: WebSocket.PayloadType) { 66 | if (type != WebSocket.PayloadType.BINARY) { 67 | val message = payload.readUtf8() 68 | eventListener?.onMessage(message) 69 | } 70 | payload.close() 71 | } 72 | 73 | override fun onPong(payload: Buffer) { 74 | 75 | } 76 | 77 | override fun onClose(code: Int, reason: String) { 78 | eventListener?.onClose(code, reason, true) 79 | } 80 | 81 | override fun onFailure(e: IOException) { 82 | e.printStackTrace() 83 | if (e is EOFException) { 84 | eventListener?.onClose(WebSocketCloseCodes.CLOSE_NORMAL.code, WebSocketCloseCodes.CLOSE_NORMAL.name, true) 85 | } else { 86 | eventListener?.onError(e.message) 87 | } 88 | } 89 | }) 90 | } 91 | 92 | override fun send(data: String?) { 93 | if (ws != null) { 94 | try { 95 | val buffer = Buffer().writeUtf8(data ?: "") 96 | ws!!.sendMessage(WebSocket.PayloadType.TEXT, buffer.buffer()) 97 | buffer.flush() 98 | buffer.close() 99 | } catch (e: Exception) { 100 | e.printStackTrace() 101 | } 102 | } else { 103 | Logger.e("WebSocket is not ready") 104 | } 105 | } 106 | 107 | override fun close(code: Int, reason: String?) { 108 | if (ws != null) { 109 | try { 110 | ws!!.close(code, reason) 111 | } catch (e: Exception) { 112 | e.printStackTrace() 113 | Logger.e(e.message ?: "") 114 | } 115 | 116 | } 117 | } 118 | 119 | override fun destroy() { 120 | if (ws != null) { 121 | try { 122 | ws!!.close(WebSocketCloseCodes.CLOSE_GOING_AWAY.code, WebSocketCloseCodes.CLOSE_GOING_AWAY.name) 123 | } catch (e: Exception) { 124 | e.printStackTrace() 125 | } 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/adapter/WebSocketAdapterFactory.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.adapter 2 | 3 | import com.taobao.weex.appfram.websocket.IWebSocketAdapter 4 | import com.taobao.weex.appfram.websocket.IWebSocketAdapterFactory 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2019/2/25 4:01 PM 9 | * Description: This is WebSocketAdapterFactory 10 | */ 11 | 12 | class WebSocketAdapterFactory: IWebSocketAdapterFactory { 13 | 14 | override fun createWebSocketAdapter(): IWebSocketAdapter { 15 | return WebSocketAdapter() 16 | } 17 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/component/BaseComponent.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.component 2 | 3 | import android.view.View 4 | import com.taobao.weex.WXSDKInstance 5 | import com.taobao.weex.ui.action.BasicComponentData 6 | import com.taobao.weex.ui.component.WXComponent 7 | import com.taobao.weex.ui.component.WXVContainer 8 | 9 | /** 10 | * Author: Mario 11 | * Time: 2019/1/16 5:58 PM 12 | * Description: This is BaseComponent 13 | */ 14 | 15 | open class BaseComponent(instance: WXSDKInstance?, parent: WXVContainer<*>?, basicComponentData: BasicComponentData<*>?) : WXComponent(instance, parent, basicComponentData) { 16 | 17 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/component/LottieComponent.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.component 2 | 3 | import android.animation.Animator 4 | import android.content.Context 5 | import android.widget.ImageView 6 | import com.airbnb.lottie.LottieAnimationView 7 | import com.airbnb.lottie.LottieDrawable 8 | import com.taobao.weex.WXSDKInstance 9 | import com.taobao.weex.annotation.JSMethod 10 | import com.taobao.weex.bridge.JSCallback 11 | import com.taobao.weex.ui.action.BasicComponentData 12 | import com.taobao.weex.ui.component.WXVContainer 13 | import com.taobao.weex.utils.WXUtils 14 | import com.weexbox.core.model.Result 15 | 16 | /** 17 | * Author: Mario 18 | * Time: 2019/1/16 6:13 PM 19 | * Description: This is LottieComponent 20 | */ 21 | 22 | class LottieComponent(instance: WXSDKInstance?, parent: WXVContainer<*>?, basicComponentData: BasicComponentData<*>?) : BaseComponent(instance, parent, basicComponentData) { 23 | 24 | var callback: JSCallback? = null 25 | 26 | override fun initComponentHostView(context: Context): LottieAnimationView { 27 | return LottieAnimationView(context) 28 | } 29 | 30 | override fun onHostViewInitialized(host: LottieAnimationView?) { 31 | super.onHostViewInitialized(host) 32 | 33 | hostView.addAnimatorListener(object : Animator.AnimatorListener { 34 | override fun onAnimationStart(animation: Animator?) { 35 | 36 | } 37 | 38 | override fun onAnimationEnd(animation: Animator?) { 39 | complete(true) 40 | } 41 | 42 | override fun onAnimationCancel(animation: Animator?) { 43 | complete(false) 44 | } 45 | 46 | override fun onAnimationRepeat(animation: Animator?) { 47 | 48 | } 49 | }) 50 | loadSource(attrs) 51 | applyProperties(attrs) 52 | } 53 | 54 | override fun updateAttrs(attrs: MutableMap?) { 55 | super.updateAttrs(attrs) 56 | 57 | if (loadSource(attrs!!)) { 58 | applyProperties(this.attrs) 59 | } else { 60 | applyProperties(attrs) 61 | } 62 | } 63 | 64 | fun loadSource(attributes: MutableMap): Boolean { 65 | val sourceJson = attributes["sourceJson"] 66 | val sourceUrl = attributes["sourceUrl"] 67 | if (sourceJson != null) { 68 | hostView.setAnimationFromJson(WXUtils.getString(sourceJson, null), null) 69 | return true 70 | } else if (sourceUrl != null) { 71 | hostView.setAnimationFromUrl(WXUtils.getString(sourceUrl, null)) 72 | return true 73 | } 74 | return false 75 | } 76 | 77 | fun applyProperties(attributes: MutableMap) { 78 | val speed = attributes["speed"] 79 | if (speed != null) { 80 | hostView.speed = WXUtils.getFloat(speed) 81 | } 82 | val loop = attributes["loop"] 83 | if (WXUtils.getBoolean(loop, false)) { 84 | hostView.repeatCount = LottieDrawable.INFINITE 85 | } 86 | var scaleType: ImageView.ScaleType? = null 87 | when (WXUtils.getString(attributes["resizeMode"], null)) { 88 | "cover" -> scaleType = ImageView.ScaleType.CENTER_CROP 89 | "contain" -> scaleType = ImageView.ScaleType.CENTER_INSIDE 90 | "center" -> scaleType = ImageView.ScaleType.CENTER 91 | } 92 | if (scaleType != null) { 93 | hostView.scaleType = scaleType 94 | } 95 | } 96 | 97 | fun complete(complete: Boolean) { 98 | val result = Result() 99 | result.data["complete"] = complete 100 | callback?.invoke(result) 101 | } 102 | 103 | @JSMethod(uiThread = true) 104 | fun isAnimationPlaying(): Boolean { 105 | return hostView.isAnimating 106 | } 107 | 108 | @JSMethod(uiThread = true) 109 | fun playFromProgress(fromProgress: Any, toProgress: Any, callback: JSCallback?) { 110 | stop() 111 | hostView.setMinAndMaxProgress(WXUtils.getFloat(fromProgress), WXUtils.getFloat(toProgress)) 112 | hostView.playAnimation() 113 | this.callback = callback 114 | } 115 | 116 | @JSMethod(uiThread = true) 117 | fun playFromFrame(fromFrame: Any, toFrame: Any, callback: JSCallback?) { 118 | stop() 119 | hostView.setMinFrame(WXUtils.getInt(fromFrame)) 120 | hostView.setMaxFrame(WXUtils.getInt(toFrame)) 121 | hostView.playAnimation() 122 | this.callback = callback 123 | } 124 | 125 | @JSMethod(uiThread = true) 126 | fun play(callback: JSCallback?) { 127 | hostView.resumeAnimation() 128 | this.callback = callback 129 | } 130 | 131 | @JSMethod(uiThread = true) 132 | fun pause() { 133 | hostView.pauseAnimation() 134 | } 135 | 136 | @JSMethod(uiThread = true) 137 | fun stop() { 138 | hostView.cancelAnimation() 139 | hostView.progress = 0F 140 | } 141 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/controller/WBBaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.controller 2 | 3 | import android.os.Bundle 4 | import android.support.v4.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import com.weexbox.core.event.Event 9 | import com.weexbox.core.event.EventCallback 10 | import com.weexbox.core.router.Router 11 | import com.weexbox.core.util.LoadDialogHelper 12 | import org.greenrobot.eventbus.EventBus 13 | import org.greenrobot.eventbus.Subscribe 14 | import org.greenrobot.eventbus.ThreadMode 15 | import java.util.* 16 | 17 | /* 18 | * Fragment基类 19 | */ 20 | abstract class WBBaseFragment : Fragment() { 21 | 22 | // 路由 23 | var router = Router() 24 | // 通用事件 25 | var events: MutableMap = TreeMap() 26 | // 返回键操作 27 | var isListenBack = false 28 | val backName = "WB-onBackPressed" 29 | //hud 30 | var loadDialogHelper: LoadDialogHelper = LoadDialogHelper(context) 31 | 32 | // 可见性相关 33 | var isVisibleToUser = false 34 | private var isOnCreateView = false 35 | private var isSetUserVisibleHint = false 36 | private var isHiddenChanged = false 37 | private var isFirstResume = false 38 | 39 | lateinit var rootView: View 40 | 41 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 42 | isOnCreateView = true 43 | rootView = inflater.inflate(getLayoutId(), container, false) 44 | return rootView 45 | } 46 | 47 | abstract fun getLayoutId(): Int 48 | 49 | override fun onCreate(savedInstanceState: Bundle?) { 50 | super.onCreate(savedInstanceState) 51 | 52 | EventBus.getDefault().register(this) 53 | } 54 | 55 | override fun onDestroy() { 56 | super.onDestroy() 57 | 58 | loadDialogHelper.clear() 59 | EventBus.getDefault().unregister(this) 60 | } 61 | 62 | // 通用事件 63 | @Subscribe(threadMode = ThreadMode.MAIN) 64 | fun onEvent(event: Event) { 65 | val callback = events[event.name] 66 | if (event.name == backName) { 67 | if (isVisibleToUser) { 68 | callback?.invoke(event.info) 69 | } 70 | } else { 71 | callback?.invoke(event.info) 72 | } 73 | } 74 | 75 | open fun onBackPressed() { 76 | 77 | } 78 | 79 | override fun onResume() { 80 | super.onResume() 81 | 82 | if (!isHiddenChanged && !isSetUserVisibleHint) { 83 | changeVisibleToUser(true) 84 | } else if ((isHiddenChanged || isSetUserVisibleHint) && !isHidden) { 85 | changeVisibleToUser(true) 86 | } 87 | if (isSetUserVisibleHint || (!isFirstResume && !isHiddenChanged)) { 88 | isVisibleToUser = true 89 | } 90 | isFirstResume = true 91 | } 92 | 93 | override fun onPause() { 94 | super.onPause() 95 | 96 | changeVisibleToUser(false) 97 | } 98 | 99 | override fun setUserVisibleHint(isVisibleToUser: Boolean) { 100 | super.setUserVisibleHint(isVisibleToUser) 101 | 102 | isSetUserVisibleHint = true 103 | changeVisibleToUser(isVisibleToUser) 104 | } 105 | 106 | override fun onHiddenChanged(hidden: Boolean) { 107 | super.onHiddenChanged(hidden) 108 | 109 | isHiddenChanged = true 110 | changeVisibleToUser(!hidden) 111 | } 112 | 113 | private fun changeVisibleToUser(isVisibleToUser: Boolean) { 114 | if (!isOnCreateView) { 115 | return 116 | } 117 | if (isVisibleToUser == this.isVisibleToUser) { 118 | return 119 | } 120 | this.isVisibleToUser = isVisibleToUser 121 | onVisibleToUserChanged(this.isVisibleToUser) 122 | } 123 | 124 | open fun onVisibleToUserChanged(isVisibleToUser: Boolean) { 125 | } 126 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/controller/WBWebViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.controller 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.WindowManager 6 | import android.webkit.WebResourceRequest 7 | import android.webkit.WebResourceResponse 8 | import android.webkit.WebView 9 | import android.webkit.WebViewClient 10 | import com.orhanobut.logger.Logger 11 | 12 | import com.tencent.sonic.sdk.SonicConfig 13 | import com.tencent.sonic.sdk.SonicEngine 14 | import com.tencent.sonic.sdk.SonicSession 15 | import com.tencent.sonic.sdk.SonicSessionConfig 16 | import com.weexbox.core.R 17 | import com.weexbox.core.interfaces.WebViewSetInterface 18 | import com.weexbox.core.webview.SonicJavaScriptInterface 19 | import com.weexbox.core.webview.SonicRuntimeImpl 20 | import com.weexbox.core.webview.SonicSessionClientImpl 21 | import kotlinx.android.synthetic.main.activity_web_view.* 22 | 23 | /** 24 | * Author:leon.wen 25 | * Time:2018/10/20 19:00 26 | * Description:This is WBWebViewActivity 27 | */ 28 | open class WBWebViewActivity : WBBaseActivity() { 29 | 30 | private var sonicSession: SonicSession? = null 31 | 32 | 33 | companion object { 34 | var webViewSetInterface: WebViewSetInterface? = null //自定义webview设置接口 35 | } 36 | 37 | 38 | override fun onCreate(savedInstanceState: Bundle?) { 39 | super.onCreate(savedInstanceState) 40 | 41 | if (router.url == null) { 42 | Logger.e("url不能为空") 43 | return 44 | } 45 | 46 | window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) 47 | 48 | // step 1: Initialize sonic engine if necessary, or maybe u can do this when application created 49 | if (!SonicEngine.isGetInstanceAllowed()) { 50 | SonicEngine.createInstance(SonicRuntimeImpl(application), SonicConfig.Builder().build()) 51 | } 52 | 53 | var sonicSessionClient: SonicSessionClientImpl? = null 54 | 55 | // step 2: Create SonicSession 56 | sonicSession = SonicEngine.getInstance().createSession(router.url!!, SonicSessionConfig.Builder().build()) 57 | if (null != sonicSession) { 58 | sonicSessionClient = SonicSessionClientImpl() 59 | sonicSession!!.bindClient(sonicSessionClient) 60 | } 61 | 62 | // step 3: BindWebView for sessionClient and bindClient for SonicSession 63 | // in the real world, the init flow may cost a long time as startup 64 | // runtime、init configs.... 65 | setContentView(R.layout.activity_web_view) 66 | webView.webViewClient = object : WebViewClient() { 67 | override fun onPageFinished(view: WebView, url: String) { 68 | super.onPageFinished(view, url) 69 | 70 | if (router.title == null && !view.title.isNullOrEmpty()) { 71 | getActionbar().setTitleText(view.title) 72 | } 73 | 74 | if (sonicSession != null) { 75 | sonicSession!!.sessionClient.pageFinish(url) 76 | } 77 | } 78 | 79 | override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? { 80 | return sonicSessionClient?.requestResource(request.url.toString()) as WebResourceResponse? 81 | } 82 | } 83 | 84 | val webSettings = webView.settings 85 | 86 | // step 4: bind javascript 87 | // note:if api level lower than 17(android 4.2), addJavascriptInterface has security 88 | // issue, please use x5 or see https://developer.android.com/reference/android/webkit/ 89 | // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String) 90 | webSettings.javaScriptEnabled = true 91 | webView.removeJavascriptInterface("searchBoxJavaBridge_") 92 | webView.addJavascriptInterface(SonicJavaScriptInterface(sonicSessionClient, Intent()), "sonic") 93 | // init webview settings 94 | webSettings.allowContentAccess = true 95 | webSettings.databaseEnabled = true 96 | webSettings.domStorageEnabled = true 97 | webSettings.setAppCacheEnabled(true) 98 | webSettings.savePassword = false 99 | webSettings.saveFormData = false 100 | webSettings.useWideViewPort = true 101 | webSettings.loadWithOverviewMode = true 102 | 103 | if (webViewSetInterface != null){ 104 | webViewSetInterface!!.setWebViwe(webView) 105 | } 106 | // step 5: webview is ready now, just tell session client to bind 107 | if (sonicSessionClient != null) { 108 | sonicSessionClient.bindWebView(webView) 109 | sonicSessionClient.clientReady() 110 | } else { // default mode 111 | webView.loadUrl(router.url) 112 | } 113 | } 114 | 115 | override fun onBackPressed() { 116 | if (webView.canGoBack()) { 117 | webView.goBack() 118 | } else { 119 | super.onBackPressed() 120 | } 121 | } 122 | 123 | override fun onDestroy() { 124 | sonicSession?.destroy() 125 | sonicSession = null 126 | 127 | super.onDestroy() 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/controller/WBWeexActivity.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.controller 2 | 3 | import android.os.Bundle 4 | import com.weexbox.core.R 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2018/8/14 下午6:39 9 | * Description: This is WBWeexActivity 10 | */ 11 | 12 | open class WBWeexActivity : WBBaseActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | 17 | setContentView(R.layout.activity_weex) 18 | val weexFragment = WBWeexFragment() 19 | weexFragment.router = router 20 | supportFragmentManager.beginTransaction().replace(R.id.weex_fragment, weexFragment).commit() 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/event/Event.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.event 2 | 3 | import com.weexbox.core.controller.WBBaseActivity 4 | import com.weexbox.core.controller.WBBaseFragment 5 | import org.greenrobot.eventbus.EventBus 6 | 7 | /** 8 | * Author: Mario 9 | * Time: 2018/9/12 下午6:31 10 | * Description: This is Event 11 | */ 12 | 13 | typealias EventCallback = (Map?) -> Unit 14 | 15 | class Event { 16 | 17 | lateinit var name: String 18 | var info: Map? = null 19 | 20 | companion object { 21 | // 注册事件 22 | fun register(target: WBBaseFragment, name: String, callback: EventCallback) { 23 | target.events[name] = callback 24 | } 25 | 26 | // 注销事件 27 | fun unregister(target: WBBaseFragment, name: String) { 28 | target.events.remove(name) 29 | } 30 | 31 | // 注销所有事件 32 | fun unregisterAll(target: WBBaseFragment) { 33 | target.events.clear() 34 | } 35 | 36 | // 发送事件 37 | fun emit(name: String, info: Map?) { 38 | val event = Event() 39 | event.name = name 40 | event.info = info 41 | EventBus.getDefault().post(event) 42 | } 43 | 44 | // 注册事件 45 | fun register(target: WBBaseActivity, name: String, callback: EventCallback) { 46 | target.events[name] = callback 47 | } 48 | 49 | // 注销事件 50 | fun unregister(target: WBBaseActivity, name: String) { 51 | target.events.remove(name) 52 | } 53 | 54 | // 注销所有事件 55 | fun unregisterAll(target: WBBaseActivity) { 56 | target.events.clear() 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/extension/Map+WeexBox.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.extension 2 | 3 | import com.alibaba.fastjson.JSON 4 | import java.util.* 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2018/9/11 下午6:16 9 | * Description: This is `Map+WeexBox` 10 | */ 11 | 12 | fun Map.toQuery(): String { 13 | val components: MutableList> = java.util.ArrayList() 14 | for (key in this.keys.sorted()) { 15 | val value = this[key]!! 16 | components.addAll(kotlin.Pair(key, value).queryComponents()) 17 | } 18 | 19 | return components.map { "${it.first}=${it.second}" }.joinToString("&") 20 | } 21 | 22 | fun Pair.queryComponents(): List> { 23 | val key = first 24 | val value = second 25 | 26 | val components: MutableList> = ArrayList() 27 | 28 | val dictionary = value as? Map 29 | val array = value as? List 30 | val bool = value as? Boolean 31 | if (dictionary != null) { 32 | for ((nestedKey, value) in dictionary) { 33 | components.addAll(Pair("$key[$nestedKey]", value).queryComponents()) 34 | } 35 | } else if (array != null) { 36 | for (value in array) { 37 | components.addAll(Pair("$key[]", value).queryComponents()) 38 | } 39 | } else if (bool != null) { 40 | components.add(Pair(key.encodeURIComponent(), (if (bool) "1" else "0").encodeURIComponent())) 41 | } else { 42 | components.add(Pair(key.encodeURIComponent(), value.toString().encodeURIComponent())) 43 | } 44 | 45 | return components 46 | } 47 | 48 | fun Any.toJsonString(): String { 49 | return JSON.toJSONString(this) 50 | } 51 | 52 | fun Any.toJsonMap(): MutableMap { 53 | if (this is String) { 54 | return JSON.parseObject(this).toMutableMap() 55 | } else { 56 | return JSON.parseObject(toJsonString()).toMutableMap() 57 | } 58 | } 59 | 60 | fun Map.toObject(clazz: Class): T { 61 | return JSON.parseObject(toJsonString(), clazz) 62 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/extension/String+WeexBox.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.extension 2 | 3 | import android.net.Uri 4 | import com.alibaba.fastjson.JSON 5 | import com.alibaba.fastjson.TypeReference 6 | import java.io.File 7 | import java.net.URLDecoder 8 | import java.net.URLEncoder 9 | import java.util.* 10 | 11 | 12 | /** 13 | * Author: Mario 14 | * Time: 2018/9/11 下午6:18 15 | * Description: This is `String+WeexBox` 16 | */ 17 | 18 | fun String.encodeURIComponent(): String { 19 | return URLEncoder.encode(this, "UTF-8") 20 | } 21 | 22 | fun String.decodeURIComponent(): String { 23 | return URLDecoder.decode(this, "UTF-8") 24 | } 25 | 26 | fun String.getParameters(): Map { 27 | val query = getQuery() 28 | return query.queryToParameters() 29 | } 30 | 31 | fun String?.queryToParameters(): Map { 32 | val results = TreeMap() 33 | if (this == null) { 34 | return results 35 | } 36 | val parametersCombined = TreeMap>() 37 | val pairs = split("&") 38 | for (pair in pairs) { 39 | val keyValue = pair.split("=") 40 | val key = keyValue[0].decodeURIComponent() 41 | val value = keyValue[1].decodeURIComponent() 42 | if (parametersCombined[key] != null) { 43 | parametersCombined[key]!!.add(value) 44 | } else { 45 | val values = ArrayList() 46 | values.add(value) 47 | parametersCombined.put(key, values) 48 | } 49 | } 50 | for (key in parametersCombined.keys) { 51 | val values = parametersCombined[key] 52 | values!!.sort() 53 | var value = values[0] 54 | for (i in 1 until values.size) { 55 | value = value + key + values[i] 56 | } 57 | results[key] = value 58 | } 59 | return results 60 | } 61 | 62 | 63 | fun String?.getQuery(): String? { 64 | if (this == null) { 65 | return null 66 | } 67 | val index = indexOf("?") 68 | if (index > -1) { 69 | return substring(index + 1) 70 | } 71 | return null 72 | } 73 | 74 | ///* 获取parameters里面的params */ 75 | //fun String.getParamsJsonObject(): JSONObject { 76 | // return JSON.parseObject(getParamsJsonString()) 77 | //} 78 | // 79 | //fun String?.getParamsJsonString(): String? { 80 | // if (this == null) { 81 | // return null 82 | // } 83 | // val queryParameters = getParameters() 84 | // return queryParameters["params"] 85 | //} 86 | 87 | fun String.getPath(): String { 88 | val uri = Uri.parse(this) 89 | return uri.path 90 | } 91 | 92 | fun String.getScheme(): String { 93 | val uri = Uri.parse(this) 94 | return uri.scheme 95 | } 96 | 97 | fun String.getHost(): String { 98 | val uri = Uri.parse(this) 99 | return uri.host 100 | } 101 | 102 | fun String.toObject(clazz: Class): T { 103 | return JSON.parseObject(this, clazz) 104 | } 105 | 106 | fun String.toObject(type: TypeReference): T { 107 | return JSON.parseObject(this, type) 108 | } 109 | 110 | fun String.appendingPathComponent(pathComponent: String): String { 111 | if (substring(lastIndex) == File.separator) { 112 | return this + pathComponent 113 | } 114 | return this + File.separator + pathComponent 115 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/interfaces/IFrameHttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.interfaces; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import com.weexbox.core.net.HttpParams; 7 | import com.weexbox.core.net.callback.HttpCallback; 8 | 9 | import java.util.Map; 10 | 11 | public interface IFrameHttpRequest { 12 | 13 | void sendGetRequest(final String url, final Map header, final HttpParams params, final Object tag, final boolean 14 | showLoadingView, final HttpCallback callback); 15 | 16 | void sendGetRequest(final String url, final Map header, final HttpParams params, final boolean showLoadingView, final HttpCallback callback); 17 | 18 | void sendGetRequestWithLoadingDialog(final String url, final Map header, final HttpParams params, final String loadingText, final boolean 19 | canCancel, final HttpCallback callback); 20 | 21 | void sendPostRequest(final String url, final Map header, final HttpParams params, final Object tag, final boolean 22 | showLoadingView, final HttpCallback callback); 23 | 24 | void sendPostRequest(final String url, final Map header, final HttpParams params, final boolean showLoadingView, final HttpCallback callback); 25 | 26 | void sendPostRequestWithLoadingDialog(final String url, final Map header, final HttpParams params, final String 27 | loadingText, final boolean canCancel, final HttpCallback callback); 28 | 29 | void sendPostJsonRequest(final String url, final Map header, final HttpParams params, final Object tag, final boolean 30 | showLoadingView, final HttpCallback callback); 31 | 32 | void sendPostJsonRequest(final String url, final Map header, final HttpParams params, final boolean showLoadingView, final HttpCallback callback); 33 | 34 | void sendPostJsonRequestWithLoadingDialog(final String url, final Map header, final HttpParams params, final String 35 | loadingText, final boolean canCancel, final HttpCallback callback); 36 | 37 | boolean isRequesting(final String url); 38 | 39 | /** 40 | * 释放资源 41 | * 42 | * @param context 43 | */ 44 | void releaseResources(Context context); 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/interfaces/WebViewSetInterface.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.interfaces; 2 | 3 | import android.webkit.WebView; 4 | 5 | /** 6 | * Author:leon.wen 7 | * Time:2019/1/2 10:07 8 | * Description:This is WebViewJSInterface 9 | */ 10 | public interface WebViewSetInterface { 11 | public void setWebViwe(WebView webViwe); 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/model/JsOptions.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.model 2 | 3 | /** 4 | * Author: Mario 5 | * Time: 2018/9/11 下午7:45 6 | * Description: This is JsOptions 7 | */ 8 | 9 | open class JsOptions { 10 | 11 | // network 12 | var url: String? = null 13 | var method: String? = null 14 | var headers: Map? = null 15 | var params: Map? = null 16 | var responseType: String? = null 17 | // var files: Array? 18 | 19 | // modal 20 | var text: String? = null 21 | var progress: Int? = null 22 | var title: String? = null 23 | var message: String? = null 24 | var okTitle: String? = null 25 | var cancelTitle: String? = null 26 | var placeholder: String? = null 27 | var isSecure: Boolean? = null 28 | var actions: Array? = null 29 | var duration: Double? = null 30 | var millisecond: Int? = null 31 | 32 | class ActionSheet { 33 | var title: String? = null 34 | var type: String? = null // destructive;cancel;normal 35 | } 36 | 37 | var name: String? = null 38 | // var count: Int? = null 39 | 40 | //ExternalModule 相机相册使用options 41 | var enableCrop = false 42 | var isCircle = true 43 | var width = 100 44 | var height = 100 45 | var count: Int = 0 46 | 47 | //Navigator 48 | var color: String? = null 49 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/model/Result.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.model 2 | 3 | import com.weexbox.core.extension.toJsonMap 4 | import java.util.* 5 | 6 | /** 7 | * Author: Mario 8 | * Time: 2018/9/11 下午8:01 9 | * Description: This is Result 10 | */ 11 | 12 | typealias JsResult = Map? 13 | 14 | typealias Callback = (Result) -> Unit 15 | 16 | class Result { 17 | 18 | companion object { 19 | const val success = 0 20 | const val error = -1 21 | } 22 | 23 | var status: Int = Result.success 24 | var data: MutableMap = TreeMap() 25 | var error: String? = null 26 | var progress: Int? = null 27 | 28 | fun toJsResult(): JsResult { 29 | return toJsonMap() 30 | } 31 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/model/UpdateConfig.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.model 2 | 3 | internal class UpdateConfig { 4 | 5 | var name: String? = null 6 | var ios_min_version: String? = null 7 | var android_min_version: String? = null 8 | var release: String? = null 9 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/model/UpdateMd5.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.model 2 | 3 | import io.realm.RealmObject 4 | import io.realm.annotations.PrimaryKey 5 | 6 | internal open class Md5Realm : RealmObject() { 7 | 8 | @PrimaryKey 9 | var path: String? = null 10 | var md5: String? = null 11 | } 12 | 13 | internal class UpdateMd5 { 14 | 15 | var path: String? = null 16 | var md5: String? = null 17 | 18 | fun toRealm(): Md5Realm { 19 | val fileRealm = Md5Realm() 20 | fileRealm.path = path 21 | fileRealm.md5 = md5 22 | return fileRealm 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/model/WbLibraryModule.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.model; 2 | 3 | import io.realm.annotations.RealmModule; 4 | 5 | /** 6 | * Author:leon.wen 7 | * Time:2019/6/15 11:08 8 | * Description:This is WbLibraryModule 9 | */ 10 | @RealmModule(library = true, classes = {Md5Realm.class}) 11 | public class WbLibraryModule { 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/BaseModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import android.support.v4.app.Fragment 4 | import com.taobao.weex.common.WXModule 5 | import com.weexbox.core.controller.WBBaseActivity 6 | import com.weexbox.core.controller.WBWeexFragment 7 | 8 | /** 9 | * Author: Mario 10 | * Time: 2018/9/12 下午7:45 11 | * Description: This is BaseModule 12 | */ 13 | 14 | open class BaseModule : WXModule() { 15 | 16 | fun getActivity(): WBBaseActivity { 17 | return mWXSDKInstance.context as WBBaseActivity 18 | } 19 | 20 | fun getFragment(): WBWeexFragment? { 21 | val fragments = getActivity().supportFragmentManager.fragments as List 22 | return getRecursionFragment(fragments) 23 | } 24 | 25 | private fun getRecursionFragment(fragments: List): WBWeexFragment? { 26 | for (recursionFragment in fragments) { 27 | if (recursionFragment is WBWeexFragment && mWXSDKInstance == recursionFragment.instance) { 28 | return recursionFragment 29 | } else if (recursionFragment.childFragmentManager.fragments.size > 0) { 30 | getRecursionFragment(recursionFragment.childFragmentManager.fragments) 31 | } 32 | } 33 | return null 34 | } 35 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/EventModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import com.taobao.weex.annotation.JSMethod 4 | import com.taobao.weex.bridge.JSCallback 5 | import com.taobao.weex.utils.WXUtils 6 | import com.weexbox.core.event.Event 7 | import com.weexbox.core.extension.toObject 8 | import com.weexbox.core.model.JsOptions 9 | 10 | /** 11 | * Author: Mario 12 | * Time: 2018/9/12 下午6:33 13 | * Description: This is EventModule 14 | */ 15 | 16 | open class EventModule : BaseModule() { 17 | 18 | @JSMethod(uiThread = true) 19 | open fun register(name: Any, callback: JSCallback) { 20 | Event.register(getFragment()!!, WXUtils.getString(name, null)) { 21 | callback.invokeAndKeepAlive(it) 22 | } 23 | } 24 | 25 | @JSMethod(uiThread = true) 26 | open fun emit(options: Map) { 27 | val info = options.toObject(JsOptions::class.java) 28 | Event.emit(info.name!!, info.params) 29 | } 30 | 31 | @JSMethod(uiThread = true) 32 | open fun unregister(name: Any) { 33 | Event.unregister(getFragment()!!, WXUtils.getString(name, null)) 34 | } 35 | 36 | @JSMethod(uiThread = true) 37 | open fun unregisterAll() { 38 | Event.unregisterAll(getFragment()!!) 39 | } 40 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/NetworkModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import com.alibaba.fastjson.JSONObject 4 | import com.taobao.weex.annotation.JSMethod 5 | import com.taobao.weex.bridge.JSCallback 6 | import com.weexbox.core.extension.toJsonMap 7 | import com.weexbox.core.extension.toObject 8 | import com.weexbox.core.model.JsOptions 9 | import com.weexbox.core.model.Result 10 | import com.weexbox.core.network.Network 11 | import okhttp3.* 12 | import java.io.IOException 13 | 14 | 15 | /** 16 | * Author: Mario 17 | * Time: 2018/9/11 下午7:41 18 | * Description: This is NetworkModule 19 | */ 20 | 21 | open class NetworkModule : BaseModule() { 22 | 23 | @JSMethod(uiThread = false) 24 | open fun request(options: Map, callback: JSCallback) { 25 | val info = options.toObject(JsOptions::class.java) 26 | var method = Network.HTTPMethod.GET 27 | if (info.method?.toUpperCase() == "POST") { 28 | method = Network.HTTPMethod.POST 29 | } 30 | val result = Result() 31 | 32 | // Network.request(info.url!!, method, info.params, info.headers, object : Callback { 33 | // override fun onResponse(call: Call, response: Response) { 34 | // result.status = response.code() 35 | // val data = response.body()?.string() 36 | // if (data != null) { 37 | // if (info.responseType?.toUpperCase() == "TEXT") { 38 | // result.data["data"] = data 39 | // } else { 40 | // result.data = data.toJsonMap() 41 | // } 42 | // } 43 | // result.error = response.errorBody()?.string() 44 | // callback(result) 45 | // } 46 | // 47 | // override fun onFailure(call: Call, t: Throwable) { 48 | // result.status = Result.error 49 | // result.error = t.message 50 | // callback(result) 51 | // } 52 | // }) 53 | 54 | // info.url!!, method, info.params, info.headers 55 | 56 | 57 | val mOkHttpClient = OkHttpClient() 58 | 59 | var formEncodingBuilder: RequestBody ?= null 60 | if (info.params != null && info?.params?.size!! > 0) { 61 | formEncodingBuilder = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), JSONObject.toJSONString(info.params)) 62 | } else{ 63 | formEncodingBuilder = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), "") 64 | } 65 | 66 | var requestBuilder = Request.Builder() 67 | if (info.headers != null && info?.headers?.size!! > 0) { 68 | for (param in info?.headers!!) { 69 | requestBuilder.addHeader(param.key, param.value) 70 | } 71 | } 72 | 73 | var request: Request? = null 74 | if (info.method?.toUpperCase() == "POST") { 75 | request = requestBuilder.url(info.url!!) 76 | .post(formEncodingBuilder) 77 | .build() 78 | } else{ 79 | request = requestBuilder.url(info.url!!) 80 | .get() 81 | .build() 82 | } 83 | 84 | val call = mOkHttpClient.newCall(request) 85 | call.enqueue(object : Callback { 86 | override fun onFailure(call: Call, e: IOException) { 87 | result.status = Result.error 88 | // result.error = e.message 89 | result.error = "似乎已断开与互联网的链接" 90 | callback(result) 91 | } 92 | 93 | override fun onResponse(call: Call, response: Response) { 94 | result.status = response.code() 95 | val data = response.body()?.string() 96 | if (data != null) { 97 | if (info.responseType?.toUpperCase() == "TEXT") { 98 | result.data["data"] = data 99 | } else { 100 | try { 101 | result.data = data.toJsonMap() 102 | } catch (e: Exception){ 103 | result.status = Result.error 104 | } 105 | } 106 | } 107 | result.error = response.message() 108 | callback(result) 109 | } 110 | }) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/RouterModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import com.taobao.weex.annotation.JSMethod 4 | import com.taobao.weex.utils.WXUtils 5 | import com.weexbox.core.extension.toObject 6 | import com.weexbox.core.router.Router 7 | 8 | /** 9 | * Author: Mario 10 | * Time: 2018/8/16 下午5:05 11 | * Description: This is RouterModule 12 | */ 13 | 14 | open class RouterModule : BaseModule() { 15 | 16 | //打开页面 17 | @JSMethod(uiThread = true) 18 | open fun open(options: Map) { 19 | getRouter(options).open(getActivity()) 20 | } 21 | 22 | @JSMethod(uiThread = false) 23 | open fun getParams(): Map? { 24 | return getFragment()!!.router.params 25 | } 26 | 27 | @JSMethod(uiThread = true) 28 | open fun close(levels: Any?) { 29 | getFragment()!!.router.close(getActivity(), WXUtils.getInt(levels)) 30 | } 31 | 32 | @JSMethod(uiThread = true) 33 | open fun refresh() { 34 | getFragment()!!.refreshWeex() 35 | } 36 | 37 | fun getRouter(options: Map): Router { 38 | return options.toObject(Router::class.java) 39 | } 40 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/StorageModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import com.taobao.weex.annotation.JSMethod 4 | 5 | /** 6 | * Author: Mario 7 | * Time: 2018/8/17 下午5:24 8 | * Description: This is StorageModule 9 | */ 10 | 11 | open class StorageModule : BaseModule() { 12 | 13 | @JSMethod(uiThread = true) 14 | open fun setData(key: String, value: String) { 15 | 16 | } 17 | 18 | @JSMethod(uiThread = true) 19 | open fun getData(key: String): String { 20 | return key 21 | } 22 | 23 | @JSMethod(uiThread = true) 24 | open fun deleteData(key: String) { 25 | 26 | } 27 | 28 | @JSMethod(uiThread = true) 29 | open fun deleteAll() { 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/module/WXNavigatorModule.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.module 2 | 3 | import com.alibaba.fastjson.JSON 4 | import com.taobao.weex.annotation.JSMethod 5 | import com.taobao.weex.appfram.navigator.WXNavigatorModule 6 | import com.taobao.weex.bridge.JSCallback 7 | import com.weexbox.core.controller.WBBaseActivity 8 | import com.weexbox.core.router.Router 9 | 10 | /** 11 | * Author: Mario 12 | * Time: 2019-08-05 20:19 13 | * Description: This is WXNavigatorModule 14 | */ 15 | 16 | open class WXNavigatorModule: WXNavigatorModule() { 17 | 18 | @JSMethod(uiThread = true) 19 | override fun push(param: String?, callback: JSCallback?) { 20 | val jsonObject = JSON.parseObject(param) 21 | val url = jsonObject.getString("url") 22 | val router = Router() 23 | router.url = url 24 | router.name = Router.NAME_WEEX 25 | router.open(mWXSDKInstance.context as WBBaseActivity) 26 | callback?.invoke(MSG_SUCCESS) 27 | } 28 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/CookiesUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net; 2 | 3 | import android.content.Context; 4 | import android.webkit.CookieManager; 5 | import android.webkit.CookieSyncManager; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | import okhttp3.Cookie; 11 | 12 | /** 13 | * Created by freeson on 16/8/4. 14 | */ 15 | public final class CookiesUtil { 16 | 17 | private CookiesUtil() { 18 | } 19 | 20 | /** 21 | * 获取cookies 22 | * 23 | * @return 24 | */ 25 | public static List getCookies() { 26 | return HttpUtil.getCookies(); 27 | } 28 | 29 | /** 30 | * 设置cookies到WebView 31 | * 32 | * @param context 33 | * @param url 34 | */ 35 | public static void syncCookiesToWebView(Context context, String url) { 36 | setCookiesToWebView(context, url, getCookies()); 37 | } 38 | 39 | /** 40 | * 设置cookies到WebView 41 | * 42 | * @param context 43 | * @param url 44 | * @param cookies 45 | */ 46 | public static void setCookiesToWebView(Context context, String url, List cookies) { 47 | if (!cookies.isEmpty()) { 48 | CookieSyncManager.createInstance(context); 49 | CookieManager cookieManager = CookieManager.getInstance(); 50 | cookieManager.setAcceptCookie(true); 51 | for (Cookie cookie : cookies) { 52 | String cookieStr = cookie.name() + "=" + cookie.value() + "; expires=" + cookie.expiresAt() 53 | + "; path=" + cookie.path() + "; domain=" + cookie.domain(); 54 | cookieManager.setCookie(url, cookieStr); 55 | } 56 | CookieSyncManager.getInstance().sync(); 57 | } 58 | } 59 | 60 | /** 61 | * 设置cookies到WebView 62 | * 63 | * @param context 64 | * @param url 65 | */ 66 | public static void setCookiesToWebView(Context context, String url) { 67 | List cookies = getCookies(); 68 | if (!cookies.isEmpty()) { 69 | CookieSyncManager.createInstance(context); 70 | CookieManager cookieManager = CookieManager.getInstance(); 71 | cookieManager.setAcceptCookie(true); 72 | for (Cookie cookie : cookies) { 73 | String cookieStr = cookie.name() + "=" + cookie.value() + "; expires=" + cookie.expiresAt() 74 | + "; path=" + cookie.path() + "; domain=" + cookie.domain(); 75 | cookieManager.setCookie(url, cookieStr); 76 | } 77 | CookieSyncManager.getInstance().sync(); 78 | } 79 | } 80 | 81 | /** 82 | * 设置cookies到WebView 83 | * 84 | * @param context 85 | * @param url 86 | * @param cookie 87 | */ 88 | public static void setCookieToWebview(Context context, String url, String cookie) { 89 | CookieSyncManager.createInstance(context); 90 | CookieManager mCookieManager = CookieManager.getInstance(); 91 | mCookieManager.setAcceptCookie(true); 92 | mCookieManager.setCookie(url, cookie); 93 | CookieSyncManager.getInstance().sync(); 94 | } 95 | 96 | /** 97 | * 设置同步cookies到httpclient 98 | * 99 | * @param cookies 100 | * @param domain 101 | * @param expireDate 102 | */ 103 | public static void setCookiesToHttp(String cookies, String domain, Date expireDate) { 104 | HttpUtil.setCookiesToHttp(cookies, domain, expireDate); 105 | } 106 | 107 | /** 108 | * 清除WebView的cookies 109 | * 110 | * @param context 111 | */ 112 | public static void clearWebViewCookies(Context context) { 113 | CookieSyncManager.createInstance(context); 114 | CookieManager cookieManager = CookieManager.getInstance(); 115 | cookieManager.removeAllCookie(); 116 | } 117 | 118 | /** 119 | * 清除http的cookies 120 | */ 121 | public static void clearHttpCookies() { 122 | HttpUtil.clearCookies(); 123 | } 124 | 125 | /** 126 | * 清除http和webView的cookie 127 | * 128 | * @param context 129 | */ 130 | public static void clearCookies(Context context) { 131 | clearHttpCookies(); 132 | clearWebViewCookies(context); 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/HttpParams.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | import java.io.File; 6 | import java.io.Serializable; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | public class HttpParams implements Serializable { 13 | 14 | private final LinkedHashMap urlParams = new LinkedHashMap(); 15 | private LinkedHashMap fileParams; 16 | 17 | public HttpParams(Map source) { 18 | if (source != null) { 19 | for (Map.Entry entry : source.entrySet()) { 20 | put(entry.getKey(), entry.getValue()); 21 | } 22 | } 23 | } 24 | 25 | public HttpParams(final String key, final String value) { 26 | this(new HashMap() { 27 | { 28 | put(key, value); 29 | } 30 | }); 31 | } 32 | 33 | public HttpParams(Object... keysAndValues) { 34 | int len = keysAndValues.length; 35 | if (len % 2 != 0) { 36 | throw new IllegalArgumentException("Supplied arguments must be even"); 37 | } 38 | for (int i = 0; i < len; i += 2) { 39 | String key = String.valueOf(keysAndValues[i]); 40 | String val = String.valueOf(keysAndValues[i + 1]); 41 | put(key, val); 42 | } 43 | } 44 | 45 | public void put(String key, Object value) { 46 | if (key != null && value != null) { 47 | urlParams.put(key, value); 48 | } 49 | } 50 | 51 | public void put(String key, File file) { 52 | if (key != null) { 53 | if (fileParams == null) { 54 | fileParams = new LinkedHashMap<>(); 55 | } 56 | fileParams.put(key, file); 57 | } 58 | } 59 | 60 | public void remove(String key) { 61 | urlParams.remove(key); 62 | } 63 | 64 | public boolean has(String key) { 65 | return urlParams.get(key) != null; 66 | } 67 | 68 | public String convertToJson() { 69 | return JSON.toJSONString(urlParams); 70 | } 71 | 72 | public LinkedHashMap getUrlParams() { 73 | final LinkedHashMap temp = new LinkedHashMap<>(); 74 | for (ConcurrentHashMap.Entry entry : urlParams.entrySet()) { 75 | final Object object = entry.getValue(); 76 | temp.put(entry.getKey(), String.valueOf(object)); 77 | } 78 | return temp; 79 | } 80 | 81 | public LinkedHashMap getFileParams() { 82 | return fileParams; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | StringBuilder result = new StringBuilder(); 88 | for (ConcurrentHashMap.Entry entry : urlParams.entrySet()) { 89 | if (result.length() > 0) { 90 | result.append("&"); 91 | } 92 | 93 | result.append(entry.getKey()); 94 | result.append("="); 95 | result.append(entry.getValue().toString()); 96 | } 97 | return result.toString(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/callback/HttpBitmapCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.callback; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | import java.io.InputStream; 7 | 8 | /** 9 | * Created by freeson on 16/7/29. 10 | */ 11 | public abstract class HttpBitmapCallback extends HttpCallback { 12 | 13 | @Override 14 | protected boolean useInputStream() { 15 | return true; 16 | } 17 | 18 | @Override 19 | protected Bitmap decodeInputStream(InputStream inputStream, final long length, int requestId) { 20 | return BitmapFactory.decodeStream(inputStream); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/callback/HttpEntityCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.callback; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | 8 | /** 9 | * Created by freeson on 16/7/28.
10 | *

11 | * 使用方法:
12 | *

13 | * OkHttpUtils.post().url(url) 14 | * .build() 15 | * .execute(new HttpEntityCallback() { 16 | * 17 | * @Override protected void onSuccess(TestEntity entity, int id) { 18 | * System.out.println("---response.imageUrl--->" + entity.imageUrl); 19 | * } 20 | * @Override protected void onFail(Call call, int errorCode, int id) { 21 | *

22 | * } 23 | * }); 24 | */ 25 | public abstract class HttpEntityCallback extends HttpCallback { 26 | 27 | @Override 28 | public T parseEntity(String data, int requestId) { 29 | T object = null; 30 | Type t = getClass().getGenericSuperclass(); 31 | if (t instanceof ParameterizedType) { 32 | Type[] p = ((ParameterizedType) t).getActualTypeArguments(); 33 | // if (isList()) { 34 | // Class entityClass = (Class) p[0]; 35 | // object = new Gson().fromJson(data, entityClass); 36 | // } else { 37 | // Class entityClass = (Class) p[0]; 38 | // object = new Gson().fromJson(data, entityClass); 39 | // } 40 | 41 | 42 | if (isList()) { 43 | object = JSON.parseObject(data, p[0]); 44 | } else { 45 | Class entityClass = (Class) p[0]; 46 | object = JSON.parseObject(data, entityClass); 47 | } 48 | } 49 | 50 | return object; 51 | } 52 | 53 | /** 54 | * 如果最外层数据直接就是一个数组的话, 请返回true, 或者使用{@link HttpListEntityCallback} 55 | * 56 | * @return 57 | */ 58 | protected boolean isList() { 59 | return false; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/callback/HttpFileCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.callback; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | 10 | /** 11 | * Created by freeson on 16/7/29. 12 | */ 13 | public abstract class HttpFileCallback extends HttpCallback { 14 | 15 | /** 16 | * 目标文件存储的文件夹路径 17 | */ 18 | private String destFileDir; 19 | /** 20 | * 目标文件存储的文件名 21 | */ 22 | private String destFileName; 23 | 24 | 25 | public HttpFileCallback(String destFileDir, String destFileName) { 26 | this.destFileDir = destFileDir; 27 | this.destFileName = destFileName; 28 | } 29 | 30 | @Override 31 | public void inProgress(float progress, long total, int id) { 32 | super.inProgress(progress, total, id); 33 | } 34 | 35 | @Override 36 | protected boolean useInputStream() { 37 | return true; 38 | } 39 | 40 | @Override 41 | protected File decodeInputStream(InputStream inputStream, long length, int requestId) throws IOException { 42 | return saveFile(inputStream, length, requestId); 43 | } 44 | 45 | public File saveFile(InputStream inputStream, long length, final int requestId) throws IOException { 46 | InputStream is = inputStream; 47 | byte[] buf = new byte[2048]; 48 | int len = 0; 49 | FileOutputStream fos = null; 50 | try { 51 | final long total = length; 52 | 53 | long sum = 0; 54 | 55 | File dir = new File(destFileDir); 56 | if (!dir.exists()) { 57 | dir.mkdirs(); 58 | } 59 | File file = new File(dir, destFileName); 60 | fos = new FileOutputStream(file); 61 | while ((len = is.read(buf)) != -1) { 62 | sum += len; 63 | fos.write(buf, 0, len); 64 | final long finalSum = sum; 65 | OkHttpUtils.getInstance().getDelivery().execute(new Runnable() { 66 | @Override 67 | public void run() { 68 | 69 | inProgress(finalSum * 1.0f / total, total, requestId); 70 | } 71 | }); 72 | } 73 | fos.flush(); 74 | 75 | return file; 76 | 77 | } finally { 78 | try { 79 | inputStream.close(); 80 | if (is != null) { 81 | is.close(); 82 | } 83 | } catch (IOException e) { 84 | } 85 | try { 86 | if (fos != null) { 87 | fos.close(); 88 | } 89 | } catch (IOException e) { 90 | } 91 | 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/callback/HttpListEntityCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.callback; 2 | 3 | /** 4 | * Created by freeson on 16/7/28. 5 | *

6 | * OkHttpUtils.post().url(url) 7 | * .build() 8 | * .execute(new HttpListEntityCallback>() { 9 | * 10 | * @Override protected void onSuccess(List entity, int id) { 11 | * System.out.println("------>" + entity.size()); 12 | * } 13 | * @Override protected void onFail(Call call, int code, int id) { 14 | *

15 | * } 16 | * }); 17 | */ 18 | 19 | 20 | public abstract class HttpListEntityCallback extends HttpEntityCallback { 21 | 22 | @Override 23 | protected boolean isList() { 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/callback/HttpStringCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.callback; 2 | 3 | /** 4 | * Created by freeson on 16/7/28. 5 | */ 6 | public abstract class HttpStringCallback extends HttpCallback { 7 | 8 | @Override 9 | public String parseEntity(String data, int requestId) { 10 | return data; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/entity/HttpBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by freeson on 16/7/28. 7 | */ 8 | public class HttpBaseEntity implements Serializable, INoneConfuse { 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/net/entity/INoneConfuse.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.net.entity; 2 | 3 | /** 4 | * Created by freeson on 16/7/28. 5 | */ 6 | public interface INoneConfuse { 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/network/Network.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.network 2 | 3 | import com.weexbox.core.extension.appendingPathComponent 4 | import com.weexbox.core.extension.toJsonString 5 | import okhttp3.MediaType 6 | import okhttp3.OkHttpClient 7 | import okhttp3.RequestBody 8 | import okhttp3.ResponseBody 9 | import retrofit2.Call 10 | import retrofit2.Callback 11 | import retrofit2.Retrofit 12 | import retrofit2.http.* 13 | import java.io.File 14 | import java.util.* 15 | import java.util.concurrent.TimeUnit 16 | 17 | /** 18 | * Author: Mario 19 | * Time: 2018/9/11 下午4:46 20 | * Description: This is Network 21 | */ 22 | 23 | object Network { 24 | 25 | var server: String? = null 26 | 27 | enum class HTTPMethod { 28 | GET, 29 | POST 30 | } 31 | 32 | @JvmSuppressWildcards 33 | interface Service { 34 | @GET 35 | fun methodGet(@Url url: String, @QueryMap parameters: Map, @HeaderMap headers: Map): Call 36 | 37 | // @FormUrlEncoded 38 | // @POST 39 | // fun methodPost(@Url url: String, @FieldMap parameters: Map, @HeaderMap headers: Map): Call 40 | 41 | @POST 42 | fun methodJson(@Url url: String, @Body body: RequestBody, @HeaderMap headers: Map): Call 43 | } 44 | 45 | val client: OkHttpClient = OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).retryOnConnectionFailure(true).build() 46 | var mediaTypeJSON: MediaType? = MediaType.parse("application/json") 47 | 48 | private fun call(url: String, method: HTTPMethod = HTTPMethod.GET, parameters: Map, headers: Map): Call { 49 | val retrofit = Retrofit.Builder().baseUrl(url.appendingPathComponent(File.separator)).client(client).build() 50 | val service = retrofit.create(Service::class.java) 51 | if (method == HTTPMethod.POST) { 52 | // val contentType = headers["Content-Type"] 53 | // if (contentType != null && contentType.contains("application/json")) { 54 | // val body = RequestBody.create(mediaTypeJSON, parameters.toJsonString()) 55 | // return service.methodJson(url, body, headers) 56 | // } else { 57 | // return service.methodPost(url, parameters, headers) 58 | // } 59 | val body = RequestBody.create(mediaTypeJSON, parameters.toJsonString()) 60 | return service.methodJson(url, body, headers) 61 | } else { 62 | return service.methodGet(url, parameters, headers) 63 | } 64 | } 65 | 66 | fun request(url: String, method: HTTPMethod = HTTPMethod.GET, parameters: Map?, headers: Map?, callback: Callback) { 67 | var urlFinal: String? = null 68 | if (!url.startsWith("http://") && !url.startsWith("https://")) { 69 | urlFinal = server?.appendingPathComponent(url) 70 | } 71 | val call = call(urlFinal ?: url, method, parameters ?: TreeMap(), headers ?: TreeMap()) 72 | call.enqueue(callback) 73 | } 74 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/GetBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import android.net.Uri; 4 | 5 | import com.weexbox.core.okhttp.request.GetRequest; 6 | import com.weexbox.core.okhttp.request.RequestCall; 7 | 8 | import java.util.Iterator; 9 | import java.util.LinkedHashMap; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | /** 14 | * Created by zhy on 15/12/14. 15 | */ 16 | public class GetBuilder extends OkHttpRequestBuilder implements HasParamsable { 17 | @Override 18 | public RequestCall build() { 19 | if (params != null) { 20 | url = appendParams(url, params); 21 | } 22 | 23 | return new GetRequest(url, tag, params, headers, id).build(); 24 | } 25 | 26 | protected String appendParams(String url, Map params) { 27 | if (url == null || params == null || params.isEmpty()) { 28 | return url; 29 | } 30 | Uri.Builder builder = Uri.parse(url).buildUpon(); 31 | Set keys = params.keySet(); 32 | Iterator iterator = keys.iterator(); 33 | while (iterator.hasNext()) { 34 | String key = iterator.next(); 35 | builder.appendQueryParameter(key, params.get(key)); 36 | } 37 | return builder.build().toString(); 38 | } 39 | 40 | 41 | @Override 42 | public GetBuilder params(Map params) { 43 | this.params = params; 44 | return this; 45 | } 46 | 47 | @Override 48 | public GetBuilder addParams(String key, String val) { 49 | if (this.params == null) { 50 | params = new LinkedHashMap<>(); 51 | } 52 | params.put(key, val); 53 | return this; 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/HasParamsable.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by zhy on 16/3/1. 7 | */ 8 | public interface HasParamsable { 9 | OkHttpRequestBuilder params(Map params); 10 | 11 | OkHttpRequestBuilder addParams(String key, String val); 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/HeadBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | import com.weexbox.core.okhttp.request.OtherRequest; 5 | import com.weexbox.core.okhttp.request.RequestCall; 6 | 7 | /** 8 | * Created by zhy on 16/3/2. 9 | */ 10 | public class HeadBuilder extends GetBuilder { 11 | @Override 12 | public RequestCall build() { 13 | return new OtherRequest(null, null, OkHttpUtils.METHOD.HEAD, url, tag, params, headers, id).build(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/OkHttpRequestBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.request.RequestCall; 4 | 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by zhy on 15/12/14. 10 | */ 11 | public abstract class OkHttpRequestBuilder { 12 | protected String url; 13 | protected Object tag; 14 | protected Map headers; 15 | protected Map params; 16 | protected int id; 17 | 18 | public T id(int id) { 19 | this.id = id; 20 | return (T) this; 21 | } 22 | 23 | public T url(String url) { 24 | this.url = url; 25 | return (T) this; 26 | } 27 | 28 | 29 | public T tag(Object tag) { 30 | this.tag = tag; 31 | return (T) this; 32 | } 33 | 34 | public T headers(Map headers) { 35 | this.headers = headers; 36 | return (T) this; 37 | } 38 | 39 | public T addHeader(String key, String val) { 40 | if (this.headers == null) { 41 | headers = new LinkedHashMap<>(); 42 | } 43 | headers.put(key, val); 44 | return (T) this; 45 | } 46 | 47 | public abstract RequestCall build(); 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/OtherRequestBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.request.OtherRequest; 4 | import com.weexbox.core.okhttp.request.RequestCall; 5 | 6 | import okhttp3.RequestBody; 7 | 8 | /** 9 | * DELETE、PUT、PATCH等其他方法 10 | */ 11 | public class OtherRequestBuilder extends OkHttpRequestBuilder { 12 | private RequestBody requestBody; 13 | private String method; 14 | private String content; 15 | 16 | public OtherRequestBuilder(String method) { 17 | this.method = method; 18 | } 19 | 20 | @Override 21 | public RequestCall build() { 22 | return new OtherRequest(requestBody, content, method, url, tag, params, headers, id).build(); 23 | } 24 | 25 | public OtherRequestBuilder requestBody(RequestBody requestBody) { 26 | this.requestBody = requestBody; 27 | return this; 28 | } 29 | 30 | public OtherRequestBuilder requestBody(String content) { 31 | this.content = content; 32 | return this; 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/PostFileBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.request.PostFileRequest; 4 | import com.weexbox.core.okhttp.request.RequestCall; 5 | 6 | import java.io.File; 7 | 8 | import okhttp3.MediaType; 9 | 10 | /** 11 | * Created by zhy on 15/12/14. 12 | */ 13 | public class PostFileBuilder extends OkHttpRequestBuilder { 14 | private File file; 15 | private MediaType mediaType; 16 | 17 | 18 | public OkHttpRequestBuilder file(File file) { 19 | this.file = file; 20 | return this; 21 | } 22 | 23 | public OkHttpRequestBuilder mediaType(MediaType mediaType) { 24 | this.mediaType = mediaType; 25 | return this; 26 | } 27 | 28 | @Override 29 | public RequestCall build() { 30 | return new PostFileRequest(url, tag, params, headers, file, mediaType, id).build(); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/PostFormBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.request.PostFormRequest; 4 | import com.weexbox.core.okhttp.request.RequestCall; 5 | 6 | import java.io.File; 7 | import java.util.ArrayList; 8 | import java.util.LinkedHashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created by zhy on 15/12/14. 14 | */ 15 | public class PostFormBuilder extends OkHttpRequestBuilder implements HasParamsable { 16 | private List files = new ArrayList<>(); 17 | 18 | @Override 19 | public RequestCall build() { 20 | return new PostFormRequest(url, tag, params, headers, files, id).build(); 21 | } 22 | 23 | public PostFormBuilder files(String key, Map files) { 24 | for (String filename : files.keySet()) { 25 | this.files.add(new FileInput(key, filename, files.get(filename))); 26 | } 27 | return this; 28 | } 29 | 30 | public PostFormBuilder addFile(String name, String filename, File file) { 31 | files.add(new FileInput(name, filename, file)); 32 | return this; 33 | } 34 | 35 | @Override 36 | public PostFormBuilder params(Map params) { 37 | this.params = params; 38 | return this; 39 | } 40 | 41 | @Override 42 | public PostFormBuilder addParams(String key, String val) { 43 | if (this.params == null) { 44 | params = new LinkedHashMap<>(); 45 | } 46 | params.put(key, val); 47 | return this; 48 | } 49 | 50 | public static class FileInput { 51 | public String key; 52 | public String filename; 53 | public File file; 54 | 55 | public FileInput(String name, String filename, File file) { 56 | this.key = name; 57 | this.filename = filename; 58 | this.file = file; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "FileInput{" + 64 | "key='" + key + '\'' + 65 | ", filename='" + filename + '\'' + 66 | ", file=" + file + 67 | '}'; 68 | } 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/builder/PostStringBuilder.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.builder; 2 | 3 | import com.weexbox.core.okhttp.request.PostStringRequest; 4 | import com.weexbox.core.okhttp.request.RequestCall; 5 | 6 | import okhttp3.MediaType; 7 | 8 | /** 9 | * Created by zhy on 15/12/14. 10 | */ 11 | public class PostStringBuilder extends OkHttpRequestBuilder { 12 | private String content; 13 | private MediaType mediaType; 14 | 15 | 16 | public PostStringBuilder content(String content) { 17 | this.content = content; 18 | return this; 19 | } 20 | 21 | public PostStringBuilder mediaType(MediaType mediaType) { 22 | this.mediaType = mediaType; 23 | return this; 24 | } 25 | 26 | @Override 27 | public RequestCall build() { 28 | return new PostStringRequest(url, tag, params, headers, content, mediaType, id).build(); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/BitmapCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | import okhttp3.Response; 7 | 8 | /** 9 | * Created by zhy on 15/12/14. 10 | */ 11 | public abstract class BitmapCallback extends Callback { 12 | @Override 13 | public Bitmap parseNetworkResponse(Response response, int id) { 14 | return BitmapFactory.decodeStream(response.body().byteStream()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/Callback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | import okhttp3.Call; 4 | import okhttp3.Request; 5 | import okhttp3.Response; 6 | 7 | public abstract class Callback { 8 | public static Callback CALLBACK_DEFAULT = new Callback() { 9 | 10 | @Override 11 | public Object parseNetworkResponse(Response response, int id) { 12 | return null; 13 | } 14 | 15 | @Override 16 | public void onError(Call call, Exception e, int id) { 17 | 18 | } 19 | 20 | @Override 21 | public void onResponse(Object response, int id) { 22 | 23 | } 24 | }; 25 | 26 | /** 27 | * UI Thread 28 | * 29 | * @param request 30 | */ 31 | public void onBefore(Request request, int id) { 32 | } 33 | 34 | /** 35 | * UI Thread 36 | * 37 | * @param 38 | */ 39 | public void onAfter(int id) { 40 | } 41 | 42 | /** 43 | * UI Thread 44 | * 45 | * @param progress 46 | */ 47 | public void inProgress(float progress, long total, int id) { 48 | 49 | } 50 | 51 | /** 52 | * if you parse reponse code in parseNetworkResponse, you should make this method return true. 53 | * 54 | * @param response 55 | * @return 56 | */ 57 | public boolean validateReponse(Response response, int id) { 58 | return response.isSuccessful(); 59 | } 60 | 61 | /** 62 | * Thread Pool Thread 63 | * 64 | * @param response 65 | */ 66 | public abstract T parseNetworkResponse(Response response, int id) throws Exception; 67 | 68 | public abstract void onError(Call call, Exception e, int id); 69 | 70 | public abstract void onResponse(T response, int id); 71 | 72 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/FileCallBack.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | 10 | import okhttp3.Response; 11 | 12 | /** 13 | * Created by zhy on 15/12/15. 14 | */ 15 | public abstract class FileCallBack extends Callback { 16 | /** 17 | * 目标文件存储的文件夹路径 18 | */ 19 | private String destFileDir; 20 | /** 21 | * 目标文件存储的文件名 22 | */ 23 | private String destFileName; 24 | 25 | 26 | public FileCallBack(String destFileDir, String destFileName) { 27 | this.destFileDir = destFileDir; 28 | this.destFileName = destFileName; 29 | } 30 | 31 | 32 | @Override 33 | public File parseNetworkResponse(Response response, int id) throws Exception { 34 | return saveFile(response, id); 35 | } 36 | 37 | 38 | public File saveFile(Response response, final int id) throws IOException { 39 | InputStream is = null; 40 | byte[] buf = new byte[2048]; 41 | int len = 0; 42 | FileOutputStream fos = null; 43 | try { 44 | is = response.body().byteStream(); 45 | final long total = response.body().contentLength(); 46 | 47 | long sum = 0; 48 | 49 | File dir = new File(destFileDir); 50 | if (!dir.exists()) { 51 | dir.mkdirs(); 52 | } 53 | File file = new File(dir, destFileName); 54 | fos = new FileOutputStream(file); 55 | while ((len = is.read(buf)) != -1) { 56 | sum += len; 57 | fos.write(buf, 0, len); 58 | final long finalSum = sum; 59 | OkHttpUtils.getInstance().getDelivery().execute(new Runnable() { 60 | @Override 61 | public void run() { 62 | 63 | inProgress(finalSum * 1.0f / total, total, id); 64 | } 65 | }); 66 | } 67 | fos.flush(); 68 | 69 | return file; 70 | 71 | } finally { 72 | try { 73 | response.body().close(); 74 | if (is != null) { 75 | is.close(); 76 | } 77 | } catch (IOException e) { 78 | } 79 | try { 80 | if (fos != null) { 81 | fos.close(); 82 | } 83 | } catch (IOException e) { 84 | } 85 | 86 | } 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/GenericsCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.ParameterizedType; 5 | 6 | import okhttp3.Response; 7 | 8 | /** 9 | * Created by JimGong on 2016/6/23. 10 | */ 11 | 12 | public abstract class GenericsCallback extends Callback { 13 | IGenericsSerializator mGenericsSerializator; 14 | 15 | public GenericsCallback(IGenericsSerializator serializator) { 16 | mGenericsSerializator = serializator; 17 | } 18 | 19 | @Override 20 | public T parseNetworkResponse(Response response, int id) throws IOException { 21 | String string = response.body().string(); 22 | Class entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 23 | if (entityClass == String.class) { 24 | return (T) string; 25 | } 26 | T bean = mGenericsSerializator.transform(string, entityClass); 27 | return bean; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/IGenericsSerializator.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | /** 4 | * Created by JimGong on 2016/6/23. 5 | */ 6 | public interface IGenericsSerializator { 7 | T transform(String response, Class classOfT); 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/callback/StringCallback.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.callback; 2 | 3 | import java.io.IOException; 4 | 5 | import okhttp3.Response; 6 | 7 | /** 8 | * Created by zhy on 15/12/14. 9 | */ 10 | public abstract class StringCallback extends Callback { 11 | @Override 12 | public String parseNetworkResponse(Response response, int id) throws IOException { 13 | return response.body().string(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/cookie/CookieJarImpl.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.cookie; 2 | 3 | import com.weexbox.core.okhttp.cookie.store.CookieStore; 4 | import com.weexbox.core.okhttp.utils.Exceptions; 5 | 6 | import java.util.List; 7 | 8 | import okhttp3.Cookie; 9 | import okhttp3.CookieJar; 10 | import okhttp3.HttpUrl; 11 | 12 | /** 13 | * Created by zhy on 16/3/10. 14 | */ 15 | public class CookieJarImpl implements CookieJar { 16 | private CookieStore cookieStore; 17 | 18 | public CookieJarImpl(CookieStore cookieStore) { 19 | if (cookieStore == null) { 20 | Exceptions.illegalArgument("cookieStore can not be null."); 21 | } 22 | this.cookieStore = cookieStore; 23 | } 24 | 25 | @Override 26 | public synchronized void saveFromResponse(HttpUrl url, List cookies) { 27 | cookieStore.add(url, cookies); 28 | } 29 | 30 | @Override 31 | public synchronized List loadForRequest(HttpUrl url) { 32 | return cookieStore.get(url); 33 | } 34 | 35 | public CookieStore getCookieStore() { 36 | return cookieStore; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/cookie/store/CookieStore.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.cookie.store; 2 | 3 | import java.util.List; 4 | 5 | import okhttp3.Cookie; 6 | import okhttp3.HttpUrl; 7 | 8 | public interface CookieStore { 9 | 10 | void add(HttpUrl uri, List cookie); 11 | 12 | List get(HttpUrl uri); 13 | 14 | List getCookies(); 15 | 16 | boolean remove(HttpUrl uri, Cookie cookie); 17 | 18 | boolean removeAll(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/cookie/store/HasCookieStore.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.cookie.store; 2 | 3 | /** 4 | * Created by zhy on 16/3/10. 5 | */ 6 | public interface HasCookieStore { 7 | CookieStore getCookieStore(); 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/cookie/store/MemoryCookieStore.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.cookie.store; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import okhttp3.Cookie; 10 | import okhttp3.HttpUrl; 11 | 12 | /** 13 | * Created by zhy on 16/3/10. 14 | */ 15 | public class MemoryCookieStore implements CookieStore { 16 | private final HashMap> allCookies = new HashMap<>(); 17 | 18 | @Override 19 | public void add(HttpUrl url, List cookies) { 20 | List oldCookies = allCookies.get(url.host()); 21 | 22 | if (oldCookies != null) { 23 | Iterator itNew = cookies.iterator(); 24 | Iterator itOld = oldCookies.iterator(); 25 | while (itNew.hasNext()) { 26 | String va = itNew.next().name(); 27 | while (va != null && itOld.hasNext()) { 28 | String v = itOld.next().name(); 29 | if (v != null && va.equals(v)) { 30 | itOld.remove(); 31 | } 32 | } 33 | } 34 | oldCookies.addAll(cookies); 35 | } else { 36 | allCookies.put(url.host(), cookies); 37 | } 38 | 39 | 40 | } 41 | 42 | @Override 43 | public List get(HttpUrl uri) { 44 | List cookies = allCookies.get(uri.host()); 45 | if (cookies == null) { 46 | cookies = new ArrayList<>(); 47 | allCookies.put(uri.host(), cookies); 48 | } 49 | return cookies; 50 | 51 | } 52 | 53 | @Override 54 | public boolean removeAll() { 55 | allCookies.clear(); 56 | return true; 57 | } 58 | 59 | @Override 60 | public List getCookies() { 61 | List cookies = new ArrayList<>(); 62 | Set httpUrls = allCookies.keySet(); 63 | for (String url : httpUrls) { 64 | cookies.addAll(allCookies.get(url)); 65 | } 66 | return cookies; 67 | } 68 | 69 | 70 | @Override 71 | public boolean remove(HttpUrl uri, Cookie cookie) { 72 | List cookies = allCookies.get(uri.host()); 73 | if (cookie != null) { 74 | return cookies.remove(cookie); 75 | } 76 | return false; 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/cookie/store/SerializableHttpCookie.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.cookie.store; 2 | 3 | import java.io.IOException; 4 | import java.io.ObjectInputStream; 5 | import java.io.ObjectOutputStream; 6 | import java.io.Serializable; 7 | 8 | import okhttp3.Cookie; 9 | 10 | /** 11 | * from http://stackoverflow.com/questions/25461792/persistent-cookie-store-using-okhttp-2-on-android 12 | * and
13 | * http://www.geebr.com/post/okHttp3%E4%B9%8BCookies%E7%AE%A1%E7%90%86%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96 14 | */ 15 | 16 | public class SerializableHttpCookie implements Serializable { 17 | private static final long serialVersionUID = 6374381323722046732L; 18 | 19 | private transient final Cookie cookie; 20 | private transient Cookie clientCookie; 21 | 22 | public SerializableHttpCookie(Cookie cookie) { 23 | this.cookie = cookie; 24 | } 25 | 26 | public Cookie getCookie() { 27 | Cookie bestCookie = cookie; 28 | if (clientCookie != null) { 29 | bestCookie = clientCookie; 30 | } 31 | 32 | return bestCookie; 33 | } 34 | 35 | private void writeObject(ObjectOutputStream out) throws IOException { 36 | out.writeObject(cookie.name()); 37 | out.writeObject(cookie.value()); 38 | out.writeLong(cookie.expiresAt()); 39 | out.writeObject(cookie.domain()); 40 | out.writeObject(cookie.path()); 41 | out.writeBoolean(cookie.secure()); 42 | out.writeBoolean(cookie.httpOnly()); 43 | out.writeBoolean(cookie.hostOnly()); 44 | out.writeBoolean(cookie.persistent()); 45 | } 46 | 47 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 48 | String name = (String) in.readObject(); 49 | String value = (String) in.readObject(); 50 | long expiresAt = in.readLong(); 51 | String domain = (String) in.readObject(); 52 | String path = (String) in.readObject(); 53 | boolean secure = in.readBoolean(); 54 | boolean httpOnly = in.readBoolean(); 55 | boolean hostOnly = in.readBoolean(); 56 | boolean persistent = in.readBoolean(); 57 | Cookie.Builder builder = new Cookie.Builder(); 58 | builder = builder.name(name); 59 | builder = builder.value(value); 60 | builder = builder.expiresAt(expiresAt); 61 | builder = hostOnly ? builder.hostOnlyDomain(domain) : builder.domain(domain); 62 | builder = builder.path(path); 63 | builder = secure ? builder.secure() : builder; 64 | builder = httpOnly ? builder.httpOnly() : builder; 65 | clientCookie = builder.build(); 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/CountingRequestBody.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import java.io.IOException; 4 | 5 | import okhttp3.MediaType; 6 | import okhttp3.RequestBody; 7 | import okio.Buffer; 8 | import okio.BufferedSink; 9 | import okio.ForwardingSink; 10 | import okio.Okio; 11 | import okio.Sink; 12 | 13 | /** 14 | * Decorates an OkHttp request body to count the number of bytes written when writing it. Can 15 | * decorate any request body, but is most useful for tracking the upload progress of large 16 | * multipart requests. 17 | * 18 | * @author Leo Nikkilä 19 | */ 20 | public class CountingRequestBody extends RequestBody { 21 | 22 | protected RequestBody delegate; 23 | protected Listener listener; 24 | 25 | protected CountingSink countingSink; 26 | 27 | public CountingRequestBody(RequestBody delegate, Listener listener) { 28 | this.delegate = delegate; 29 | this.listener = listener; 30 | } 31 | 32 | @Override 33 | public MediaType contentType() { 34 | return delegate.contentType(); 35 | } 36 | 37 | @Override 38 | public long contentLength() { 39 | try { 40 | return delegate.contentLength(); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } 44 | return -1; 45 | } 46 | 47 | @Override 48 | public void writeTo(BufferedSink sink) throws IOException { 49 | 50 | countingSink = new CountingSink(sink); 51 | BufferedSink bufferedSink = Okio.buffer(countingSink); 52 | 53 | delegate.writeTo(bufferedSink); 54 | 55 | bufferedSink.flush(); 56 | } 57 | 58 | public interface Listener { 59 | void onRequestProgress(long bytesWritten, long contentLength); 60 | } 61 | 62 | protected final class CountingSink extends ForwardingSink { 63 | 64 | private long bytesWritten = 0; 65 | 66 | public CountingSink(Sink delegate) { 67 | super(delegate); 68 | } 69 | 70 | @Override 71 | public void write(Buffer source, long byteCount) throws IOException { 72 | super.write(source, byteCount); 73 | 74 | bytesWritten += byteCount; 75 | listener.onRequestProgress(bytesWritten, contentLength()); 76 | } 77 | 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/GetRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import java.util.Map; 4 | 5 | import okhttp3.Request; 6 | import okhttp3.RequestBody; 7 | 8 | /** 9 | * Created by zhy on 15/12/14. 10 | */ 11 | public class GetRequest extends OkHttpRequest { 12 | public GetRequest(String url, Object tag, Map params, Map headers, int id) { 13 | super(url, tag, params, headers, id); 14 | } 15 | 16 | @Override 17 | protected RequestBody buildRequestBody() { 18 | return null; 19 | } 20 | 21 | @Override 22 | protected Request buildRequest(RequestBody requestBody) { 23 | return builder.get().build(); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/OkHttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import com.weexbox.core.okhttp.callback.Callback; 4 | import com.weexbox.core.okhttp.utils.Exceptions; 5 | 6 | import java.util.Map; 7 | 8 | import okhttp3.Headers; 9 | import okhttp3.Request; 10 | import okhttp3.RequestBody; 11 | 12 | /** 13 | * Created by zhy on 15/11/6. 14 | */ 15 | public abstract class OkHttpRequest { 16 | protected String url; 17 | protected Object tag; 18 | protected Map params; 19 | protected Map headers; 20 | protected int id; 21 | 22 | protected Request.Builder builder = new Request.Builder(); 23 | 24 | protected OkHttpRequest(String url, Object tag, 25 | Map params, Map headers, int id) { 26 | this.url = url; 27 | this.tag = tag; 28 | this.params = params; 29 | this.headers = headers; 30 | this.id = id; 31 | 32 | if (url == null) { 33 | Exceptions.illegalArgument("url can not be null."); 34 | } 35 | 36 | initBuilder(); 37 | } 38 | 39 | 40 | /** 41 | * 初始化一些基本参数 url , tag , headers 42 | */ 43 | private void initBuilder() { 44 | builder.url(url).tag(tag); 45 | appendHeaders(); 46 | } 47 | 48 | protected abstract RequestBody buildRequestBody(); 49 | 50 | protected RequestBody wrapRequestBody(RequestBody requestBody, final Callback callback) { 51 | return requestBody; 52 | } 53 | 54 | protected abstract Request buildRequest(RequestBody requestBody); 55 | 56 | public RequestCall build() { 57 | return new RequestCall(this); 58 | } 59 | 60 | 61 | public Request generateRequest(Callback callback) { 62 | RequestBody requestBody = buildRequestBody(); 63 | RequestBody wrappedRequestBody = wrapRequestBody(requestBody, callback); 64 | Request request = buildRequest(wrappedRequestBody); 65 | return request; 66 | } 67 | 68 | 69 | protected void appendHeaders() { 70 | Headers.Builder headerBuilder = new Headers.Builder(); 71 | if (headers == null || headers.isEmpty()) { 72 | return; 73 | } 74 | 75 | for (String key : headers.keySet()) { 76 | headerBuilder.add(key, headers.get(key)); 77 | } 78 | builder.headers(headerBuilder.build()); 79 | } 80 | 81 | public int getId() { 82 | return id; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/OtherRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.weexbox.core.okhttp.OkHttpUtils; 6 | import com.weexbox.core.okhttp.utils.Exceptions; 7 | 8 | import java.util.Map; 9 | 10 | import okhttp3.MediaType; 11 | import okhttp3.Request; 12 | import okhttp3.RequestBody; 13 | import okhttp3.internal.http.HttpMethod; 14 | 15 | /** 16 | * Created by zhy on 16/2/23. 17 | */ 18 | public class OtherRequest extends OkHttpRequest { 19 | private static MediaType MEDIA_TYPE_PLAIN = MediaType.parse("text/plain;charset=utf-8"); 20 | 21 | private RequestBody requestBody; 22 | private String method; 23 | private String content; 24 | 25 | public OtherRequest(RequestBody requestBody, String content, String method, String url, Object tag, Map params, Map headers, int id) { 26 | super(url, tag, params, headers, id); 27 | this.requestBody = requestBody; 28 | this.method = method; 29 | this.content = content; 30 | 31 | } 32 | 33 | @Override 34 | protected RequestBody buildRequestBody() { 35 | if (requestBody == null && TextUtils.isEmpty(content) && HttpMethod.requiresRequestBody(method)) { 36 | Exceptions.illegalArgument("requestBody and content can not be null in method:" + method); 37 | } 38 | 39 | if (requestBody == null && !TextUtils.isEmpty(content)) { 40 | requestBody = RequestBody.create(MEDIA_TYPE_PLAIN, content); 41 | } 42 | 43 | return requestBody; 44 | } 45 | 46 | @Override 47 | protected Request buildRequest(RequestBody requestBody) { 48 | if (method.equals(OkHttpUtils.METHOD.PUT)) { 49 | builder.put(requestBody); 50 | } else if (method.equals(OkHttpUtils.METHOD.DELETE)) { 51 | if (requestBody == null) { 52 | builder.delete(); 53 | } else { 54 | builder.delete(requestBody); 55 | } 56 | } else if (method.equals(OkHttpUtils.METHOD.HEAD)) { 57 | builder.head(); 58 | } else if (method.equals(OkHttpUtils.METHOD.PATCH)) { 59 | builder.patch(requestBody); 60 | } 61 | 62 | return builder.build(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/PostFileRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | import com.weexbox.core.okhttp.callback.Callback; 5 | import com.weexbox.core.okhttp.utils.Exceptions; 6 | 7 | import java.io.File; 8 | import java.util.Map; 9 | 10 | import okhttp3.MediaType; 11 | import okhttp3.Request; 12 | import okhttp3.RequestBody; 13 | 14 | /** 15 | * Created by zhy on 15/12/14. 16 | */ 17 | public class PostFileRequest extends OkHttpRequest { 18 | private static MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream"); 19 | 20 | private File file; 21 | private MediaType mediaType; 22 | 23 | public PostFileRequest(String url, Object tag, Map params, Map headers, File file, MediaType mediaType, int id) { 24 | super(url, tag, params, headers, id); 25 | this.file = file; 26 | this.mediaType = mediaType; 27 | 28 | if (this.file == null) { 29 | Exceptions.illegalArgument("the file can not be null !"); 30 | } 31 | if (this.mediaType == null) { 32 | this.mediaType = MEDIA_TYPE_STREAM; 33 | } 34 | } 35 | 36 | @Override 37 | protected RequestBody buildRequestBody() { 38 | return RequestBody.create(mediaType, file); 39 | } 40 | 41 | @Override 42 | protected RequestBody wrapRequestBody(RequestBody requestBody, final Callback callback) { 43 | if (callback == null) { 44 | return requestBody; 45 | } 46 | CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.Listener() { 47 | @Override 48 | public void onRequestProgress(final long bytesWritten, final long contentLength) { 49 | 50 | OkHttpUtils.getInstance().getDelivery().execute(new Runnable() { 51 | @Override 52 | public void run() { 53 | callback.inProgress(bytesWritten * 1.0f / contentLength, contentLength, id); 54 | } 55 | }); 56 | 57 | } 58 | }); 59 | return countingRequestBody; 60 | } 61 | 62 | @Override 63 | protected Request buildRequest(RequestBody requestBody) { 64 | return builder.post(requestBody).build(); 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/PostFormRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | import com.weexbox.core.okhttp.builder.PostFormBuilder; 5 | import com.weexbox.core.okhttp.callback.Callback; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | import java.net.FileNameMap; 9 | import java.net.URLConnection; 10 | import java.net.URLEncoder; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import okhttp3.FormBody; 15 | import okhttp3.Headers; 16 | import okhttp3.MediaType; 17 | import okhttp3.MultipartBody; 18 | import okhttp3.Request; 19 | import okhttp3.RequestBody; 20 | 21 | /** 22 | * Created by zhy on 15/12/14. 23 | */ 24 | public class PostFormRequest extends OkHttpRequest { 25 | private List files; 26 | 27 | public PostFormRequest(String url, Object tag, Map params, Map headers, List files, int id) { 28 | super(url, tag, params, headers, id); 29 | this.files = files; 30 | } 31 | 32 | @Override 33 | protected RequestBody buildRequestBody() { 34 | if (files == null || files.isEmpty()) { 35 | FormBody.Builder builder = new FormBody.Builder(); 36 | addParams(builder); 37 | FormBody formBody = builder.build(); 38 | return formBody; 39 | } else { 40 | MultipartBody.Builder builder = new MultipartBody.Builder() 41 | .setType(MultipartBody.FORM); 42 | addParams(builder); 43 | 44 | for (int i = 0; i < files.size(); i++) { 45 | PostFormBuilder.FileInput fileInput = files.get(i); 46 | RequestBody fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileInput.filename)), fileInput.file); 47 | builder.addFormDataPart(fileInput.key, fileInput.filename, fileBody); 48 | } 49 | return builder.build(); 50 | } 51 | } 52 | 53 | @Override 54 | protected RequestBody wrapRequestBody(RequestBody requestBody, final Callback callback) { 55 | if (callback == null) { 56 | return requestBody; 57 | } 58 | CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.Listener() { 59 | @Override 60 | public void onRequestProgress(final long bytesWritten, final long contentLength) { 61 | 62 | OkHttpUtils.getInstance().getDelivery().execute(new Runnable() { 63 | @Override 64 | public void run() { 65 | callback.inProgress(bytesWritten * 1.0f / contentLength, contentLength, id); 66 | } 67 | }); 68 | 69 | } 70 | }); 71 | return countingRequestBody; 72 | } 73 | 74 | @Override 75 | protected Request buildRequest(RequestBody requestBody) { 76 | return builder.post(requestBody).build(); 77 | } 78 | 79 | private String guessMimeType(String path) { 80 | FileNameMap fileNameMap = URLConnection.getFileNameMap(); 81 | String contentTypeFor = null; 82 | try { 83 | contentTypeFor = fileNameMap.getContentTypeFor(URLEncoder.encode(path, "UTF-8")); 84 | } catch (UnsupportedEncodingException e) { 85 | e.printStackTrace(); 86 | } 87 | if (contentTypeFor == null) { 88 | contentTypeFor = "application/octet-stream"; 89 | } 90 | return contentTypeFor; 91 | } 92 | 93 | private void addParams(MultipartBody.Builder builder) { 94 | if (params != null && !params.isEmpty()) { 95 | for (String key : params.keySet()) { 96 | builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""), 97 | RequestBody.create(null, params.get(key))); 98 | } 99 | } 100 | } 101 | 102 | private void addParams(FormBody.Builder builder) { 103 | if (params != null) { 104 | for (String key : params.keySet()) { 105 | builder.add(key, params.get(key)); 106 | } 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/PostStringRequest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import com.weexbox.core.okhttp.utils.Exceptions; 4 | 5 | import java.util.Map; 6 | 7 | import okhttp3.MediaType; 8 | import okhttp3.Request; 9 | import okhttp3.RequestBody; 10 | 11 | /** 12 | * Created by zhy on 15/12/14. 13 | */ 14 | public class PostStringRequest extends OkHttpRequest { 15 | private static MediaType MEDIA_TYPE_PLAIN = MediaType.parse("text/plain;charset=utf-8"); 16 | 17 | private String content; 18 | private MediaType mediaType; 19 | 20 | 21 | public PostStringRequest(String url, Object tag, Map params, Map headers, String content, MediaType mediaType, int id) { 22 | super(url, tag, params, headers, id); 23 | this.content = content; 24 | this.mediaType = mediaType; 25 | 26 | if (this.content == null) { 27 | Exceptions.illegalArgument("the content can not be null !"); 28 | } 29 | if (this.mediaType == null) { 30 | this.mediaType = MEDIA_TYPE_PLAIN; 31 | } 32 | 33 | } 34 | 35 | @Override 36 | protected RequestBody buildRequestBody() { 37 | return RequestBody.create(mediaType, content); 38 | } 39 | 40 | @Override 41 | protected Request buildRequest(RequestBody requestBody) { 42 | return builder.post(requestBody).build(); 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/request/RequestCall.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.request; 2 | 3 | import com.weexbox.core.okhttp.OkHttpUtils; 4 | import com.weexbox.core.okhttp.callback.Callback; 5 | 6 | import java.io.IOException; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import okhttp3.Call; 10 | import okhttp3.OkHttpClient; 11 | import okhttp3.Request; 12 | import okhttp3.Response; 13 | 14 | /** 15 | * Created by zhy on 15/12/15. 16 | * 对OkHttpRequest的封装,对外提供更多的接口:cancel(),readTimeOut()... 17 | */ 18 | public class RequestCall { 19 | private OkHttpRequest okHttpRequest; 20 | private Request request; 21 | private Call call; 22 | 23 | private long readTimeOut; 24 | private long writeTimeOut; 25 | private long connTimeOut; 26 | 27 | private OkHttpClient clone; 28 | 29 | public RequestCall(OkHttpRequest request) { 30 | this.okHttpRequest = request; 31 | } 32 | 33 | public RequestCall readTimeOut(long readTimeOut) { 34 | this.readTimeOut = readTimeOut; 35 | return this; 36 | } 37 | 38 | public RequestCall writeTimeOut(long writeTimeOut) { 39 | this.writeTimeOut = writeTimeOut; 40 | return this; 41 | } 42 | 43 | public RequestCall connTimeOut(long connTimeOut) { 44 | this.connTimeOut = connTimeOut; 45 | return this; 46 | } 47 | 48 | public Call buildCall(Callback callback) { 49 | request = generateRequest(callback); 50 | 51 | if (readTimeOut > 0 || writeTimeOut > 0 || connTimeOut > 0) { 52 | readTimeOut = readTimeOut > 0 ? readTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; 53 | writeTimeOut = writeTimeOut > 0 ? writeTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; 54 | connTimeOut = connTimeOut > 0 ? connTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS; 55 | 56 | clone = OkHttpUtils.getInstance().getOkHttpClient().newBuilder() 57 | .readTimeout(readTimeOut, TimeUnit.MILLISECONDS) 58 | .writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS) 59 | .connectTimeout(connTimeOut, TimeUnit.MILLISECONDS) 60 | .build(); 61 | 62 | call = clone.newCall(request); 63 | } else { 64 | call = OkHttpUtils.getInstance().getOkHttpClient().newCall(request); 65 | } 66 | return call; 67 | } 68 | 69 | private Request generateRequest(Callback callback) { 70 | return okHttpRequest.generateRequest(callback); 71 | } 72 | 73 | public void execute(Callback callback) { 74 | buildCall(callback); 75 | 76 | if (callback != null) { 77 | callback.onBefore(request, getOkHttpRequest().getId()); 78 | } 79 | 80 | OkHttpUtils.getInstance().execute(this, callback); 81 | } 82 | 83 | public Call getCall() { 84 | return call; 85 | } 86 | 87 | public Request getRequest() { 88 | return request; 89 | } 90 | 91 | public OkHttpRequest getOkHttpRequest() { 92 | return okHttpRequest; 93 | } 94 | 95 | public Response execute() throws IOException { 96 | buildCall(null); 97 | return call.execute(); 98 | } 99 | 100 | public void cancel() { 101 | if (call != null) { 102 | call.cancel(); 103 | } 104 | } 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/utils/Exceptions.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.utils; 2 | 3 | /** 4 | * Created by zhy on 15/12/14. 5 | */ 6 | public class Exceptions { 7 | public static void illegalArgument(String msg, Object... params) { 8 | throw new IllegalArgumentException(String.format(msg, params)); 9 | } 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/utils/L.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.okhttp.utils; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * Created by zhy on 15/11/6. 7 | */ 8 | public class L { 9 | private static boolean debug = false; 10 | 11 | public static void e(String msg) { 12 | if (debug) { 13 | Log.e("OkHttp", msg); 14 | } 15 | } 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/okhttp/utils/Platform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.weexbox.core.okhttp.utils; 17 | 18 | import android.os.Build; 19 | import android.os.Handler; 20 | import android.os.Looper; 21 | 22 | import java.util.concurrent.Executor; 23 | import java.util.concurrent.Executors; 24 | 25 | public class Platform { 26 | private static final Platform PLATFORM = findPlatform(); 27 | 28 | public static Platform get() { 29 | L.e(PLATFORM.getClass().toString()); 30 | return PLATFORM; 31 | } 32 | 33 | private static Platform findPlatform() { 34 | try { 35 | Class.forName("android.os.Build"); 36 | if (Build.VERSION.SDK_INT != 0) { 37 | return new Android(); 38 | } 39 | } catch (ClassNotFoundException ignored) { 40 | } 41 | return new Platform(); 42 | } 43 | 44 | public Executor defaultCallbackExecutor() { 45 | return Executors.newCachedThreadPool(); 46 | } 47 | 48 | public void execute(Runnable runnable) { 49 | defaultCallbackExecutor().execute(runnable); 50 | } 51 | 52 | 53 | static class Android extends Platform { 54 | @Override 55 | public Executor defaultCallbackExecutor() { 56 | return new MainThreadExecutor(); 57 | } 58 | 59 | static class MainThreadExecutor implements Executor { 60 | private final Handler handler = new Handler(Looper.getMainLooper()); 61 | 62 | @Override 63 | public void execute(Runnable r) { 64 | handler.post(r); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/AES128Util.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.util.Base64; 4 | 5 | import javax.crypto.Cipher; 6 | import javax.crypto.spec.SecretKeySpec; 7 | 8 | /** 9 | * Author:leon.wen 10 | * Time:2018/10/10 11:23 11 | * Description:This is AES128Util 12 | */ 13 | public class AES128Util { 14 | 15 | private static final String UTF_8 = "UTF-8"; 16 | 17 | /** 18 | * 加密 19 | * 20 | * @param src 需要加密的内容 21 | * @param key 加密密码 22 | * @return 23 | */ 24 | public static String encrypt(String key, String src) { 25 | try { 26 | if (key == null || key.length() <= 0 || src == null || src.length() <= 0) { 27 | return null; 28 | } 29 | SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES"); 30 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); 31 | byte[] byteContent = src.getBytes(UTF_8); 32 | cipher.init(Cipher.ENCRYPT_MODE, skey);// 初始化 33 | byte[] result = cipher.doFinal(byteContent); 34 | String resultStr = byte2Base64(result); 35 | return resultStr; 36 | } catch (Exception ext) { 37 | ext.printStackTrace(); 38 | } 39 | return null; 40 | } 41 | 42 | /** 43 | * 解密 44 | * * @param String src 解密字符串 45 | * * @param String key 密钥 46 | * * @return 解密后的字符串 47 | */ 48 | public static String decrypt(String key, String src) { 49 | try { // 判断Key是否正确 50 | if (key == null || key.length() <= 0 || src == null || src.length() <= 0) { 51 | return null; 52 | } 53 | SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES"); 54 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); 55 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 56 | byte[] encrypted1 = Base64.decode(src, Base64.NO_WRAP); 57 | //byte[] encrypted1 = src.getBytes(UTF_8); 58 | try { 59 | byte[] original = cipher.doFinal(encrypted1); 60 | String originalString = new String(original, "utf-8"); 61 | return originalString; 62 | } catch (Exception e) { 63 | System.out.println(e.toString()); 64 | return null; 65 | } 66 | } catch (Exception ex) { 67 | System.out.println(ex.toString()); 68 | return null; 69 | } 70 | } 71 | 72 | private static String byte2Base64(byte[] encode) { 73 | try { 74 | return Base64.encodeToString(encode, Base64.NO_WRAP); 75 | } catch (Exception ext) { 76 | ext.printStackTrace(); 77 | } 78 | return null; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/ActivityManager.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.app.Activity; 4 | 5 | import java.util.Stack; 6 | 7 | public final class ActivityManager { 8 | 9 | /** 10 | * Activity记录栈 11 | */ 12 | private static Stack activityStack = new Stack(); 13 | /** 14 | * AppManager单例 15 | */ 16 | private static ActivityManager singleton = new ActivityManager(); 17 | 18 | /** 19 | * 单例 20 | */ 21 | private ActivityManager() { 22 | } 23 | 24 | /** 25 | * 获取AppManager单一实例 26 | */ 27 | public static ActivityManager getInstance() { 28 | return singleton; 29 | } 30 | 31 | /** 32 | * 添加Activity到堆栈 33 | */ 34 | public void addActivity(Activity activity) { 35 | activityStack.add(activity); 36 | } 37 | 38 | /** 39 | * 获取当前Activity(堆栈中最后一个压入的) 40 | */ 41 | public Activity currentActivity() { 42 | if (activityStack.isEmpty()) { 43 | return null; 44 | } 45 | Activity activity = activityStack.lastElement(); 46 | return activity; 47 | } 48 | 49 | /** 50 | * 结束当前Activity(堆栈中最后一个压入的) 51 | */ 52 | public void finishActivity() { 53 | if (activityStack.isEmpty()) { 54 | return; 55 | } 56 | Activity activity = activityStack.lastElement(); 57 | finishActivity(activity); 58 | } 59 | 60 | /** 61 | * 结束指定类名的Activity 62 | */ 63 | public Activity getFirstActivity() { 64 | if (activityStack.isEmpty()) { 65 | return null; 66 | } 67 | return activityStack.firstElement(); 68 | } 69 | 70 | /** 71 | * 结束指定类名的Activity 72 | */ 73 | public Activity getActivity(Class cls) { 74 | if (activityStack.isEmpty()) { 75 | return null; 76 | } 77 | for (Activity activity : activityStack) { 78 | if (activity.getClass().equals(cls)) { 79 | return activity; 80 | } 81 | } 82 | return null; 83 | } 84 | 85 | /** 86 | * 结束指定的Activity 87 | */ 88 | public void finishActivity(Activity activity) { 89 | if (activityStack.isEmpty()) { 90 | return; 91 | } 92 | if (activity != null) { 93 | activityStack.remove(activity); 94 | activity.finish(); 95 | activity = null; 96 | } 97 | } 98 | 99 | /** 100 | * 移除指定的Activity 101 | */ 102 | public void removeActivity(Activity activity) { 103 | if (activityStack.isEmpty()) { 104 | return; 105 | } 106 | if (activity != null) { 107 | activityStack.remove(activity); 108 | activity = null; 109 | } 110 | } 111 | 112 | /** 113 | * 结束指定类名的Activity 114 | */ 115 | public void finishActivity(Class cls) { 116 | if (activityStack.isEmpty()) { 117 | return; 118 | } 119 | for (Activity activity : activityStack) { 120 | if (activity.getClass().equals(cls)) { 121 | finishActivity(activity); 122 | } 123 | } 124 | } 125 | 126 | /** 127 | * 结束所有Activity除了 128 | */ 129 | public void finishAllActivityExcept(Activity activity) { 130 | if (activityStack.isEmpty()) { 131 | return; 132 | } 133 | for (Activity temp : activityStack) { 134 | if (null != temp && temp != activity) { 135 | temp.finish(); 136 | } 137 | } 138 | } 139 | 140 | /** 141 | * 结束所有Activity 142 | */ 143 | public void finishAllActivity() { 144 | if (activityStack.isEmpty()) { 145 | return; 146 | } 147 | for (int i = 0, size = activityStack.size(); i < size; i++) { 148 | if (null != activityStack.get(i)) { 149 | activityStack.get(i).finish(); 150 | } 151 | } 152 | activityStack.clear(); 153 | } 154 | 155 | public Stack getAllActivities() { 156 | return activityStack; 157 | } 158 | 159 | /** 160 | * 退出应用程序 161 | */ 162 | public void exitApplication() { 163 | // try { 164 | // ReleaseResourcesUtil.releaseResources(); 165 | // finishAllActivity(); 166 | // } catch (Exception e) { 167 | // Log.e("ActivityManager", "退出应用失败"); 168 | // } finally { 169 | // System.exit(0); 170 | // } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/DeviceUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.content.Context; 4 | 5 | public class DeviceUtil { 6 | 7 | /** 8 | * 获取状态栏高度 9 | * 10 | * @param context 11 | * @return 12 | */ 13 | public static int getStatusBarHeight(Context context) { 14 | int result = 0; 15 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); 16 | if (resourceId > 0) { 17 | result = context.getResources().getDimensionPixelSize(resourceId); 18 | } 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/DisplayUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Rect; 6 | import android.util.DisplayMetrics; 7 | 8 | public class DisplayUtil { 9 | 10 | /** 11 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 12 | */ 13 | public static int dip2px(Context context, float dpValue) { 14 | final float scale = context.getResources().getDisplayMetrics().density; 15 | return (int) (dpValue * scale + 0.5f); 16 | } 17 | 18 | /** 19 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 20 | */ 21 | public static int px2dip(Context context, float pxValue) { 22 | final float scale = context.getResources().getDisplayMetrics().density; 23 | return (int) (pxValue / scale + 0.5f); 24 | } 25 | 26 | /** 27 | * 将px值转换为sp值,保证文字大小不变 28 | * 29 | * @param pxValue 30 | * @param pxValue 31 | * (DisplayMetrics类中属性scaledDensity) 32 | * @return 33 | */ 34 | public static int px2sp(Context context, float pxValue) { 35 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 36 | return (int) (pxValue / fontScale + 0.5f); 37 | } 38 | 39 | /** 40 | * 将sp值转换为px值,保证文字大小不变 41 | * 42 | * @param spValue 43 | * @param spValue 44 | * (DisplayMetrics类中属性scaledDensity) 45 | * @return 46 | */ 47 | public static int sp2px(Context context, float spValue) { 48 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 49 | return (int) (spValue * fontScale + 0.5f); 50 | } 51 | 52 | /** 53 | * 得到的屏幕的宽度 54 | */ 55 | public static int getWidthPx(Activity activity) { 56 | 57 | DisplayMetrics displaysMetrics = new DisplayMetrics(); 58 | activity.getWindowManager().getDefaultDisplay().getMetrics(displaysMetrics); 59 | return displaysMetrics.widthPixels; 60 | } 61 | 62 | /** 63 | * 得到的屏幕的高度 64 | */ 65 | public static int getHeightPx(Activity activity) { 66 | DisplayMetrics displaysMetrics = new DisplayMetrics(); 67 | activity.getWindowManager().getDefaultDisplay().getMetrics(displaysMetrics); 68 | return displaysMetrics.heightPixels; 69 | } 70 | 71 | /** 72 | * 得到屏幕的dpi 73 | * @param activity 74 | * @return 75 | */ 76 | public static int getDensityDpi(Activity activity) { 77 | 78 | DisplayMetrics displaysMetrics = new DisplayMetrics(); 79 | activity.getWindowManager().getDefaultDisplay().getMetrics(displaysMetrics); 80 | return displaysMetrics.densityDpi; 81 | } 82 | 83 | /** 84 | * 返回状态栏/通知栏的高度 85 | * 86 | * @param activity 87 | * @return 88 | */ 89 | public static int getStatusHeight(Activity activity) { 90 | Rect frame = new Rect(); 91 | activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); 92 | int statusBarHeight = frame.top; 93 | return statusBarHeight; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/HotReload.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util 2 | 3 | import com.weexbox.core.WeexBoxEngine 4 | import com.weexbox.core.event.Event 5 | import com.weexbox.core.extension.toJsonMap 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.MainScope 8 | import kotlinx.coroutines.delay 9 | import kotlinx.coroutines.launch 10 | import okhttp3.* 11 | 12 | 13 | /** 14 | * Author: Mario 15 | * Time: 2019/4/13 2:26 PM 16 | * Description: This is HotReload 17 | */ 18 | 19 | object HotReload { 20 | 21 | private var isConnect = false 22 | var url: String? = null 23 | private val listener = object : WebSocketListener() { 24 | 25 | override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { 26 | connect() 27 | } 28 | 29 | override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { 30 | connect() 31 | } 32 | 33 | override fun onMessage(webSocket: WebSocket, text: String) { 34 | val option = text.toJsonMap() 35 | val method = option["method"] as String 36 | if (method == "WXReloadBundle") { 37 | Event.emit(method, option) 38 | } 39 | } 40 | 41 | override fun onOpen(webSocket: WebSocket, response: Response) { 42 | MainScope().launch { 43 | ToastUtil.showLongToast(WeexBoxEngine.application, "热重载开启") 44 | } 45 | } 46 | } 47 | 48 | fun open(url: String) { 49 | HotReload.url = url 50 | connect() 51 | } 52 | 53 | fun connect() { 54 | if (isConnect) { 55 | return 56 | } 57 | isConnect = true 58 | GlobalScope.launch { 59 | delay(2000) 60 | isConnect = false 61 | val okHttpClient = OkHttpClient.Builder().build() 62 | val request = Request.Builder().url(url!!).build() 63 | okHttpClient.newWebSocket(request, listener) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/LogUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.content.Context; 4 | 5 | import com.orhanobut.logger.Logger; 6 | 7 | public final class LogUtil { 8 | 9 | private LogUtil() { 10 | /* Protect from instantiations */ 11 | } 12 | 13 | public static void init(Context context) { 14 | } 15 | 16 | public static boolean isDebuggable() { 17 | return true; 18 | } 19 | 20 | public static void e(String message, Object... params) { 21 | if (!isDebuggable()) { 22 | return; 23 | } 24 | Logger.e(message, params); 25 | } 26 | 27 | public static void i(String message, Object... params) { 28 | if (!isDebuggable()) { 29 | return; 30 | } 31 | Logger.i(message, params); 32 | 33 | } 34 | 35 | public static void d(String message, Object... params) { 36 | if (!isDebuggable()) { 37 | return; 38 | } 39 | Logger.d(message, params); 40 | 41 | } 42 | 43 | public static void v(String message, Object... params) { 44 | if (!isDebuggable()) { 45 | return; 46 | } 47 | Logger.v(message, params); 48 | 49 | } 50 | 51 | public static void w(String message, Object... params) { 52 | if (!isDebuggable()) { 53 | return; 54 | } 55 | Logger.w(message, params); 56 | 57 | } 58 | 59 | public static void wtf(String message, Object... params) { 60 | if (!isDebuggable()) { 61 | return; 62 | } 63 | Logger.wtf(message, params); 64 | 65 | } 66 | 67 | public static void json(String json) { 68 | if (!isDebuggable()) { 69 | return; 70 | } 71 | Logger.json(json); 72 | 73 | } 74 | 75 | public static void xml(String xml) { 76 | if (!isDebuggable()) { 77 | return; 78 | } 79 | Logger.xml(xml); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/StatusBarUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | 10 | /** 11 | * Author:leon.wen 12 | * Time:2018/8/2 15:54 13 | * Description:This is StatusBarUtil 14 | */ 15 | public class StatusBarUtil { 16 | 17 | /** 18 | * 通过设置全屏,设置状态栏透明 19 | * 20 | * @param activity 21 | */ 22 | public static void fullScreen(Activity activity) { 23 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 24 | Window window = activity.getWindow(); 25 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 26 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 27 | window.setStatusBarColor(Color.TRANSPARENT); 28 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/TaskManager.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.AsyncTask; 5 | import android.os.Handler; 6 | import android.os.HandlerThread; 7 | import android.os.Looper; 8 | 9 | /** 10 | * 线程,异步任务,异步线程池管理 11 | * 12 | * Created by masanbing on 15-11-17. 13 | */ 14 | public class TaskManager { 15 | 16 | /** 工作线程,用于处理时间比较长的异步任务,该线程相对普通线程会创建一个looper */ 17 | private static HandlerThread sWorkerThread = new HandlerThread("work_thread"); 18 | static { 19 | sWorkerThread.start(); 20 | } 21 | /** 在sWorkerThread创建一个handler */ 22 | private static Handler sWorkHandler = new Handler(sWorkerThread.getLooper()); 23 | 24 | /** 在ui主线程上创建一个handler */ 25 | private static Handler sUIHandler = new Handler(Looper.getMainLooper()); 26 | 27 | /** 28 | *
提交一个Runable到work_thread线程上 29 | *
注:所有数据库操作都必须在该数据库线程上执行 30 | *
需要串行,避免互斥访问的任务也可提交到该工作线程上运行 31 | * 32 | * @param r 33 | */ 34 | public static void execWorkTask(Runnable r) { 35 | if (r == null) { 36 | return; 37 | } 38 | sWorkHandler.post(r); 39 | } 40 | 41 | /** 42 | * post 一个delay 的runnable 到work_thread线程 43 | *
注:所有数据库操作都必须在该数据库线程上执行 44 | *
需要串行,避免互斥访问的任务也可提交到该工作线程上运行 45 | * @param r 46 | * @param delay 47 | */ 48 | public static void execWorkTaskDelay(Runnable r, long delay) { 49 | if (r == null || sWorkHandler == null) { 50 | return; 51 | } 52 | 53 | if (delay > 0) { 54 | sWorkHandler.postDelayed(r, delay); 55 | } else { 56 | execWorkTask(r); 57 | } 58 | } 59 | 60 | /** 61 | * 移除work_thread一个runnable任务 62 | * @param r 63 | */ 64 | public static void removeWorkTask(Runnable r) { 65 | if (r == null || sWorkHandler == null) { 66 | return; 67 | } 68 | sWorkHandler.removeCallbacks(r); 69 | } 70 | 71 | /**
功能简述:提交一个异步任务到异步线程池 72 | *
功能详细描述:在异步任务线程池中选一个空闲的线程执行该异步任务 73 | *
注意:若第一次执行异步任务,将会创建一个异步任务线程池 74 | *
一些独立的,耗时的,非数据库操作的后台任务可以提交到异步线程池执行 75 | * @param r 76 | */ 77 | @SuppressLint("NewApi") 78 | public static void execAsynTask(Runnable r) { 79 | if (r == null) { 80 | return; 81 | } 82 | 83 | AsyncTask.THREAD_POOL_EXECUTOR.execute(r); 84 | } 85 | 86 | /**
功能简述:执行一个异步任务 87 | *
功能详细描述:在异步任务线程池中选一个空闲的线程执行该异步任务 88 | *
注意:由于AsynTask没有延时功能,到达延时时间后由work thread线程去发起该异步任务 89 | *
一些独立的,耗时的,非数据库操作的后台任务可以提交到异步线程池执行 90 | * @param r 91 | * @param delay 92 | */ 93 | @SuppressLint("NewApi") 94 | public static void execAsynTaskDelay(final Runnable r, long delay) { 95 | if (r == null || sWorkHandler == null) { 96 | return; 97 | } 98 | 99 | if (delay > 0) { 100 | sWorkHandler.postDelayed(new Runnable() { 101 | @Override 102 | public void run() { 103 | AsyncTask.THREAD_POOL_EXECUTOR.execute(r); 104 | } 105 | }, delay); 106 | } else { 107 | AsyncTask.THREAD_POOL_EXECUTOR.execute(r); 108 | } 109 | } 110 | 111 | /**
功能简述:在ui线程上执行一个任务 112 | *
功能详细描述:该任务并非在一个新的线程上执行,而是提交一个异步任务到ui线程任务队列 113 | *
注意:因为ui线程耗时过长会报anr异常,所以提交的任务避免耗时的后台操作 114 | * @param r 115 | */ 116 | public static void execTaskOnUIThread(Runnable r) { 117 | sUIHandler.post(r); 118 | } 119 | 120 | /**
功能简述:延迟一段时间在ui线程上执行任务 121 | *
功能详细描述::该任务并非在一个新的线程上执行,而是提交一个异步任务到ui线程任务队列 122 | *
注意:因为ui线程耗时过长会报anr异常,所以提交的任务避免耗时的后台操作 123 | * @param r ui任务 124 | * @param delay 任务延时时间 125 | */ 126 | public static void execTaskOnUIThreadDelay(Runnable r, long delay) { 127 | sUIHandler.postDelayed(r, delay); 128 | } 129 | 130 | public static void removeUITask(Runnable r) { 131 | sUIHandler.removeCallbacks(r); 132 | } 133 | 134 | /**
功能简述:确保运行在主线程断言 135 | *
功能详细描述: 136 | *
注意: 137 | */ 138 | public static void assertMainThread() { 139 | if (Looper.getMainLooper().getThread() != Thread.currentThread()) { 140 | throw new IllegalStateException("Must be called on the main thread."); 141 | } 142 | } 143 | 144 | /**
功能简述:确保运行在工作线程断言 145 | *
功能详细描述: 146 | *
注意: 147 | */ 148 | public static void assertWorkThread() { 149 | if (sWorkerThread != Thread.currentThread()) { 150 | throw new IllegalStateException("Must be called on the work thread."); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.util; 2 | 3 | import android.content.Context; 4 | import android.view.Gravity; 5 | import android.widget.Toast; 6 | 7 | /** 8 | * Created by freeson on 16/8/4. 9 | */ 10 | public final class ToastUtil { 11 | 12 | public static void showShortToast(final Context context, final String text) { 13 | Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT); 14 | toast.setGravity(Gravity.CENTER, 0, 0); 15 | toast.show(); 16 | } 17 | 18 | public static void showShortToast(final Context context, final int textId) { 19 | Toast toast = Toast.makeText(context, textId, Toast.LENGTH_SHORT); 20 | toast.setGravity(Gravity.CENTER, 0, 0); 21 | toast.show(); 22 | } 23 | 24 | public static void showLongToast(final Context context, final String text) { 25 | Toast toast = Toast.makeText(context, text, Toast.LENGTH_LONG); 26 | toast.setGravity(Gravity.CENTER, 0, 0); 27 | toast.show(); 28 | } 29 | 30 | public static void showLongToast(final Context context, final int textId) { 31 | Toast toast = Toast.makeText(context, textId, Toast.LENGTH_LONG); 32 | toast.setGravity(Gravity.CENTER, 0, 0); 33 | toast.show(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/util/VersionUtil.kt: -------------------------------------------------------------------------------- 1 | import android.content.pm.PackageManager 2 | import android.os.Build 3 | import com.weexbox.core.WeexBoxEngine 4 | 5 | object VersionUtil { 6 | 7 | val hasJellyBeanMR2 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 8 | 9 | val hasHoneycomb = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB 10 | 11 | val hasJellyBean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN 12 | 13 | val hasJellyBeanMR1 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 14 | 15 | val hasKitkat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT 16 | 17 | val hasLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP 18 | 19 | val hasM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M 20 | 21 | /** 22 | * 获取版本号 23 | 24 | * @return 当前应用的版本号 25 | */ 26 | val appVersionName: String? 27 | get() { 28 | val manager = WeexBoxEngine.application.packageManager 29 | try { 30 | val info = manager.getPackageInfo(WeexBoxEngine.application.packageName, 0) 31 | val version = info.versionName 32 | return version 33 | } catch (e: PackageManager.NameNotFoundException) { 34 | 35 | } 36 | 37 | return null 38 | } 39 | 40 | /** 41 | * 比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0 42 | 43 | * @param version1 44 | * * 45 | * @param version2 46 | * * 47 | * @return 48 | */ 49 | fun compareVersion(v1: String?, v2: String?): Int { 50 | val version1 = v1 ?: "0" 51 | val version2 = v2 ?: "0" 52 | val versionArray1: List = version1.split(".")//kotlin 中不需要正则匹配,不用如此"\\."; 53 | val versionArray2: List = version2.split(".") 54 | var idx = 0 55 | val minLength = Math.min(versionArray1.size, versionArray2.size)//取最小长度值 56 | var diff = 0 57 | while (idx < minLength) { 58 | diff = versionArray1[idx].length - versionArray2[idx].length//先比较长度 59 | if (diff == 0) { 60 | diff = versionArray1[idx].compareTo(versionArray2[idx])//再比较字符 61 | if (diff == 0) { 62 | ++idx 63 | } else { 64 | break 65 | } 66 | } else { 67 | break 68 | } 69 | } 70 | //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大; 71 | diff = if (diff != 0) diff else versionArray1.size - versionArray2.size 72 | return diff 73 | } 74 | } -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/webview/SonicJavaScriptInterface.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.webview; 2 | 3 | import android.content.Intent; 4 | import android.os.Handler; 5 | import android.os.Looper; 6 | import android.webkit.JavascriptInterface; 7 | 8 | import com.alibaba.fastjson.JSONObject; 9 | import com.tencent.sonic.sdk.SonicDiffDataCallback; 10 | 11 | /** 12 | * Author:leon.wen 13 | * Time:2018/10/20 12:05 14 | * Description:This is SonicJavaScriptInterface 15 | */ 16 | public class SonicJavaScriptInterface { 17 | 18 | public static final String PARAM_CLICK_TIME = "clickTime"; 19 | public static final String PARAM_LOAD_URL_TIME = "loadUrlTime"; 20 | private final SonicSessionClientImpl sessionClient; 21 | private final Intent intent; 22 | 23 | public SonicJavaScriptInterface(SonicSessionClientImpl sessionClient, Intent intent) { 24 | this.sessionClient = sessionClient; 25 | this.intent = intent; 26 | } 27 | 28 | /* 29 | * * From RFC 4627, "All Unicode characters may be placed within the quotation marks except 30 | * for the characters that must be escaped: quotation mark, 31 | * reverse solidus, and the control characters (U+0000 through U+001F)." 32 | */ 33 | private static String toJsString(String value) { 34 | if (value == null) { 35 | return "null"; 36 | } 37 | StringBuilder out = new StringBuilder(1024); 38 | for (int i = 0, length = value.length(); i < length; i++) { 39 | char c = value.charAt(i); 40 | 41 | 42 | switch (c) { 43 | case '"': 44 | case '\\': 45 | case '/': 46 | out.append('\\').append(c); 47 | break; 48 | 49 | case '\t': 50 | out.append("\\t"); 51 | break; 52 | 53 | case '\b': 54 | out.append("\\b"); 55 | break; 56 | 57 | case '\n': 58 | out.append("\\n"); 59 | break; 60 | 61 | case '\r': 62 | out.append("\\r"); 63 | break; 64 | 65 | case '\f': 66 | out.append("\\f"); 67 | break; 68 | 69 | default: 70 | if (c <= 0x1F) { 71 | out.append(String.format("\\u%04x", (int) c)); 72 | } else { 73 | out.append(c); 74 | } 75 | break; 76 | } 77 | 78 | } 79 | return out.toString(); 80 | } 81 | 82 | @JavascriptInterface 83 | public void getDiffData() { 84 | // the callback function of demo page is hardcode as 'getDiffDataCallback' 85 | getDiffData2("getDiffDataCallback"); 86 | } 87 | 88 | @JavascriptInterface 89 | public void getDiffData2(final String jsCallbackFunc) { 90 | if (null != sessionClient) { 91 | sessionClient.getDiffData(new SonicDiffDataCallback() { 92 | @Override 93 | public void callback(final String resultData) { 94 | Runnable callbackRunnable = new Runnable() { 95 | @Override 96 | public void run() { 97 | String jsCode = "javascript:" + jsCallbackFunc + "('" + toJsString(resultData) + "')"; 98 | sessionClient.getWebView().loadUrl(jsCode); 99 | } 100 | }; 101 | if (Looper.getMainLooper() == Looper.myLooper()) { 102 | callbackRunnable.run(); 103 | } else { 104 | new Handler(Looper.getMainLooper()).post(callbackRunnable); 105 | } 106 | } 107 | }); 108 | } 109 | } 110 | 111 | @JavascriptInterface 112 | public String getPerformance() { 113 | long clickTime = intent.getLongExtra(PARAM_CLICK_TIME, -1); 114 | long loadUrlTime = intent.getLongExtra(PARAM_LOAD_URL_TIME, -1); 115 | try { 116 | JSONObject result = new JSONObject(); 117 | result.put(PARAM_CLICK_TIME, clickTime); 118 | result.put(PARAM_LOAD_URL_TIME, loadUrlTime); 119 | return result.toString(); 120 | } catch (Exception e) { 121 | 122 | } 123 | 124 | return ""; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/webview/SonicRuntimeImpl.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.webview; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | import android.webkit.CookieManager; 8 | import android.webkit.WebResourceResponse; 9 | 10 | import com.tencent.sonic.sdk.SonicRuntime; 11 | import com.tencent.sonic.sdk.SonicSessionClient; 12 | 13 | import java.io.File; 14 | import java.io.InputStream; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * Author:leon.wen 20 | * Time:2018/10/19 18:25 21 | * Description:This is SonicRuntimeImpl 22 | */ 23 | public class SonicRuntimeImpl extends SonicRuntime { 24 | 25 | public static String Ua = ""; 26 | public static String userId = ""; 27 | 28 | public SonicRuntimeImpl(Context context) { 29 | super(context); 30 | } 31 | 32 | @Override 33 | public String getUserAgent() { 34 | return Ua; 35 | } 36 | 37 | @Override 38 | public String getCurrentUserAccount() { 39 | return userId; 40 | } 41 | 42 | @Override 43 | public String getCookie(String url) { 44 | CookieManager cookieManager = CookieManager.getInstance(); 45 | return cookieManager.getCookie(url); 46 | } 47 | 48 | @Override 49 | public void log(String tag, int level, String message) { 50 | switch (level) { 51 | case Log.ERROR: 52 | Log.e(tag, message); 53 | break; 54 | case Log.INFO: 55 | Log.i(tag, message); 56 | break; 57 | default: 58 | Log.d(tag, message); 59 | } 60 | } 61 | 62 | @Override 63 | public Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map headers) { 64 | WebResourceResponse resourceResponse = new WebResourceResponse(mimeType, encoding, data); 65 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 66 | resourceResponse.setResponseHeaders(headers); 67 | } 68 | return resourceResponse; 69 | } 70 | 71 | @Override 72 | public void showToast(CharSequence text, int duration) { 73 | 74 | } 75 | 76 | @Override 77 | public void notifyError(SonicSessionClient client, String url, int errorCode) { 78 | 79 | } 80 | 81 | @Override 82 | public boolean isSonicUrl(String url) { 83 | return true; 84 | } 85 | 86 | @Override 87 | public boolean setCookie(String url, List cookies) { 88 | if (!TextUtils.isEmpty(url) && cookies != null && cookies.size() > 0) { 89 | CookieManager cookieManager = CookieManager.getInstance(); 90 | for (String cookie : cookies) { 91 | cookieManager.setCookie(url, cookie); 92 | } 93 | return true; 94 | } 95 | return false; 96 | } 97 | 98 | @Override 99 | public boolean isNetworkValid() { 100 | return true; 101 | } 102 | 103 | @Override 104 | public void postTaskToThread(Runnable task, long delayMillis) { 105 | Thread thread = new Thread(task, "SonicThread"); 106 | thread.start(); 107 | } 108 | 109 | @Override 110 | public File getSonicCacheDir() { 111 | return super.getSonicCacheDir(); 112 | } 113 | 114 | @Override 115 | public String getHostDirectAddress(String url) { 116 | return null; 117 | } 118 | } 119 | 120 | 121 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/webview/SonicSessionClientImpl.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.webview; 2 | 3 | import android.os.Bundle; 4 | import android.webkit.WebView; 5 | 6 | import com.tencent.sonic.sdk.SonicSessionClient; 7 | 8 | import java.util.HashMap; 9 | 10 | /** 11 | * Author:leon.wen 12 | * Time:2018/10/19 18:39 13 | * Description:This is SonicSessionClientImpl 14 | */ 15 | public class SonicSessionClientImpl extends SonicSessionClient { 16 | private WebView webView; 17 | 18 | public void bindWebView(WebView webView) { 19 | this.webView = webView; 20 | } 21 | 22 | public WebView getWebView() { 23 | return webView; 24 | } 25 | 26 | @Override 27 | public void loadUrl(String url, Bundle extraData) { 28 | webView.loadUrl(url); 29 | } 30 | 31 | @Override 32 | public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, 33 | String historyUrl) { 34 | webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); 35 | } 36 | 37 | @Override 38 | public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap headers) { 39 | loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl); 40 | } 41 | 42 | public void destroy() { 43 | if (null != webView) { 44 | webView.destroy(); 45 | webView = null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/widget/DrawableTextView.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.drawable.Drawable; 6 | import android.util.AttributeSet; 7 | 8 | public class DrawableTextView extends android.support.v7.widget.AppCompatTextView { 9 | 10 | public DrawableTextView(Context context) { 11 | super(context); 12 | } 13 | 14 | public DrawableTextView(Context context, AttributeSet attrs) { 15 | super(context, attrs); 16 | } 17 | 18 | public DrawableTextView(Context context, AttributeSet attrs, int defStyle) { 19 | super(context, attrs, defStyle); 20 | } 21 | 22 | @Override 23 | protected void onDraw(Canvas canvas) { 24 | Drawable[] drawables = getCompoundDrawables(); 25 | if (drawables != null) { 26 | Drawable drawableLeft = drawables[0]; 27 | if (drawableLeft != null) { 28 | float textWidth = getPaint().measureText(getText().toString()); 29 | int drawablePadding = getCompoundDrawablePadding(); 30 | int drawableWidth = drawableLeft.getIntrinsicWidth(); 31 | int viewPadding = getPaddingLeft() + getPaddingRight(); 32 | float bodyWidth = textWidth + drawableWidth + drawablePadding + viewPadding; 33 | canvas.translate((getWidth() - bodyWidth) / 2, 0); 34 | } 35 | } 36 | super.onDraw(canvas); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/java/com/weexbox/core/widget/FloatingDraftButton.kt: -------------------------------------------------------------------------------- 1 | package com.weexbox.core.widget 2 | 3 | import android.content.Context 4 | import android.support.design.widget.FloatingActionButton 5 | import android.util.AttributeSet 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import com.weexbox.core.util.AndroidUtil 9 | 10 | /** 11 | *Author:leon.wen 12 | *Time:2018/12/12 14:13 13 | *Description:This is FloatingDraftButton 14 | */ 15 | 16 | class FloatingDraftButton : FloatingActionButton, View.OnTouchListener { 17 | 18 | private var lastX = 0 19 | private var lastY = 0 20 | private var originX = 0 21 | private var originY = 0 22 | private val screenWidth: Int 23 | private val screenHeight: Int 24 | private var floatingActionButtons = ArrayList() 25 | 26 | constructor(context: Context) : this(context, null) 27 | 28 | constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) 29 | 30 | 31 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 32 | screenWidth = AndroidUtil.getScreenWidth(context) 33 | screenHeight = AndroidUtil.getScreenHeight(context) 34 | setOnTouchListener(this) 35 | } 36 | 37 | //注册归属的FloatingActionButton 38 | fun registerButton(floatingActionButton: FloatingActionButton) { 39 | floatingActionButtons.add(floatingActionButton) 40 | } 41 | 42 | fun getButtons(): ArrayList { 43 | return floatingActionButtons 44 | } 45 | 46 | fun getButtonSize(): Int { 47 | return floatingActionButtons.size 48 | } 49 | 50 | //是否可拖拽 一旦展开则不允许拖拽 51 | fun isDraftable(): Boolean { 52 | for (btn in floatingActionButtons) { 53 | if (btn.visibility == View.VISIBLE) { 54 | return false 55 | } 56 | } 57 | return true 58 | } 59 | 60 | //当被拖拽后其所属的FloatingActionButton 也要改变位置 61 | private fun slideButton(l: Int, t: Int, r: Int, b: Int) { 62 | for (floatingActionButton in floatingActionButtons) { 63 | floatingActionButton.layout(l, t, r, b) 64 | } 65 | } 66 | 67 | override fun onTouch(v: View, event: MotionEvent): Boolean { 68 | if (!isDraftable()) { 69 | return false 70 | } 71 | val ea = event.action 72 | when (ea) { 73 | MotionEvent.ACTION_DOWN -> { 74 | lastX = event.rawX.toInt() // 获取触摸事件触摸位置的原始X坐标 75 | lastY = event.rawY.toInt() 76 | originX = lastX 77 | originY = lastY 78 | } 79 | MotionEvent.ACTION_MOVE -> { 80 | val dx = event.rawX.toInt() - lastX 81 | val dy = event.rawY.toInt() - lastY 82 | var l = v.left + dx 83 | var b = v.bottom + dy 84 | var r = v.right + dx 85 | var t = v.top + dy 86 | // 下面判断移动是否超出屏幕 87 | if (l < 0) { 88 | l = 0 89 | r = l + v.width 90 | } 91 | if (t < 0) { 92 | t = 0 93 | b = t + v.height 94 | } 95 | if (r > screenWidth) { 96 | r = screenWidth 97 | l = r - v.width 98 | } 99 | if (b > screenHeight) { 100 | b = screenHeight 101 | t = b - v.height 102 | } 103 | v.layout(l, t, r, b) 104 | slideButton(l, t, r, b) 105 | lastX = event.rawX.toInt() 106 | lastY = event.rawY.toInt() 107 | v.postInvalidate() 108 | } 109 | MotionEvent.ACTION_UP -> { 110 | val distance = event.rawX.toInt() - originX + event.rawY.toInt() - originY 111 | if (Math.abs(distance) < 20) { 112 | //当变化太小的时候什么都不做 OnClick执行 113 | } else { 114 | return true 115 | } 116 | } 117 | } 118 | return false 119 | 120 | } 121 | } -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/arrows_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/arrows_left.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/arrows_left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/arrows_left2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/arrows_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/arrows_right.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/camera.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/choose1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/choose1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/choose2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/choose2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/close1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/close_page_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/close_page_icon.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/icon_go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/icon_go_back.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/more.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/more2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/more2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/open.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/refesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/refesh.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xhdpi/warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xhdpi/warn.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/arrows_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/arrows_left.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/arrows_left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/arrows_left2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/arrows_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/arrows_right.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/choose1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/choose1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/choose2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/choose2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/close1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/icon_go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/icon_go_back.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/more.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/more2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/more2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxhdpi/warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxhdpi/warn.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/arrows_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/arrows_left.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/arrows_left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/arrows_left2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/arrows_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/arrows_right.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/choose1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/choose1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/choose2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/choose2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/close1.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/more.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/more2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/more2.png -------------------------------------------------------------------------------- /core/src/main/res/drawable-xxxhdpi/warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/core/src/main/res/drawable-xxxhdpi/warn.png -------------------------------------------------------------------------------- /core/src/main/res/drawable/actionbar_bottom_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /core/src/main/res/layout/activity_base.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/src/main/res/layout/activity_photoview.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 23 | 24 | 32 | 33 | 45 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /core/src/main/res/layout/activity_statusbar_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/src/main/res/layout/activity_web_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /core/src/main/res/layout/activity_weex.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /core/src/main/res/layout/fragment_weex.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /core/src/main/res/layout/layout_floating_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 21 | 22 | 36 | 37 | 51 | 52 | 66 | 67 | -------------------------------------------------------------------------------- /core/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 |

5 | 10 | 11 | -------------------------------------------------------------------------------- /core/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #3c3c3c 5 | #cc3c3c3c 6 | #6a3c3c3c 7 | #0d3c3c3c 8 | 9 | #ff9d44 10 | #ccff9d44 11 | #6aff9d44 12 | #0dff9d44 13 | 14 | 15 | #00000000 16 | #00000000 17 | 18 | 19 | #ffffff 20 | #eeeeee 21 | 22 | 23 | #ff3c3c3c 24 | #0d3c3c3c 25 | #663c3c3c 26 | #993c3c3c 27 | #cc3c3c3c 28 | 29 | #ff649afb 30 | 31 | #f6f6f6 32 | 33 | 34 | #ff333333 35 | #cc333333 36 | #b2333333 37 | #99333333 38 | #80333333 39 | #66333333 40 | #4c333333 41 | #33333333 42 | #26333333 43 | #1a333333 44 | #0d333333 45 | #f6f6f6 46 | -------------------------------------------------------------------------------- /core/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 48dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /core/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Core 3 | 4 | 5 | Hello blank fragment 6 | MainActivity 7 | Settings 8 | 9 | -------------------------------------------------------------------------------- /core/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 21 | 22 | -------------------------------------------------------------------------------- /core/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /core/src/test/java/com/weexbox/core/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.weexbox.core; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aygtech/weexbox-android-library/8f0961930d08bde2cea76dbe58bdc415bc989b9f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Aug 29 11:34:23 CST 2019 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-5.4.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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':core' 2 | --------------------------------------------------------------------------------