| 27 | |
| 28 | import java.lang.ref.WeakReference; |
| 29 | public class JsCallback { |
| 30 | private static final String CALLBACK_JS_FORMAT = "javascript:%s.callback(%d, %d %s);"; |
| 31 | private int mIndex; |
| 32 | private boolean mCouldGoOn; |
| 33 | private WeakReference<WebView> mWebViewRef; |
| 34 | private int mIsPermanent; |
| 35 | private String mInjectedName; |
| 36 | |
| 37 | public JsCallback(WebView view, String injectedName, int index) { |
| 38 | mCouldGoOn = true; |
| 39 | mWebViewRef = new WeakReference<WebView>(view); |
| 40 | mInjectedName = injectedName; |
| 41 | mIndex = index; |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * 向网页执行js回调; |
| 46 | * @param args |
| 47 | * @throws JsCallbackException |
| 48 | */ |
| 49 | public void apply (Object... args) throws JsCallbackException { |
| 50 | if (mWebViewRef.get() == null) { |
| 51 | throw new JsCallbackException("the WebView related to the JsCallback has been recycled"); |
| 52 | } |
| 53 | if (!mCouldGoOn) { |
| 54 | throw new JsCallbackException("the JsCallback isn't permanent,cannot be called more than once"); |
| 55 | } |
| 56 | StringBuilder sb = new StringBuilder(); |
| 57 | for (Object arg : args){ |
| 58 | sb.append(","); |
| 59 | boolean isStrArg = arg instanceof String; |
| 60 | // 有的接口将Json对象转换成了String返回,这里不能加双引号,否则网页会认为是String而不是JavaScript对象; |
| 61 | boolean isObjArg = isJavaScriptObject(arg); |
| 62 | if (isStrArg && !isObjArg) { |
| 63 | sb.append("\""); |
| 64 | } |
| 65 | sb.append(String.valueOf(arg)); |
| 66 | if (isStrArg && !isObjArg) { |
| 67 | sb.append("\""); |
| 68 | } |
| 69 | } |
| 70 | String execJs = String.format(CALLBACK_JS_FORMAT, mInjectedName, mIndex, mIsPermanent, sb.toString()); |
| 71 | if (LogUtils.isDebug()) { |
| 72 | Log.d("JsCallBack", execJs); |
| 73 | } |
| 74 | mWebViewRef.get().loadUrl(execJs); |
| 75 | mCouldGoOn = mIsPermanent > 0; |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * 是否是JSON(JavaScript Object Notation)对象; |
| 80 | * @param obj |
| 81 | * @return |
| 82 | */ |
| 83 | private boolean isJavaScriptObject(Object obj) { |
| 84 | if (obj instanceof JSONObject || obj instanceof JSONArray) { |
| 85 | return true; |
| 86 | } else { |
nothing calls this directly
no outgoing calls
no test coverage detected