diff --git a/GaiaXAndroidDemo/app/src/main/AndroidManifest.xml b/GaiaXAndroidDemo/app/src/main/AndroidManifest.xml index d185483cd..7d1c562a8 100644 --- a/GaiaXAndroidDemo/app/src/main/AndroidManifest.xml +++ b/GaiaXAndroidDemo/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> = mutableListOf() - - override fun getTemplate(gxTemplateItem: GXTemplateEngine.GXTemplateItem): GXTemplate? { - return templateCache.firstOrNull { it.biz == gxTemplateItem.bizId && it.id == gxTemplateItem.templateId } - } - - fun addTemplate(bizId: String, templateId: String, template: JSONObject) { - val layer = template.getString(GXTemplateKey.GAIAX_INDEX_JSON) ?: "" - val css = template.getString(GXTemplateKey.GAIAX_INDEX_CSS) ?: "" - val dataBind = template.getString(GXTemplateKey.GAIAX_INDEX_DATABINDING) ?: "" - val js = template.getString(GXTemplateKey.GAIAX_INDEX_JS) ?: "" - templateCache.add(GXTemplate(templateId, bizId, -1, layer, css, dataBind, js)) - } - } -} \ No newline at end of file diff --git a/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/MainActivity.kt b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/MainActivity.kt index 3c48a0149..0b62d8b8d 100644 --- a/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/MainActivity.kt +++ b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/MainActivity.kt @@ -72,8 +72,8 @@ class MainActivity : AppCompatActivity() { startActivity(intent) } - findViewById(R.id.api)?.setOnClickListener { - val intent = Intent(MainActivity@ this, ApiTemplateActivity::class.java) + findViewById(R.id.remote)?.setOnClickListener { + val intent = Intent(MainActivity@ this, RemoteDataSourceTemplateActivity::class.java) startActivity(intent) } } diff --git a/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/RemoteDataSourceTemplateActivity.kt b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/RemoteDataSourceTemplateActivity.kt new file mode 100644 index 000000000..4cf8d9c67 --- /dev/null +++ b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/RemoteDataSourceTemplateActivity.kt @@ -0,0 +1,164 @@ +package com.alibaba.gaiax.demo + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.LinearLayoutCompat +import com.alibaba.fastjson.JSONObject +import com.alibaba.gaiax.GXRegisterCenter +import com.alibaba.gaiax.GXTemplateEngine +import com.alibaba.gaiax.data.assets.GXBinParser +import com.alibaba.gaiax.demo.utils.AssetsUtils +import com.alibaba.gaiax.demo.utils.UiExecutor +import com.alibaba.gaiax.template.GXSize.Companion.dpToPx +import com.alibaba.gaiax.template.GXTemplate +import com.alibaba.gaiax.template.GXTemplateKey +import java.util.concurrent.Executors + +class RemoteDataSourceTemplateActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_remote_data_source_template) + + // Init + GXTemplateEngine.instance.init(this) + + // Register remote data template source to GaiaXSDK + val netTemplateSource = RemoteDataSourceTemplateSource.instance + GXRegisterCenter.instance.registerExtensionTemplateSource(netTemplateSource, 20) + + // Request Net Data + RemoteDataSourceNetRequest.instance.requestAsync( + this, + JSONObject(), + object : RemoteDataSourceNetRequest.IDataCallback { + override fun template(bizId: String, templateId: String, data: ByteArray?) { + // add template to net template source + RemoteDataSourceTemplateSource.instance.addTemplate(bizId, templateId, data) + } + + override fun finish() { + // Net finish + toBindTemplate() + } + }) + + // Other + } + + private fun toBindTemplate() { + + // 模板参数 + // 去加载远程模板业务下的gx-vertical-item模板 + val params = GXTemplateEngine.GXTemplateItem(this, "remote", "gx-vertical-item") + + // 模板绘制尺寸 + val size = GXTemplateEngine.GXMeasureSize(100F.dpToPx(), null) + + // 模板数据 + val templateData = GXTemplateEngine.GXTemplateData( + AssetsUtils.parseAssets( + this, + "data/vertical-item.json" + ) + ) + + // 创建模板View + val view = GXTemplateEngine.instance.createView(params, size) + + // 绑定数据 + GXTemplateEngine.instance.bindData(view, templateData) + + // 插入模板View + findViewById(R.id.root).addView(view, 0) + } + + class RemoteDataSourceNetRequest { + + interface IDataCallback { + fun template(bizId: String, templateId: String, data: ByteArray?) + fun finish() + } + + fun requestAsync( + activity: RemoteDataSourceTemplateActivity, + netParams: JSONObject, + callback: IDataCallback + ) { + // Thread + Executors.newSingleThreadExecutor().execute { + // request server + val response = AssetsUtils.parseAssets( + activity, + "remote_data_source/api_response.json" + ) + + // parse data + response.getJSONArray("templates")?.forEach { + val template = (it as JSONObject) + val templateBiz = template.getString("templateBiz") + val templateId = template.getString("templateId") + val templateBytes = getTemplateContents(activity, templateId) + + // callback result + callback.template(templateBiz, templateId, templateBytes) + } + + UiExecutor.action { + callback.finish() + } + } + } + + // mock net + private fun getTemplateContents( + activity: RemoteDataSourceTemplateActivity, + templateId: String + ): ByteArray? { + return try { + activity.resources?.assets?.open("remote_data_source/templates/${templateId}") + ?.use { it.readBytes() } + } catch (e: Exception) { + e.printStackTrace() + null + } + } + + companion object { + + val instance by lazy { + RemoteDataSourceNetRequest() + } + } + } + + /** + * 远程模板的数据源 + */ + class RemoteDataSourceTemplateSource : GXRegisterCenter.GXIExtensionTemplateSource { + + companion object { + val instance by lazy { + RemoteDataSourceTemplateSource() + } + } + + private val templateCache: MutableList = mutableListOf() + + override fun getTemplate(gxTemplateItem: GXTemplateEngine.GXTemplateItem): GXTemplate? { + return templateCache.firstOrNull { it.biz == gxTemplateItem.bizId && it.id == gxTemplateItem.templateId } + } + + fun addTemplate(templateBiz: String, templateId: String, bytes: ByteArray?) { + if (bytes != null) { + val binaryData = GXBinParser.parser(bytes) + val layer = binaryData.getString(GXTemplateKey.GAIAX_LAYER) + ?: throw IllegalArgumentException("Layer mustn't empty, templateBiz = $templateBiz, templateId = $templateId") + val css = binaryData.getString(GXTemplateKey.GAIAX_CSS) ?: "" + val dataBind = binaryData.getString(GXTemplateKey.GAIAX_DATABINDING) ?: "" + val js = binaryData.getString(GXTemplateKey.GAIAX_JS) ?: "" + val template = GXTemplate(templateId, templateBiz, -1, layer, css, dataBind, js) + templateCache.add(template) + } + } + } +} \ No newline at end of file diff --git a/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/utils/UiExecutor.kt b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/utils/UiExecutor.kt new file mode 100644 index 000000000..ff9eb9066 --- /dev/null +++ b/GaiaXAndroidDemo/app/src/main/kotlin/com/alibaba/gaiax/demo/utils/UiExecutor.kt @@ -0,0 +1,26 @@ +package com.alibaba.gaiax.demo.utils + +import android.os.Handler +import android.os.Looper + +object UiExecutor { + + val ui: Handler = Handler(Looper.getMainLooper()) + + fun isMainThread(): Boolean { + // 在单元测试环境下 myLooper为null + return Looper.myLooper() == null || Looper.myLooper() == Looper.getMainLooper() + } + + fun action(runnable: Runnable) { + ui.post(runnable) + } + + fun action(function: () -> Unit) { + ui.post { function.invoke() } + } + + fun removeAction(runnable: Runnable) { + ui.removeCallbacks(runnable) + } +} \ No newline at end of file diff --git a/GaiaXAndroidDemo/app/src/main/res/layout/activity_api_template.xml b/GaiaXAndroidDemo/app/src/main/res/layout/activity_api_template.xml deleted file mode 100644 index 770807b63..000000000 --- a/GaiaXAndroidDemo/app/src/main/res/layout/activity_api_template.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/GaiaXAndroidDemo/app/src/main/res/layout/activity_remote_data_source_template.xml b/GaiaXAndroidDemo/app/src/main/res/layout/activity_remote_data_source_template.xml new file mode 100644 index 000000000..eb38eeaf7 --- /dev/null +++ b/GaiaXAndroidDemo/app/src/main/res/layout/activity_remote_data_source_template.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/GaiaXAndroidDemo/app/src/main/res/layout/content_main.xml b/GaiaXAndroidDemo/app/src/main/res/layout/content_main.xml index 22537ac06..570ce2d48 100644 --- a/GaiaXAndroidDemo/app/src/main/res/layout/content_main.xml +++ b/GaiaXAndroidDemo/app/src/main/res/layout/content_main.xml @@ -54,10 +54,10 @@ android:textColor="@color/black" /> diff --git a/GaiaXAndroidDemo/app/src/main/res/values-zh-rCN/strings.xml b/GaiaXAndroidDemo/app/src/main/res/values-zh-rCN/strings.xml index 376643c0a..1fb7722f1 100644 --- a/GaiaXAndroidDemo/app/src/main/res/values-zh-rCN/strings.xml +++ b/GaiaXAndroidDemo/app/src/main/res/values-zh-rCN/strings.xml @@ -6,5 +6,5 @@ 容器模板 数据绑定 事件绑定 - Api + 远程数据源 diff --git a/GaiaXAndroidDemo/app/src/main/res/values/strings.xml b/GaiaXAndroidDemo/app/src/main/res/values/strings.xml index 5850fa090..aa9fe8f9e 100644 --- a/GaiaXAndroidDemo/app/src/main/res/values/strings.xml +++ b/GaiaXAndroidDemo/app/src/main/res/values/strings.xml @@ -6,5 +6,5 @@ Container Template Data Binding Event Binding - Api + Remote Data Source diff --git a/GaiaXiOS/GaiaXiOS.podspec b/GaiaXiOS/GaiaXiOS.podspec index f2da7e76b..957c4bf8a 100644 --- a/GaiaXiOS/GaiaXiOS.podspec +++ b/GaiaXiOS/GaiaXiOS.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "GaiaXiOS" - s.version = "0.2.5" + s.version = "0.2.7" s.platform = :ios, "9.0" s.summary = "dynamic template engine is a lightweight cross-end solution of pure native dynamic card" diff --git a/GaiaXiOS/GaiaXiOS/Impl/Interface/GXTemplateSourceProtocal.h b/GaiaXiOS/GaiaXiOS/Impl/Interface/GXTemplateSourceProtocal.h index a988584b0..7229a2fd0 100644 --- a/GaiaXiOS/GaiaXiOS/Impl/Interface/GXTemplateSourceProtocal.h +++ b/GaiaXiOS/GaiaXiOS/Impl/Interface/GXTemplateSourceProtocal.h @@ -13,10 +13,15 @@ NS_ASSUME_NONNULL_BEGIN @protocol GXTemplateSourceProtocal @required + // priority - (NSInteger)priority; -//get template +/// get template +/// @param templateItem 模板相关信息 +/// 注意: +/// 1. 如需缓存逻辑,需要在协议方法内自行添加 +/// 2. 配合 GXUtils (Template) 中的方法,可以解析文件夹和二进制模板 - (NSDictionary *)getTemplateInfoWithTemplateItem:(GXTemplateItem *)templateItem; @optional diff --git a/README-ZH.md b/README-ZH.md index e30b91578..a6cdc6964 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -1,5 +1,5 @@

- GaiaX-logo + GaiaX-logo

GaiaX动态模板引擎是阿里巴巴优酷技术团队研发的一套轻量级的纯原生动态化卡片跨端解决方案 diff --git a/README.md b/README.md index a62381ca3..e532f7343 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- GaiaX-logo + GaiaX-logo

GaiaX dynamic template engine is a lightweight cross-platform solution for pure native dynamic card, developed by Alibaba YouKu technology team