114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/uexDemo/src/com/test/EUExDemo.java:
--------------------------------------------------------------------------------
1 | package com.test;
2 |
3 | import android.app.Activity;
4 | import android.app.Service;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Vibrator;
8 | import android.util.Log;
9 | import android.view.View;
10 | import android.widget.RelativeLayout;
11 | import android.widget.Toast;
12 |
13 | import org.json.JSONException;
14 | import org.json.JSONObject;
15 | import org.zywx.wbpalmstar.base.BDebug;
16 | import org.zywx.wbpalmstar.engine.DataHelper;
17 | import org.zywx.wbpalmstar.engine.EBrowserView;
18 | import org.zywx.wbpalmstar.engine.universalex.EUExBase;
19 |
20 | public class EUExDemo extends EUExBase {
21 |
22 | private static final String TAG = "uexDemo";
23 |
24 | private int mFuncActivityCallback =-1;
25 | private static final int mMyActivityRequestCode = 10000;
26 |
27 | private static final String CALLBACK_ON_VIEW_BUTTON_CLICK = "uexDemo.onViewButtonClick";
28 | private static final String CALLBACK_ON_FRAGMENT_BUTTON_CLICK = "uexDemo.onFragmentButtonClick";
29 |
30 | private Vibrator m_v;
31 | private View mAddView;
32 | private ViewDataVO mAddViewData;
33 |
34 | private DemoFragment mAddFragmentView;
35 | private ViewDataVO mAddFragmentData;
36 |
37 | public EUExDemo(Context context, EBrowserView view) {
38 | super(context, view);
39 | }
40 |
41 | // ============= 分割线 ==============
42 | // 以下为生命周期事件监听方法,按需声明,不需要的话就不用声明。
43 |
44 | /**
45 | * 用于监听Application的onCreate事件,需要的写好这个方法用来接收引擎的通知。
46 | * 利用此方法可以解决绝大部分需要自定义Application的情况(AppCan插件中不允许自定义Application)
47 | *
48 | * @param context ApplicationContext上下文实例
49 | */
50 | public static void onApplicationCreate(Context context) {
51 | BDebug.i(TAG, TAG + " onApplicationCreate");
52 | }
53 |
54 | /**
55 | * 对应加载插件的引擎Activity的生命周期方法onCreate
56 | *
57 | * @param context 加载插件的引擎ActivityContext实例
58 | */
59 | public static void onActivityCreate(Context context) {
60 | BDebug.i(TAG, TAG + " onActivityCreate");
61 | }
62 |
63 | /**
64 | * 对应加载插件的引擎Activity的生命周期方法onStart
65 | *
66 | * @param context 加载插件的引擎ActivityContext实例
67 | */
68 | public static void onActivityStart(Context context) {
69 | BDebug.i(TAG, TAG + " onActivityStart");
70 | }
71 |
72 | /**
73 | * 对应加载插件的引擎Activity的生命周期方法onRestart
74 | *
75 | * @param context 加载插件的引擎ActivityContext实例
76 | */
77 | public static void onActivityReStart(Context context) {
78 | BDebug.i(TAG, TAG + " onActivityReStart");
79 | }
80 |
81 | /**
82 | * 对应加载插件的引擎Activity的生命周期方法onResume
83 | *
84 | * @param context 加载插件的引擎ActivityContext实例
85 | */
86 | public static void onActivityResume(Context context) {
87 | BDebug.i(TAG, TAG + " onActivityResume");
88 | }
89 |
90 | /**
91 | * 对应加载插件的引擎Activity的生命周期方法onPause
92 | *
93 | * @param context 加载插件的引擎ActivityContext实例
94 | */
95 | public static void onActivityPause(Context context) {
96 | BDebug.i(TAG, TAG + " onActivityPause");
97 | }
98 |
99 | /**
100 | * 对应加载插件的引擎Activity的生命周期方法onStop
101 | *
102 | * @param context 加载插件的引擎ActivityContext实例
103 | */
104 | public static void onActivityStop(Context context) {
105 | BDebug.i(TAG, TAG + " onActivityStop");
106 | }
107 |
108 | /**
109 | * 对应加载插件的引擎Activity的生命周期方法onDestroy
110 | *
111 | * @param context 加载插件的引擎ActivityContext实例
112 | */
113 | public static void onActivityDestroy(Context context) {
114 | BDebug.i(TAG, TAG + " onActivityDestroy");
115 | }
116 |
117 | // 以上为生命周期事件监听方法,按需声明,不需要的话就不用声明。
118 | // ============= 分割线 ==============
119 |
120 | public void test_addView(String[] parm) {
121 | if (parm.length < 1) {
122 | return;
123 | }
124 | mAddViewData = DataHelper.gson.fromJson(parm[0], ViewDataVO.class);
125 | if (mAddViewData == null){
126 | return;
127 | }
128 | if (mAddView != null){
129 | test_removeView(null);
130 | }
131 | // mContext变量是继承自父类的上下文,此Context实际上是加载本插件入口类对象的引擎Activity(4.0引擎中为EBrowserActivity的实例)
132 | mAddView = new DemoView(mContext, "我是一个添加的view的text",
133 | "view button", onViewButtonClick);
134 | if (mAddViewData.isScrollWithWebView()){
135 | android.widget.AbsoluteLayout.LayoutParams lp = new
136 | android.widget.AbsoluteLayout.LayoutParams(
137 | mAddViewData.getWidth(),
138 | mAddViewData.getHeight(),
139 | mAddViewData.getLeft(),
140 | mAddViewData.getTop());
141 | addViewToWebView(mAddView, lp, TAG);
142 | }else{
143 | RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
144 | mAddViewData.getWidth(), mAddViewData.getHeight());
145 | lp.leftMargin = mAddViewData.getLeft();
146 | lp.topMargin = mAddViewData.getTop();
147 | addViewToCurrentWindow(mAddView, lp);
148 | }
149 | }
150 |
151 | public void test_removeView(String[] params) {
152 | if (mAddViewData == null || mAddView == null){
153 | return;
154 | }
155 | if (mAddViewData.isScrollWithWebView()){
156 | removeViewFromWebView(TAG);
157 | }else{
158 | removeViewFromCurrentWindow(mAddView);
159 | mAddView = null;
160 | }
161 | }
162 |
163 | // this case start a Activity: HelloAppCanNativeActivity
164 | public void test_startActivityForResult(String[] parm) {
165 | if (parm.length>0) {
166 | // save the callbackId so you can callback to Javascript with it.
167 | mFuncActivityCallback = Integer.parseInt(parm[0]);
168 | }
169 | Intent intent = new Intent();
170 | intent.setClass(mContext, HelloAppCanNativeActivity.class);
171 | try {
172 | startActivityForResult(intent, mMyActivityRequestCode);
173 | } catch (Exception e) {
174 | Toast.makeText(mContext, "找不到此Activity!!", Toast.LENGTH_LONG)
175 | .show();
176 | }
177 | }
178 |
179 | // this case to use Vibrator
180 | public boolean test_vibrator(String[] parm) {
181 | if (parm.length < 1) {
182 | return false;
183 | }
184 | VibratorDataVO dataVO = DataHelper.gson.fromJson(parm[0], VibratorDataVO.class);
185 | double inMilliseconds = dataVO.getTime();
186 | try {
187 | if (null == m_v) {
188 | m_v = (Vibrator) mContext
189 | .getSystemService(Service.VIBRATOR_SERVICE);
190 | }
191 | if (m_v != null) {
192 | m_v.vibrate((int)inMilliseconds);
193 | } else {
194 | Toast.makeText(mContext, "Error: Vibrator is null", Toast.LENGTH_SHORT).show();
195 | }
196 | } catch (SecurityException e) {
197 | Toast.makeText(mContext, "未配置震动权限或参数错误!!", Toast.LENGTH_LONG)
198 | .show();
199 | return false;
200 | }
201 | return true;
202 | }
203 |
204 | // this case show a input dialog
205 | public void test_showInputDialog(String[] parm) {
206 | if (parm.length < 1) {
207 | return;
208 | }
209 | int funcDialogCallback = -1;
210 | if (parm.length>1){
211 | funcDialogCallback= Integer.parseInt(parm[1]);
212 | }
213 | DialogDataVO dataVO = DataHelper.gson.fromJson(parm[0], DialogDataVO.class);
214 | String defaultValue = dataVO.getDefaultValue();
215 | new DialogUtil(mContext, this).show(defaultValue,funcDialogCallback);
216 | }
217 |
218 | // this case show a custom view into window
219 | public void test_addFragment(String[] parm) {
220 | if (parm.length < 1) {
221 | return;
222 | }
223 | if (mAddFragmentView != null){
224 | test_removeFragment(null);
225 | }
226 | mAddFragmentData = DataHelper.gson.fromJson(parm[0], ViewDataVO.class);
227 | if (mAddFragmentData == null) return;
228 | mAddFragmentView = new DemoFragment();
229 | mAddFragmentView.setFragmentText("我是一个添加的fragment的text");
230 | mAddFragmentView.setFragmentButtonText("fragment button");
231 | mAddFragmentView.setOnButtonClick(onFragmentButtonClick);
232 | if (mAddFragmentData.isScrollWithWebView()){
233 | android.widget.AbsoluteLayout.LayoutParams lp = new
234 | android.widget.AbsoluteLayout.LayoutParams(
235 | mAddFragmentData.getWidth(),
236 | mAddFragmentData.getHeight(),
237 | mAddFragmentData.getLeft(),
238 | mAddFragmentData.getTop());
239 | addFragmentToWebView(mAddFragmentView, lp, TAG);
240 | }else{
241 | RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
242 | mAddFragmentData.getWidth(), mAddFragmentData.getHeight());
243 | lp.leftMargin = mAddFragmentData.getLeft();
244 | lp.topMargin = mAddFragmentData.getTop();
245 | addFragmentToCurrentWindow(mAddFragmentView, lp, TAG);
246 | }
247 |
248 | }
249 |
250 | // this case remove a custom view from window
251 | public void test_removeFragment(String[] parm) {
252 | if (mAddFragmentData == null || mAddFragmentView == null){
253 | return;
254 | }
255 | if (mAddFragmentData.isScrollWithWebView()){
256 | removeFragmentFromWebView(TAG);
257 | }else{
258 | removeFragmentFromWindow(mAddFragmentView);
259 | mAddFragmentView = null;
260 | }
261 | }
262 |
263 | /**
264 | * 用于执行JS回调方法
265 | *
266 | * @param methodName 回调方法名
267 | * @param jsonData 回调json数据
268 | */
269 | private void callBackPluginJs(String methodName, String jsonData){
270 | String js = SCRIPT_HEADER + "if(" + methodName + "){"
271 | + methodName + "('" + jsonData + "');}";
272 | onCallback(js);
273 | }
274 |
275 | /**
276 | * 用于执行JS回调方法(数据为JSON object)
277 | * 推荐此方式,防止极个别情况下,回调数据中存在异常字符导致JS处理错误 by yipeng
278 | *
279 | * @param methodName 回调方法名
280 | * @param jsonData 回调json数据
281 | */
282 | private void callBackPluginJsWithJsonObject(String methodName, String jsonData){
283 | String js = SCRIPT_HEADER + "if(" + methodName + "){"
284 | + methodName + "(" + jsonData + ");}";
285 | // 是否看出与上面方法的区别?传参的括号内少了单引号,这样可以让JS收到回调时拿到的就是一个JS的object,而无需使用JSON.parse
286 | onCallback(js);
287 | }
288 |
289 | // clean something
290 | @Override
291 | protected boolean clean() {
292 | return true;
293 | }
294 |
295 | @Override
296 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
297 | if (requestCode == mMyActivityRequestCode) {
298 | JSONObject jsonObject = new JSONObject();
299 | try {
300 | if (resultCode == Activity.RESULT_OK) {
301 | String ret = data.getStringExtra("result");
302 | jsonObject.put("result", ret);
303 | } else {
304 | jsonObject.put("result", "cancel");
305 | }
306 | } catch (JSONException e) {
307 | e.printStackTrace();
308 | }
309 | callbackToJs(mFuncActivityCallback,false,0, jsonObject);
310 | }
311 | }
312 |
313 | public interface OnButtonClick{
314 | void onButtonClick();
315 | }
316 |
317 | private OnButtonClick onViewButtonClick = new OnButtonClick() {
318 | @Override
319 | public void onButtonClick() {
320 | callBackPluginJs(CALLBACK_ON_VIEW_BUTTON_CLICK, "");
321 | }
322 | };
323 |
324 | private OnButtonClick onFragmentButtonClick = new OnButtonClick() {
325 | @Override
326 | public void onButtonClick() {
327 | callBackPluginJs(CALLBACK_ON_FRAGMENT_BUTTON_CLICK, "");
328 | }
329 | };
330 | }
331 |
--------------------------------------------------------------------------------
/uexDemo/assets/widget/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |