Repository: incubator-weex
Updated Branches:
  refs/heads/master 51b060cef -> bbb0817f6


* [android] new visual sense for playground

* [android] request camera permission before scan qr code

* [android] sync return for locale module

* [android] sync return for locale module

* [android] fix crash on no connection

* [android] remove invalid module


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/bbb0817f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/bbb0817f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/bbb0817f

Branch: refs/heads/master
Commit: bbb0817f66ae535a2e44a44cc71e8e32eae4a720
Parents: 51b060c
Author: misakuo <[email protected]>
Authored: Fri Jan 12 15:32:40 2018 +0800
Committer: acton393 <[email protected]>
Committed: Wed Jan 17 16:28:19 2018 +0800

----------------------------------------------------------------------
 .../weex/commons/AbstractWeexActivity.java      |  11 +-
 .../java/com/alibaba/weex/WXApplication.java    |   4 +-
 .../alibaba/weex/extend/component/WXMask.java   | 223 ++++++++++++++--
 .../extend/component/dom/WXMaskDomObject.java   | 251 +++++++++++++++++--
 .../weex/extend/module/WXEventModule.java       |  31 +++
 .../alibaba/weex/extend/module/WXTitleBar.java  | 109 ++++++++
 .../app/src/main/res/values-v21/styles.xml      |   4 +
 .../app/src/main/res/values/colors.xml          |   4 +-
 .../app/src/main/res/values/styles.xml          |   4 +-
 android/sdk/build.gradle                        |   2 +-
 .../main/java/com/taobao/weex/WXSDKEngine.java  |   4 +-
 .../weex/adapter/DefaultWXHttpAdapter.java      |   6 +-
 .../taobao/weex/ui/module/WXLocalModule.java    |  93 -------
 .../taobao/weex/ui/module/WXLocaleModule.java   | 106 ++++++++
 14 files changed, 710 insertions(+), 142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/commons/src/main/java/com/alibaba/weex/commons/AbstractWeexActivity.java
----------------------------------------------------------------------
diff --git 
a/android/commons/src/main/java/com/alibaba/weex/commons/AbstractWeexActivity.java
 
b/android/commons/src/main/java/com/alibaba/weex/commons/AbstractWeexActivity.java
index c71ce3c..3627b8c 100644
--- 
a/android/commons/src/main/java/com/alibaba/weex/commons/AbstractWeexActivity.java
+++ 
b/android/commons/src/main/java/com/alibaba/weex/commons/AbstractWeexActivity.java
@@ -22,6 +22,7 @@ import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.support.annotation.CallSuper;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.app.AppCompatActivity;
 import android.view.KeyEvent;
@@ -31,10 +32,10 @@ import android.view.ViewGroup;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.weex.commons.util.AssertUtil;
 import com.alibaba.weex.commons.util.ScreenUtil;
-import com.taobao.weex.common.Constants;
 import com.taobao.weex.IWXRenderListener;
 import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.WXSDKInstance;
+import com.taobao.weex.common.Constants;
 import com.taobao.weex.common.WXRenderStrategy;
 import com.taobao.weex.utils.WXUtils;
 
@@ -249,4 +250,12 @@ public abstract class AbstractWeexActivity extends 
AppCompatActivity implements
   public boolean onKeyUp(int keyCode, KeyEvent event) {
     return (mWxAnalyzerDelegate != null && 
mWxAnalyzerDelegate.onKeyUp(keyCode,event)) || super.onKeyUp(keyCode, event);
   }
+
+  @Override
+  public void onRequestPermissionsResult(int requestCode, @NonNull String[] 
permissions, @NonNull int[] grantResults) {
+    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    if (mInstance != null) {
+      mInstance.onRequestPermissionsResult(requestCode, permissions, 
grantResults);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java 
b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
index d9c6b64..adfc9d4 100644
--- a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
+++ b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
@@ -20,7 +20,6 @@ package com.alibaba.weex;
 
 import android.app.Activity;
 import android.app.Application;
-import android.graphics.Typeface;
 import android.os.Bundle;
 
 import com.alibaba.weex.commons.adapter.DefaultWebSocketAdapterFactory;
@@ -38,6 +37,7 @@ import com.alibaba.weex.extend.module.MyModule;
 import com.alibaba.weex.extend.module.RenderModule;
 import com.alibaba.weex.extend.module.SyncTestModule;
 import com.alibaba.weex.extend.module.WXEventModule;
+import com.alibaba.weex.extend.module.WXTitleBar;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.taobao.weex.InitConfig;
 import com.taobao.weex.WXEnvironment;
@@ -90,6 +90,8 @@ public class WXApplication extends Application {
 
       WXSDKEngine.registerModule("myModule", MyModule.class);
       WXSDKEngine.registerModule("geolocation", GeolocationModule.class);
+
+      WXSDKEngine.registerModule("titleBar", WXTitleBar.class);
       /**
        * override default image tag
        * WXSDKEngine.registerComponent("image", FrescoImageComponent.class);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/java/com/alibaba/weex/extend/component/WXMask.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/component/WXMask.java
 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/component/WXMask.java
index 1021041..5a26542 100644
--- 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/component/WXMask.java
+++ 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/component/WXMask.java
@@ -1,20 +1,112 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
+/**
+ * Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ 
TERMS AND CONDITIONS FOR
+ * USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean 
the terms and conditions
+ * for use, reproduction, and distribution as defined by Sections 1 through 9 
of this document.
+ * "Licensor" shall mean the copyright owner or entity authorized by the 
copyright owner that is
+ * granting the License. "Legal Entity" shall mean the union of the acting 
entity and all other
+ * entities that control, are controlled by, or are under common control with 
that entity. For the
+ * purposes of this definition, "control" means (i) the power, direct or 
indirect, to cause the
+ * direction or management of such entity, whether by contract or otherwise, 
or (ii) ownership of
+ * fifty percent (50%) or more of the outstanding shares, or (iii) beneficial 
ownership of such
+ * entity. "You" (or "Your") shall mean an individual or Legal Entity 
exercising permissions granted
+ * by this License. "Source" form shall mean the preferred form for making 
modifications, including
+ * but not limited to software source code, documentation source, and 
configuration files. "Object"
+ * form shall mean any form resulting from mechanical transformation or 
translation of a Source
+ * form, including but not limited to compiled object code, generated 
documentation, and conversions
+ * to other media types. "Work" shall mean the work of authorship, whether in 
Source or Object form,
+ * made available under the License, as indicated by a copyright notice that 
is included in or
+ * attached to the work (an example is provided in the Appendix below). 
"Derivative Works" shall
+ * mean any work, whether in Source or Object form, that is based on (or 
derived from) the Work and
+ * for which the editorial revisions, annotations, elaborations, or other 
modifications represent,
+ * as a whole, an original work of authorship. For the purposes of this 
License, Derivative Works
+ * shall not include works that remain separable from, or merely link (or bind 
by name) to the
+ * interfaces of, the Work and Derivative Works thereof. "Contribution" shall 
mean any work of
+ * authorship, including the original version of the Work and any 
modifications or additions to that
+ * Work or Derivative Works thereof, that is intentionally submitted to 
Licensor for inclusion in
+ * the Work by the copyright owner or by an individual or Legal Entity 
authorized to submit on
+ * behalf of the copyright owner. For the purposes of this definition, 
"submitted" means any form of
+ * electronic, verbal, or written communication sent to the Licensor or its 
representatives,
+ * including but not limited to communication on electronic mailing lists, 
source code control
+ * systems, and issue tracking systems that are managed by, or on behalf of, 
the Licensor for the
+ * purpose of discussing and improving the Work, but excluding communication 
that is conspicuously
+ * marked or otherwise designated in writing by the copyright owner as "Not a 
Contribution."
+ * "Contributor" shall mean Licensor and any individual or Legal Entity on 
behalf of whom a
+ * Contribution has been received by Licensor and subsequently incorporated 
within the Work. 2.
+ * Grant of Copyright License. Subject to the terms and conditions of this 
License, each Contributor
+ * hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of, publicly 
display, publicly perform,
+ * sublicense, and distribute the Work and such Derivative Works in Source or 
Object form. 3. Grant
+ * of Patent License. Subject to the terms and conditions of this License, 
each Contributor hereby
+ * grants to You a perpetual, worldwide, non-exclusive, no-charge, 
royalty-free, irrevocable (except
+ * as stated in this section) patent license to make, have made, use, offer to 
sell, sell, import,
+ * and otherwise transfer the Work, where such license applies only to those 
patent claims
+ * licensable by such Contributor that are necessarily infringed by their 
Contribution(s) alone or
+ * by combination of their Contribution(s) with the Work to which such 
Contribution(s) was
+ * submitted. If You institute patent litigation against any entity (including 
a cross-claim or
+ * counterclaim in a lawsuit) alleging that the Work or a Contribution 
incorporated within the Work
+ * constitutes direct or contributory patent infringement, then any patent 
licenses granted to You
+ * under this License for that Work shall terminate as of the date such 
litigation is filed. 4.
+ * Redistribution. You may reproduce and distribute copies of the Work or 
Derivative Works thereof
+ * in any medium, with or without modifications, and in Source or Object form, 
provided that You
+ * meet the following conditions: (a) You must give any other recipients of 
the Work or Derivative
+ * Works a copy of this License; and (b) You must cause any modified files to 
carry prominent
+ * notices stating that You changed the files; and (c) You must retain, in the 
Source form of any
+ * Derivative Works that You distribute, all copyright, patent, trademark, and 
attribution notices
+ * from the Source form of the Work, excluding those notices that do not 
pertain to any part of the
+ * Derivative Works; and (d) If the Work includes a "NOTICE" text file as part 
of its distribution,
+ * then any Derivative Works that You distribute must include a readable copy 
of the attribution
+ * notices contained within such NOTICE file, excluding those notices that do 
not pertain to any
+ * part of the Derivative Works, in at least one of the following places: 
within a NOTICE text file
+ * distributed as part of the Derivative Works; within the Source form or 
documentation, if provided
+ * along with the Derivative Works; or, within a display generated by the 
Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents of the 
NOTICE file are for
+ * informational purposes only and do not modify the License. You may add Your 
own attribution
+ * notices within Derivative Works that You distribute, alongside or as an 
addendum to the NOTICE
+ * text from the Work, provided that such additional attribution notices 
cannot be construed as
+ * modifying the License. You may add Your own copyright statement to Your 
modifications and may
+ * provide additional or different license terms and conditions for use, 
reproduction, or
+ * distribution of Your modifications, or for any such Derivative Works as a 
whole, provided Your
+ * use, reproduction, and distribution of the Work otherwise complies with the 
conditions stated in
+ * this License. 5. Submission of Contributions. Unless You explicitly state 
otherwise, any
+ * Contribution intentionally submitted for inclusion in the Work by You to 
the Licensor shall be
+ * under the terms and conditions of this License, without any additional 
terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify the 
terms of any separate
+ * license agreement you may have executed with Licensor regarding such 
Contributions. 6.
+ * Trademarks. This License does not grant permission to use the trade names, 
trademarks, service
+ * marks, or product names of the Licensor, except as required for reasonable 
and customary use in
+ * describing the origin of the Work and reproducing the content of the NOTICE 
file. 7. Disclaimer
+ * of Warranty. Unless required by applicable law or agreed to in writing, 
Licensor provides the
+ * Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied, including, without 
limitation, any warranties
+ * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 
PARTICULAR PURPOSE.
+ * You are solely responsible for determining the appropriateness of using or 
redistributing the
+ * Work and assume any risks associated with Your exercise of permissions 
under this License. 8.
+ * Limitation of Liability. In no event and under no legal theory, whether in 
tort (including
+ * negligence), contract, or otherwise, unless required by applicable law 
(such as deliberate and
+ * grossly negligent acts) or agreed to in writing, shall any Contributor be 
liable to You for
+ * damages, including any direct, indirect, special, incidental, or 
consequential damages of any
+ * character arising as a result of this License or out of the use or 
inability to use the Work
+ * (including but not limited to damages for loss of goodwill, work stoppage, 
computer failure or
+ * malfunction, or any and all other commercial damages or losses), even if 
such Contributor has
+ * been advised of the possibility of such damages. 9. Accepting Warranty or 
Additional Liability.
+ * While redistributing the Work or Derivative Works thereof, You may choose 
to offer, and charge a
+ * fee for, acceptance of support, warranty, indemnity, or other liability 
obligations and/or rights
+ * consistent with this License. However, in accepting such obligations, You 
may act only on Your
+ * own behalf and on Your sole responsibility, not on behalf of any other 
Contributor, and only if
+ * You agree to indemnify, defend, and hold each Contributor harmless for any 
liability incurred by,
+ * or claims asserted against, such Contributor by reason of your accepting 
any such warranty or
+ * additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply 
the Apache License to
+ * your work. To apply the Apache License to your work, attach the following 
boilerplate notice,
+ * with the fields enclosed by brackets "[]" replaced with your own 
identifying information. (Don't
+ * include the brackets!)  The text should be enclosed in the appropriate 
comment syntax for the
+ * file format. We also recommend that a file or class name and description of 
purpose be included
+ * on the same "printed page" as the copyright notice for easier 
identification within third-party
+ * archives. Copyright 2016 Alibaba Group Licensed under the Apache License, 
Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless 
required by applicable
+ * law or agreed to in writing, software distributed under the License is 
distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
implied. See the License
+ * for the specific language governing permissions and limitations under the 
License.
  */
 package com.alibaba.weex.extend.component;
 
@@ -22,17 +114,25 @@ import android.app.Activity;
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
 import android.support.annotation.NonNull;
 import android.view.Gravity;
 import android.view.View;
 import android.view.WindowManager;
+import android.widget.FrameLayout;
 import android.widget.PopupWindow;
 
 import com.alibaba.weex.extend.view.WXMaskView;
 import com.taobao.weex.WXSDKInstance;
+import com.taobao.weex.dom.ImmutableDomObject;
 import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.dom.WXStyle;
+import com.taobao.weex.dom.flex.Spacing;
 import com.taobao.weex.ui.component.WXVContainer;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Created by lixinke on 2016/12/26.
  */
@@ -52,11 +152,41 @@ public class WXMask extends WXVContainer {
     mContainerView = new WXMaskView(context);
     mPopupWindow = new PopupWindow(context);
     mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-    mPopupWindow.setClippingEnabled(false);
+
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
+      mPopupWindow.setAttachedInDecor(true);
+    }
+
+    //setClippingEnabled(false) will cause INPUT_ADJUST_PAN invalid.
+    //mPopupWindow.setClippingEnabled(false);
+
     mPopupWindow.setContentView(mContainerView);
     mPopupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
     mPopupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
-    mPopupWindow.showAtLocation(((Activity) 
context).getWindow().getDecorView(), Gravity.TOP, (int) 
getDomObject().getLayoutX(), (int) getDomObject().getLayoutY());
+    
mPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |
+        WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+    mPopupWindow.setFocusable(true);
+
+    mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
+      @Override
+      public void onDismiss() {
+        fireVisibleChangedEvent(false);
+      }
+    });
+
+    int y = 0;
+    int statusBarHeight = 0;
+    int resourceId = context.getResources().getIdentifier("status_bar_height", 
"dimen", "android");
+    if (resourceId > 0) {
+      statusBarHeight = 
context.getResources().getDimensionPixelSize(resourceId);
+      y = statusBarHeight;
+    }
+
+    mPopupWindow.showAtLocation(((Activity) 
context).getWindow().getDecorView(),
+        Gravity.TOP | Gravity.START,
+        0,
+        y);
+    fireVisibleChangedEvent(true);
 
     return mContainerView;
   }
@@ -72,4 +202,59 @@ public class WXMask extends WXVContainer {
       mPopupWindow.dismiss();
     }
   }
+
+  private void fireVisibleChangedEvent(boolean visible) {
+    Map<String, Object> event = new HashMap<>(1);
+    event.put("visible", visible);
+    fireEvent("visiblechanged", event);
+  }
+
+  @Override
+  protected void setHostLayoutParams(View host, int width, int height, int 
left, int right, int top, int bottom) {
+    ImmutableDomObject domObject = getDomObject();
+    left = get(LEFT, domObject);
+    right = get(RIGHT, domObject);
+    top = get(TOP, domObject);
+    bottom = get(BOTTOM, domObject);
+    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, 
height);
+    params.setMargins(left, top, right, bottom);
+    getHostView().setLayoutParams(params);
+  }
+
+  private static final int LEFT = 0;
+  private static final int RIGHT = 1;
+  private static final int TOP = 2;
+  private static final int BOTTOM = 3;
+
+  private int get(int type, ImmutableDomObject domObject) {
+    try {
+      Spacing margin = domObject.getMargin();
+      WXStyle style = domObject.getStyles();
+      switch (type) {
+        case LEFT:
+          return add(style.getLeft(), margin.get(Spacing.LEFT));
+        case RIGHT:
+          return add(style.getRight(), margin.get(Spacing.RIGHT));
+        case TOP:
+          return add(style.getTop(), margin.get(Spacing.TOP));
+        case BOTTOM:
+          return add(style.getBottom(), margin.get(Spacing.BOTTOM));
+      }
+    } catch (Throwable t) {
+      //ignore
+    }
+    return 0;
+  }
+
+  private int add(float a, float b) {
+    if (Float.isNaN(a)) {
+      a = 0f;
+    }
+
+    if (Float.isNaN(b)) {
+      b = 0f;
+    }
+
+    return (int) (a + b);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/java/com/alibaba/weex/extend/component/dom/WXMaskDomObject.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/component/dom/WXMaskDomObject.java
 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/component/dom/WXMaskDomObject.java
index d476302..1de289b 100644
--- 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/component/dom/WXMaskDomObject.java
+++ 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/component/dom/WXMaskDomObject.java
@@ -1,23 +1,212 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
+/**
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ * <p>
+ * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ * <p>
+ * 1. Definitions.
+ * <p>
+ * "License" shall mean the terms and conditions for use, reproduction,
+ * and distribution as defined by Sections 1 through 9 of this document.
+ * <p>
+ * "Licensor" shall mean the copyright owner or entity authorized by
+ * the copyright owner that is granting the License.
+ * <p>
+ * "Legal Entity" shall mean the union of the acting entity and all
+ * other entities that control, are controlled by, or are under common
+ * control with that entity. For the purposes of this definition,
+ * "control" means (i) the power, direct or indirect, to cause the
+ * direction or management of such entity, whether by contract or
+ * otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ * outstanding shares, or (iii) beneficial ownership of such entity.
+ * <p>
+ * "You" (or "Your") shall mean an individual or Legal Entity
+ * exercising permissions granted by this License.
+ * <p>
+ * "Source" form shall mean the preferred form for making modifications,
+ * including but not limited to software source code, documentation
+ * source, and configuration files.
+ * <p>
+ * "Object" form shall mean any form resulting from mechanical
+ * transformation or translation of a Source form, including but
+ * not limited to compiled object code, generated documentation,
+ * and conversions to other media types.
+ * <p>
+ * "Work" shall mean the work of authorship, whether in Source or
+ * Object form, made available under the License, as indicated by a
+ * copyright notice that is included in or attached to the work
+ * (an example is provided in the Appendix below).
+ * <p>
+ * "Derivative Works" shall mean any work, whether in Source or Object
+ * form, that is based on (or derived from) the Work and for which the
+ * editorial revisions, annotations, elaborations, or other modifications
+ * represent, as a whole, an original work of authorship. For the purposes
+ * of this License, Derivative Works shall not include works that remain
+ * separable from, or merely link (or bind by name) to the interfaces of,
+ * the Work and Derivative Works thereof.
+ * <p>
+ * "Contribution" shall mean any work of authorship, including
+ * the original version of the Work and any modifications or additions
+ * to that Work or Derivative Works thereof, that is intentionally
+ * submitted to Licensor for inclusion in the Work by the copyright owner
+ * or by an individual or Legal Entity authorized to submit on behalf of
+ * the copyright owner. For the purposes of this definition, "submitted"
+ * means any form of electronic, verbal, or written communication sent
+ * to the Licensor or its representatives, including but not limited to
+ * communication on electronic mailing lists, source code control systems,
+ * and issue tracking systems that are managed by, or on behalf of, the
+ * Licensor for the purpose of discussing and improving the Work, but
+ * excluding communication that is conspicuously marked or otherwise
+ * designated in writing by the copyright owner as "Not a Contribution."
+ * <p>
+ * "Contributor" shall mean Licensor and any individual or Legal Entity
+ * on behalf of whom a Contribution has been received by Licensor and
+ * subsequently incorporated within the Work.
+ * <p>
+ * 2. Grant of Copyright License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of,
+ * publicly display, publicly perform, sublicense, and distribute the
+ * Work and such Derivative Works in Source or Object form.
+ * <p>
+ * 3. Grant of Patent License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * (except as stated in this section) patent license to make, have made,
+ * use, offer to sell, sell, import, and otherwise transfer the Work,
+ * where such license applies only to those patent claims licensable
+ * by such Contributor that are necessarily infringed by their
+ * Contribution(s) alone or by combination of their Contribution(s)
+ * with the Work to which such Contribution(s) was submitted. If You
+ * institute patent litigation against any entity (including a
+ * cross-claim or counterclaim in a lawsuit) alleging that the Work
+ * or a Contribution incorporated within the Work constitutes direct
+ * or contributory patent infringement, then any patent licenses
+ * granted to You under this License for that Work shall terminate
+ * as of the date such litigation is filed.
+ * <p>
+ * 4. Redistribution. You may reproduce and distribute copies of the
+ * Work or Derivative Works thereof in any medium, with or without
+ * modifications, and in Source or Object form, provided that You
+ * meet the following conditions:
+ * <p>
+ * (a) You must give any other recipients of the Work or
+ * Derivative Works a copy of this License; and
+ * <p>
+ * (b) You must cause any modified files to carry prominent notices
+ * stating that You changed the files; and
+ * <p>
+ * (c) You must retain, in the Source form of any Derivative Works
+ * that You distribute, all copyright, patent, trademark, and
+ * attribution notices from the Source form of the Work,
+ * excluding those notices that do not pertain to any part of
+ * the Derivative Works; and
+ * <p>
+ * (d) If the Work includes a "NOTICE" text file as part of its
+ * distribution, then any Derivative Works that You distribute must
+ * include a readable copy of the attribution notices contained
+ * within such NOTICE file, excluding those notices that do not
+ * pertain to any part of the Derivative Works, in at least one
+ * of the following places: within a NOTICE text file distributed
+ * as part of the Derivative Works; within the Source form or
+ * documentation, if provided along with the Derivative Works; or,
+ * within a display generated by the Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents
+ * of the NOTICE file are for informational purposes only and
+ * do not modify the License. You may add Your own attribution
+ * notices within Derivative Works that You distribute, alongside
+ * or as an addendum to the NOTICE text from the Work, provided
+ * that such additional attribution notices cannot be construed
+ * as modifying the License.
+ * <p>
+ * You may add Your own copyright statement to Your modifications and
+ * may provide additional or different license terms and conditions
+ * for use, reproduction, or distribution of Your modifications, or
+ * for any such Derivative Works as a whole, provided Your use,
+ * reproduction, and distribution of the Work otherwise complies with
+ * the conditions stated in this License.
+ * <p>
+ * 5. Submission of Contributions. Unless You explicitly state otherwise,
+ * any Contribution intentionally submitted for inclusion in the Work
+ * by You to the Licensor shall be under the terms and conditions of
+ * this License, without any additional terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify
+ * the terms of any separate license agreement you may have executed
+ * with Licensor regarding such Contributions.
+ * <p>
+ * 6. Trademarks. This License does not grant permission to use the trade
+ * names, trademarks, service marks, or product names of the Licensor,
+ * except as required for reasonable and customary use in describing the
+ * origin of the Work and reproducing the content of the NOTICE file.
+ * <p>
+ * 7. Disclaimer of Warranty. Unless required by applicable law or
+ * agreed to in writing, Licensor provides the Work (and each
+ * Contributor provides its Contributions) on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied, including, without limitation, any warranties or conditions
+ * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ * PARTICULAR PURPOSE. You are solely responsible for determining the
+ * appropriateness of using or redistributing the Work and assume any
+ * risks associated with Your exercise of permissions under this License.
+ * <p>
+ * 8. Limitation of Liability. In no event and under no legal theory,
+ * whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law (such as deliberate and grossly
+ * negligent acts) or agreed to in writing, shall any Contributor be
+ * liable to You for damages, including any direct, indirect, special,
+ * incidental, or consequential damages of any character arising as a
+ * result of this License or out of the use or inability to use the
+ * Work (including but not limited to damages for loss of goodwill,
+ * work stoppage, computer failure or malfunction, or any and all
+ * other commercial damages or losses), even if such Contributor
+ * has been advised of the possibility of such damages.
+ * <p>
+ * 9. Accepting Warranty or Additional Liability. While redistributing
+ * the Work or Derivative Works thereof, You may choose to offer,
+ * and charge a fee for, acceptance of support, warranty, indemnity,
+ * or other liability obligations and/or rights consistent with this
+ * License. However, in accepting such obligations, You may act only
+ * on Your own behalf and on Your sole responsibility, not on behalf
+ * of any other Contributor, and only if You agree to indemnify,
+ * defend, and hold each Contributor harmless for any liability
+ * incurred by, or claims asserted against, such Contributor by reason
+ * of your accepting any such warranty or additional liability.
+ * <p>
+ * END OF TERMS AND CONDITIONS
+ * <p>
+ * APPENDIX: How to apply the Apache License to your work.
+ * <p>
+ * To apply the Apache License to your work, attach the following
+ * boilerplate notice, with the fields enclosed by brackets "[]"
+ * replaced with your own identifying information. (Don't include
+ * the brackets!)  The text should be enclosed in the appropriate
+ * comment syntax for the file format. We also recommend that a
+ * file or class name and description of purpose be included on the
+ * same "printed page" as the copyright notice for easier
+ * identification within third-party archives.
+ * <p>
+ * Copyright 2016 Alibaba Group
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package com.alibaba.weex.extend.component.dom;
 
+import android.app.Application;
+import android.content.res.Resources;
+
+import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.utils.WXViewUtils;
@@ -33,12 +222,32 @@ public class WXMaskDomObject extends WXDomObject {
 
   @Override
   protected Map<String, String> getDefaultStyle() {
-    Map<String,String> styles=new HashMap<>();
+    if (getDomContext() == null || getDomContext().getUIContext() == null) {
+      return super.getDefaultStyle();
+    }
+
+    int height = WXViewUtils.getScreenHeight(getDomContext().getUIContext());
+    int width = WXViewUtils.getScreenWidth(getDomContext().getUIContext());
+    Resources resources = getDomContext().getUIContext().getResources();
+    if (resources != null) {
+      width = resources.getDisplayMetrics().widthPixels;
+      height = resources.getDisplayMetrics().heightPixels;
+    }
+
+    if (WXEnvironment.getApplication() != null) {
+      Application context = WXEnvironment.getApplication();
+      int statusBarHeight = 0;
+      int resourceId = 
context.getResources().getIdentifier("status_bar_height", "dimen", "android");
+      if (resourceId > 0) {
+        statusBarHeight = 
context.getResources().getDimensionPixelSize(resourceId);
+        height -= statusBarHeight;
+      }
+    }
+
+    Map<String, String> styles = new HashMap<>();
     styles.put(Constants.Name.POSITION, "absolute");
-    int width=WXViewUtils.getScreenWidth(getDomContext().getUIContext());
     styles.put(Constants.Name.WIDTH, 
String.valueOf(WXViewUtils.getWebPxByWidth(width, getViewPortWidth())));
-    int height=WXViewUtils.getScreenHeight(getDomContext().getUIContext());
-    styles.put(Constants.Name.HEIGHT, 
String.valueOf(WXViewUtils.getWebPxByWidth(height,getViewPortWidth())));
+    styles.put(Constants.Name.HEIGHT, 
String.valueOf(WXViewUtils.getWebPxByWidth(height, getViewPortWidth())));
     styles.put(Constants.Name.TOP, "0");
     return styles;
   }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
index e417f0f..5ab286a 100644
--- 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
+++ 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXEventModule.java
@@ -18,11 +18,18 @@
  */
 package com.alibaba.weex.extend.module;
 
+import android.Manifest;
+import android.app.Activity;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.net.Uri;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
 import android.text.TextUtils;
+import android.widget.Toast;
 
 import com.alibaba.weex.WXPageActivity;
+import com.google.zxing.client.android.CaptureActivity;
 import com.taobao.weex.annotation.JSMethod;
 import com.taobao.weex.bridge.JSCallback;
 import com.taobao.weex.common.WXModule;
@@ -36,6 +43,8 @@ public class WXEventModule extends WXModule {
   private static final String WEEX_CATEGORY = 
"com.taobao.android.intent.category.WEEX";
   private static final String WEEX_ACTION = 
"com.taobao.android.intent.action.WEEX";
 
+  private static final int CAMERA_PERMISSION_REQUEST_CODE = 0x9;
+
 
   @JSMethod(uiThread = true)
   public void openURL(String url) {
@@ -44,6 +53,20 @@ public class WXEventModule extends WXModule {
     }
     String scheme = Uri.parse(url).getScheme();
     StringBuilder builder = new StringBuilder();
+
+    if ("weex://go/scan".equals(url)) {
+      if (ContextCompat.checkSelfPermission(mWXSDKInstance.getContext(), 
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+        if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) 
mWXSDKInstance.getContext(), Manifest.permission.CAMERA)) {
+          Toast.makeText(mWXSDKInstance.getContext(), "Weex playground need 
the camera permission to scan QR code", Toast.LENGTH_SHORT).show();
+        } else {
+          ActivityCompat.requestPermissions((Activity) 
mWXSDKInstance.getContext(), new String[]{Manifest.permission.CAMERA}, 
CAMERA_PERMISSION_REQUEST_CODE);
+        }
+      } else {
+        mWXSDKInstance.getContext().startActivity(new 
Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
+      }
+      return;
+    }
+
     if (TextUtils.equals("http", scheme) || TextUtils.equals("https", scheme) 
|| TextUtils.equals("file", scheme)) {
       builder.append(url);
     } else {
@@ -82,4 +105,12 @@ public class WXEventModule extends WXModule {
       callback.invoke(result);
     }
   }
+
+  @Override
+  public void onRequestPermissionsResult(int requestCode, String[] 
permissions, int[] grantResults) {
+    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 
0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+      mWXSDKInstance.getContext().startActivity(new 
Intent(mWXSDKInstance.getContext(), CaptureActivity.class));
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXTitleBar.java
----------------------------------------------------------------------
diff --git 
a/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXTitleBar.java
 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXTitleBar.java
new file mode 100644
index 0000000..733020c
--- /dev/null
+++ 
b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXTitleBar.java
@@ -0,0 +1,109 @@
+package com.alibaba.weex.extend.module;
+
+import android.app.Activity;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.weex.R;
+import com.taobao.weex.annotation.JSMethod;
+import com.taobao.weex.common.WXModule;
+import com.taobao.weex.utils.WXResourceUtils;
+
+
+/**
+ * Created by moxun on 12/01/2018.
+ */
+
+public class WXTitleBar extends WXModule {
+  @JSMethod
+  public void setTitle(String title) {
+    ActionBar actionBar = getActionBar();
+    if (actionBar != null) {
+      actionBar.setTitle(String.valueOf(title));
+    }
+  }
+
+  @JSMethod
+  public void setStyle(JSONObject object) {
+    String bgColor = object.getString("backgroundColor");
+    String color = object.getString("foregroundColor");
+    ActionBar actionBar = getActionBar();
+    if (actionBar != null) {
+      if (bgColor != null) {
+        int c = WXResourceUtils.getColor(bgColor);
+        actionBar.setBackgroundDrawable(new ColorDrawable(c));
+      }
+
+      if (color != null) {
+        int c = WXResourceUtils.getColor(color);
+
+        Toolbar toolbar = (Toolbar) ((Activity) 
mWXSDKInstance.getContext()).findViewById(R.id.toolbar);
+        if (toolbar != null) {
+          toolbar.setTitleTextColor(c);
+          toolbar.setSubtitleTextColor(c);
+
+          Drawable upNavigation = toolbar.getNavigationIcon();
+          if (null != upNavigation) {
+            upNavigation = DrawableCompat.wrap(upNavigation);
+            upNavigation = upNavigation.mutate();
+            DrawableCompat.setTint(upNavigation, c);
+            toolbar.setNavigationIcon(upNavigation);
+          }
+
+          Drawable overflowIcon = toolbar.getOverflowIcon();
+          if (null != overflowIcon) {
+            overflowIcon = DrawableCompat.wrap(overflowIcon);
+            overflowIcon = overflowIcon.mutate();
+            DrawableCompat.setTint(overflowIcon, c);
+            toolbar.setOverflowIcon(overflowIcon);
+          }
+
+          Menu menu = toolbar.getMenu();
+          if (menu != null && menu.size() > 0) {
+            for (int i = 0; i < menu.size(); i++) {
+              MenuItem item = menu.getItem(i);
+              if (item != null && item.getIcon() != null) {
+                Drawable drawable = item.getIcon();
+                if (null != drawable) {
+                  drawable = DrawableCompat.wrap(drawable);
+                  drawable = drawable.mutate();
+                  DrawableCompat.setTint(drawable, c);
+                  item.setIcon(drawable);
+                }
+              }
+            }
+            ((Activity) mWXSDKInstance.getContext()).invalidateOptionsMenu();
+          }
+        }
+      }
+    }
+  }
+
+  @JSMethod
+  public void showTitleBar(String isShow) {
+    ActionBar actionBar = getActionBar();
+    if (actionBar != null) {
+      if ("true".equals(isShow) && !actionBar.isShowing()) {
+        actionBar.show();
+      }
+
+      if ("false".equals(isShow) && actionBar.isShowing()) {
+        actionBar.hide();
+      }
+    }
+  }
+
+  private ActionBar getActionBar() {
+    if (mWXSDKInstance.getContext() instanceof AppCompatActivity) {
+      return ((AppCompatActivity) 
mWXSDKInstance.getContext()).getSupportActionBar();
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/res/values-v21/styles.xml
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/res/values-v21/styles.xml 
b/android/playground/app/src/main/res/values-v21/styles.xml
index f98bd65..9bd9d59 100755
--- a/android/playground/app/src/main/res/values-v21/styles.xml
+++ b/android/playground/app/src/main/res/values-v21/styles.xml
@@ -24,4 +24,8 @@ under the License.
         <item name="android:windowDrawsSystemBarBackgrounds">true</item>
         <item name="android:statusBarColor">@android:color/transparent</item>
     </style>
+
+    <style name="AppTheme.AppBarOverlay" 
parent="ThemeOverlay.AppCompat.Dark.ActionBar">
+        <item name="elevation">0dp</item>
+    </style>
 </resources>

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/res/values/colors.xml
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/res/values/colors.xml 
b/android/playground/app/src/main/res/values/colors.xml
index ad29c22..c115dc1 100755
--- a/android/playground/app/src/main/res/values/colors.xml
+++ b/android/playground/app/src/main/res/values/colors.xml
@@ -18,8 +18,8 @@ specific language governing permissions and limitations
 under the License.
 -->
 <resources>
-    <color name="colorPrimary">#3F51B5</color>
-    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorPrimary">#00B4FF</color>
+    <color name="colorPrimaryDark">#00B4FF</color>
     <color name="colorAccent">#FF4081</color>
 
     <color name="black_overlay">#66000000</color>

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/playground/app/src/main/res/values/styles.xml
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/res/values/styles.xml 
b/android/playground/app/src/main/res/values/styles.xml
index f0407f1..52fd8ac 100755
--- a/android/playground/app/src/main/res/values/styles.xml
+++ b/android/playground/app/src/main/res/values/styles.xml
@@ -31,7 +31,9 @@ under the License.
         <item name="windowNoTitle">true</item>
     </style>
 
-    <style name="AppTheme.AppBarOverlay" 
parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
+    <style name="AppTheme.AppBarOverlay" 
parent="ThemeOverlay.AppCompat.Dark.ActionBar">
+        <item name="elevation">0dp</item>
+    </style>
 
     <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/sdk/build.gradle
----------------------------------------------------------------------
diff --git a/android/sdk/build.gradle b/android/sdk/build.gradle
index a49a05f..26c8b28 100755
--- a/android/sdk/build.gradle
+++ b/android/sdk/build.gradle
@@ -40,7 +40,7 @@ checkstyle {
     toolVersion = '6.9'
 }
 
-version = "0.9.4"
+version = "0.17.0"
 
 android {
     compileSdkVersion project.compileSdkVersion

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java 
b/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
index 4731aa4..5548ced 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKEngine.java
@@ -89,7 +89,7 @@ import com.taobao.weex.ui.component.list.SimpleListComponent;
 import com.taobao.weex.ui.component.list.WXCell;
 import com.taobao.weex.ui.component.list.WXListComponent;
 import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList;
-import com.taobao.weex.ui.module.WXLocalModule;
+import com.taobao.weex.ui.module.WXLocaleModule;
 import com.taobao.weex.ui.module.WXMetaModule;
 import com.taobao.weex.ui.module.WXModalUIModule;
 import com.taobao.weex.ui.module.WXTimerModule;
@@ -323,7 +323,7 @@ public class WXSDKEngine {
       registerModule("picker", WXPickersModule.class);
       registerModule("meta", WXMetaModule.class,true);
       registerModule("webSocket", WebSocketModule.class);
-      registerModule("local", WXLocalModule.class);
+      registerModule("locale", WXLocaleModule.class);
 
 
       registerDomObject(simpleList, WXListDomObject.class);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/sdk/src/main/java/com/taobao/weex/adapter/DefaultWXHttpAdapter.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/adapter/DefaultWXHttpAdapter.java 
b/android/sdk/src/main/java/com/taobao/weex/adapter/DefaultWXHttpAdapter.java
index 5546a89..6e96756 100644
--- 
a/android/sdk/src/main/java/com/taobao/weex/adapter/DefaultWXHttpAdapter.java
+++ 
b/android/sdk/src/main/java/com/taobao/weex/adapter/DefaultWXHttpAdapter.java
@@ -92,7 +92,11 @@ public class DefaultWXHttpAdapter implements IWXHttpAdapter {
             listener.onHttpFinish(response);
           }
           if (e instanceof IOException) {
-            reporter.httpExchangeFailed((IOException) e);
+            try {
+              reporter.httpExchangeFailed((IOException) e);
+            } catch (Throwable t) {
+              t.printStackTrace();
+            }
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocalModule.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocalModule.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocalModule.java
deleted file mode 100644
index 5f6d8cb..0000000
--- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocalModule.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.taobao.weex.ui.module;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.LocaleList;
-import android.text.TextUtils;
-
-import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.annotation.JSMethod;
-import com.taobao.weex.bridge.JSCallback;
-import com.taobao.weex.common.WXModule;
-
-import java.util.Locale;
-
-/**
- * Created by moxun on 2017/9/26.
- *
- * Ref: https://tools.ietf.org/html/bcp47
- */
-
-public class WXLocalModule extends WXModule {
-
-  @JSMethod
-  public void getLanguage(JSCallback callback) {
-    callback.invoke(getLanguageTags());
-  }
-
-  @JSMethod
-  public void getLanguages(JSCallback callback) {
-    callback.invoke(getLanguageTags().split(","));
-  }
-
-  private String getLanguageTags() {
-    Context application = WXEnvironment.getApplication();
-    if (application != null) {
-      Resources res = application.getResources();
-      if (res != null) {
-        Configuration configuration = res.getConfiguration();
-        if (configuration != null) {
-          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            LocaleList localeList = configuration.getLocales();
-            return localeList.toLanguageTags();
-          } else {
-            Locale local = configuration.locale;
-            if (local != null) {
-              return toLanguageTag(local);
-            }
-          }
-        }
-      }
-    }
-    return "";
-  }
-
-  private String toLanguageTag(Locale locale) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      return locale.toLanguageTag();
-    } else {
-      StringBuilder sb = new StringBuilder();
-      String language = locale.getLanguage();
-      String script = locale.getScript();
-      String region = locale.getCountry();
-      sb.append(language);
-      if (!TextUtils.isEmpty(script)) {
-        sb.append("-").append(script);
-      }
-      if (!TextUtils.isEmpty(region)) {
-        sb.append("-").append(region);
-      }
-      return sb.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/bbb0817f/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocaleModule.java
----------------------------------------------------------------------
diff --git 
a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocaleModule.java 
b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocaleModule.java
new file mode 100644
index 0000000..9838c47
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXLocaleModule.java
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.module;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.LocaleList;
+import android.text.TextUtils;
+
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.annotation.JSMethod;
+import com.taobao.weex.bridge.JSCallback;
+import com.taobao.weex.common.WXModule;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Created by moxun on 2017/9/26.
+ * <p>
+ * Ref: https://tools.ietf.org/html/bcp47
+ */
+
+public class WXLocaleModule extends WXModule {
+
+  @JSMethod(uiThread = false)
+  public String getLanguage() {
+    return getLanguageTags();
+  }
+
+  @JSMethod(uiThread = false)
+  public void getLanguage(JSCallback callback) {
+    callback.invoke(getLanguageTags());
+  }
+
+  @JSMethod(uiThread = false)
+  public List<String> getLanguages() {
+    String[] tags = getLanguageTags().split(",");
+    return Arrays.asList(tags);
+  }
+
+  @JSMethod(uiThread = false)
+  public void getLanguages(JSCallback callback) {
+    callback.invoke(getLanguageTags().split(","));
+  }
+
+  private String getLanguageTags() {
+    Context application = WXEnvironment.getApplication();
+    if (application != null) {
+      Resources res = application.getResources();
+      if (res != null) {
+        Configuration configuration = res.getConfiguration();
+        if (configuration != null) {
+          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            LocaleList localeList = configuration.getLocales();
+            return localeList.toLanguageTags();
+          } else {
+            Locale local = configuration.locale;
+            if (local != null) {
+              return toLanguageTag(local);
+            }
+          }
+        }
+      }
+    }
+    return "";
+  }
+
+  private String toLanguageTag(Locale locale) {
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+      return locale.toLanguageTag();
+    } else {
+      StringBuilder sb = new StringBuilder();
+      String language = locale.getLanguage();
+      String script = locale.getScript();
+      String region = locale.getCountry();
+      sb.append(language);
+      if (!TextUtils.isEmpty(script)) {
+        sb.append("-").append(script);
+      }
+      if (!TextUtils.isEmpty(region)) {
+        sb.append("-").append(region);
+      }
+      return sb.toString();
+    }
+  }
+}

Reply via email to