just to save some fucking works
This commit is contained in:
@@ -70,10 +70,10 @@ public class AutoJs implements AccessibilityBridge {
|
||||
.uiHandler(mUiHandler)
|
||||
.globalConsole(new JraskaConsole())
|
||||
.engineManger(manager)
|
||||
.runtime(new Supplier<ScriptRuntime>() {
|
||||
.runtime(new Supplier<com.stardust.autojs.runtime.ScriptRuntime>() {
|
||||
|
||||
@Override
|
||||
public ScriptRuntime get() {
|
||||
public com.stardust.autojs.runtime.ScriptRuntime get() {
|
||||
return new ScriptRuntime.Builder()
|
||||
.setAppUtils(mAppUtils)
|
||||
.setConsole(new StardustConsole(mUiHandler))
|
||||
|
||||
@@ -16,45 +16,16 @@ import com.stardust.util.UiHandler;
|
||||
public class ScriptRuntime extends com.stardust.autojs.runtime.ScriptRuntime {
|
||||
|
||||
|
||||
public static class Builder {
|
||||
private AppUtils mAppUtils;
|
||||
private UiHandler mUiHandler;
|
||||
private Console mConsole;
|
||||
private AccessibilityBridge mAccessibilityBridge;
|
||||
private Supplier<AbstractShell> mShellSupplier;
|
||||
public static class Builder extends com.stardust.autojs.runtime.ScriptRuntime.Builder {
|
||||
|
||||
|
||||
public Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder setAppUtils(AppUtils appUtils) {
|
||||
mAppUtils = appUtils;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUiHandler(UiHandler uiHandler) {
|
||||
mUiHandler = uiHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setConsole(Console console) {
|
||||
mConsole = console;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAccessibilityBridge(AccessibilityBridge accessibilityBridge) {
|
||||
mAccessibilityBridge = accessibilityBridge;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShellSupplier(Supplier<AbstractShell> shellSupplier) {
|
||||
mShellSupplier = shellSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScriptRuntime build() {
|
||||
return new ScriptRuntime(mAppUtils, mUiHandler, mConsole, mAccessibilityBridge, mShellSupplier);
|
||||
return new ScriptRuntime(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,9 +33,9 @@ public class ScriptRuntime extends com.stardust.autojs.runtime.ScriptRuntime {
|
||||
@ScriptVariable
|
||||
public Dialogs dialogs;
|
||||
|
||||
public ScriptRuntime(AppUtils appUtils, UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge, Supplier<AbstractShell> shellSupplier) {
|
||||
super(appUtils, uiHandler, console, accessibilityBridge, shellSupplier);
|
||||
dialogs = new Dialogs(appUtils, uiHandler);
|
||||
private ScriptRuntime(Builder builder) {
|
||||
super(builder);
|
||||
dialogs = new Dialogs(app, getUiHandler());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ public class InputEventToJsConverter extends InputEventConverter {
|
||||
|
||||
private class KeyHandler implements EventHandler {
|
||||
|
||||
private Map<String, String> mKeyPressCodeMap = new MapEntries<>(new HashMap<String, String>())
|
||||
private Map<String, String> mKeyPressCodeMap = new MapEntries<String, String>()
|
||||
.entry("KEY_HOME", "Home")
|
||||
.entry("KEY_MENU", "Menu")
|
||||
.entry("KEY_VOLUMEDOWN", "VolumeDown")
|
||||
|
||||
@@ -26,7 +26,7 @@ require("__general__")(__runtime__, this);
|
||||
|
||||
|
||||
(function(scope){
|
||||
var modules = ['app', 'automator', 'console', 'io', 'selector', 'shell', 'web'];
|
||||
var modules = ['app', 'automator', 'console', 'io', 'selector', 'shell', 'web', 'ui'];
|
||||
var len = modules.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var m = modules[i];
|
||||
|
||||
@@ -1,31 +1,13 @@
|
||||
|
||||
|
||||
ui.layout = function(layout){
|
||||
layout = layout[0];
|
||||
view = ui.inflate(layout);
|
||||
ui.setView(view);
|
||||
}
|
||||
|
||||
ui.inflate = function(xml){
|
||||
var name = xml.name();
|
||||
var view = ui.createView(name);
|
||||
ui.putAttributes(view, xml.attributes());
|
||||
ui.addChildren(view, xml.children());
|
||||
return view;
|
||||
}
|
||||
|
||||
ui.putAttributes = function(view, attrs){
|
||||
var len = attrs.length();
|
||||
for(var i = 0; i < len; i++){
|
||||
var attr = attrs[i];
|
||||
view.putAttribute(attr.name(), attr.toString());
|
||||
module.exports = function(__runtime__, scope){
|
||||
var ui = Object(__runtime__.ui);
|
||||
ui.layout = function(xml){
|
||||
view = ui.inflate(xml);
|
||||
ui.setView(view);
|
||||
}
|
||||
}
|
||||
|
||||
ui.addChildren = function(view, children){
|
||||
var len = children.length();
|
||||
for(var i = 0; i < len; i++){
|
||||
var child = children[i];
|
||||
view.addChild(ui.inflate(child));
|
||||
ui.setView = function(view){
|
||||
activity.setContentView(view);
|
||||
}
|
||||
}
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
@@ -141,12 +141,12 @@ public class RhinoJavaScriptEngine implements ScriptEngine {
|
||||
|
||||
protected Context createContext() {
|
||||
if (!ContextFactory.hasExplicitGlobal()) {
|
||||
//ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mEngineManager.getContext().getCacheDir(), "classes")));
|
||||
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mEngineManager.getContext().getCacheDir(), "classes")));
|
||||
}
|
||||
Context context = Context.enter();//new RhinoAndroidHelper(mEngineManager.getContext()).enterContext();
|
||||
Context context = new RhinoAndroidHelper(mEngineManager.getContext()).enterContext();
|
||||
contextCount++;
|
||||
context.setOptimizationLevel(-1);
|
||||
//context.setLanguageVersion(Context.VERSION_ES6);
|
||||
context.setLanguageVersion(Context.VERSION_ES6);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.stardust.autojs.runtime;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||
import com.stardust.autojs.runtime.api.AppUtils;
|
||||
import com.stardust.autojs.runtime.api.Console;
|
||||
import com.stardust.autojs.runtime.api.UiSelector;
|
||||
import com.stardust.autojs.runtime.api.ui.UI;
|
||||
import com.stardust.autojs.runtime.simple_action.SimpleActionAutomator;
|
||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||
|
||||
@@ -26,11 +29,15 @@ public abstract class AbstractScriptRuntime {
|
||||
@ScriptVariable
|
||||
public AccessibilityInfoProvider info;
|
||||
|
||||
public AbstractScriptRuntime(AppUtils app, Console console, AccessibilityBridge bridge) {
|
||||
@ScriptVariable
|
||||
public UI ui;
|
||||
|
||||
public AbstractScriptRuntime(AppUtils app, Console console, AccessibilityBridge bridge, UI ui) {
|
||||
this.app = app;
|
||||
this.console = console;
|
||||
this.automator = new SimpleActionAutomator(bridge, this);
|
||||
this.info = bridge.getInfoProvider();
|
||||
this.ui = ui;
|
||||
}
|
||||
|
||||
public AbstractScriptRuntime() {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.stardust.autojs.runtime.api.AppUtils;
|
||||
import com.stardust.autojs.runtime.api.Console;
|
||||
import com.stardust.autojs.runtime.api.UiSelector;
|
||||
import com.stardust.autojs.runtime.api.internal.VolatileBox;
|
||||
import com.stardust.autojs.runtime.api.ui.UI;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.autojs.runtime.api.ProcessShell;
|
||||
@@ -39,6 +40,7 @@ public class ScriptRuntime extends AbstractScriptRuntime {
|
||||
private Console mConsole;
|
||||
private AccessibilityBridge mAccessibilityBridge;
|
||||
private Supplier<AbstractShell> mShellSupplier;
|
||||
public UI mUi;
|
||||
|
||||
|
||||
public Builder() {
|
||||
@@ -70,8 +72,13 @@ public class ScriptRuntime extends AbstractScriptRuntime {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUI(UI ui) {
|
||||
mUi = ui;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScriptRuntime build() {
|
||||
return new ScriptRuntime(mAppUtils, mUiHandler, mConsole, mAccessibilityBridge, mShellSupplier);
|
||||
return new ScriptRuntime(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,11 +90,14 @@ public class ScriptRuntime extends AbstractScriptRuntime {
|
||||
private Supplier<AbstractShell> mShellSupplier;
|
||||
|
||||
|
||||
protected ScriptRuntime(AppUtils appUtils, UiHandler uiHandler, Console console, AccessibilityBridge accessibilityBridge, Supplier<AbstractShell> shellSupplier) {
|
||||
super(appUtils, console, accessibilityBridge);
|
||||
mAccessibilityBridge = accessibilityBridge;
|
||||
mUiHandler = uiHandler;
|
||||
mShellSupplier = shellSupplier;
|
||||
protected ScriptRuntime(Builder builder) {
|
||||
super(builder.mAppUtils, builder.mConsole, builder.mAccessibilityBridge, builder.mUi);
|
||||
mAccessibilityBridge = builder.mAccessibilityBridge;
|
||||
mUiHandler = builder.mUiHandler;
|
||||
mShellSupplier = builder.mShellSupplier;
|
||||
if (ui == null) {
|
||||
ui = new UI(mUiHandler.getContext());
|
||||
}
|
||||
}
|
||||
|
||||
public UiHandler getUiHandler() {
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public interface AttributeHandler {
|
||||
|
||||
boolean handle(String nodeName, Node attr, StringBuilder layoutXml);
|
||||
|
||||
class AttrNameRouter implements AttributeHandler {
|
||||
|
||||
private Map<String, AttributeHandler> mHandlerMap = new HashMap<>();
|
||||
private AttributeHandler mDefaultHandler;
|
||||
|
||||
@Override
|
||||
public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) {
|
||||
AttributeHandler handler = mHandlerMap.get(attr.getNodeName());
|
||||
if (handler == null)
|
||||
handler = mDefaultHandler;
|
||||
return handler != null && handler.handle(nodeName, attr, layoutXml);
|
||||
}
|
||||
|
||||
public AttrNameRouter registerHandler(String attrName, AttributeHandler handler) {
|
||||
mHandlerMap.put(attrName, handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttrNameRouter setDefaultHandler(AttributeHandler defaultHandler) {
|
||||
mDefaultHandler = defaultHandler;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
class MappedAttributeHandler implements AttributeHandler {
|
||||
|
||||
private Map<String, String> mAttrNameMap = new HashMap<>();
|
||||
private Map<String, Map<String, String>> mAttrValueMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) {
|
||||
layoutXml.append("android:").append(mapAttrName(nodeName, attr.getNodeName()))
|
||||
.append("=\"").append(mapAttrValue(nodeName, attr.getNodeName(), attr.getNodeValue())).append("\"\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
public MappedAttributeHandler putAttrNameMap(String oldAttrName, String newAttrName) {
|
||||
mAttrNameMap.put(oldAttrName, newAttrName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MappedAttributeHandler putAttrValueMap(String attrName, String oldValue, String newValue) {
|
||||
Map<String, String> valueMap = mAttrValueMap.get(attrName);
|
||||
if (valueMap == null) {
|
||||
valueMap = new HashMap<>();
|
||||
mAttrValueMap.put(attrName, valueMap);
|
||||
}
|
||||
valueMap.put(oldValue, newValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private String mapAttrName(String nodeName, String attrName) {
|
||||
String mappedAttrName = mAttrNameMap.get(attrName);
|
||||
if (mappedAttrName == null)
|
||||
return attrName;
|
||||
return mappedAttrName;
|
||||
}
|
||||
|
||||
private String mapAttrValue(String nodeName, String attrName, String value) {
|
||||
Map<String, String> valueMap = mAttrValueMap.get(attrName);
|
||||
if (valueMap == null)
|
||||
return value;
|
||||
String mappedValue = valueMap.get(value);
|
||||
return mappedValue == null ? value : mappedValue;
|
||||
}
|
||||
}
|
||||
|
||||
class IdHandler implements AttributeHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) {
|
||||
layoutXml.append("android:id=\"@+id/").append(attr.getNodeValue()).append("\"\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class DimenHandler implements AttributeHandler {
|
||||
|
||||
private String mAttrName;
|
||||
|
||||
public DimenHandler(String attrName) {
|
||||
mAttrName = attrName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) {
|
||||
String dimen = convertToAndroidDimen(attr.getNodeName());
|
||||
layoutXml.append("android:").append(mAttrName).append("=\"").append(dimen).append("\"\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static String convertToAndroidDimen(String dimen) {
|
||||
if (dimen.equals("*")) {
|
||||
return "match_parent";
|
||||
}
|
||||
if (dimen.equals("auto")) {
|
||||
return "wrap_content";
|
||||
}
|
||||
if (Character.isDigit(dimen.charAt(dimen.length() - 1))) {
|
||||
return dimen + "dp";
|
||||
}
|
||||
return dimen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/13.
|
||||
*/
|
||||
|
||||
public interface AttributeSetter<V extends View> {
|
||||
|
||||
boolean putAttribute(V view, String value);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/13.
|
||||
*/
|
||||
|
||||
public class AttributeSetters<V extends View> {
|
||||
|
||||
private Map<String, AttributeSetter<V>> mAttributeSetters = new HashMap<>();
|
||||
|
||||
|
||||
public boolean putAttribute(V view, String name, String value) {
|
||||
AttributeSetter<V> setter = mAttributeSetters.get(name);
|
||||
return setter != null && setter.putAttribute(view, value);
|
||||
}
|
||||
|
||||
public AttributeSetters<V> registerAttributeSetter(String name, AttributeSetter<V> setter) {
|
||||
mAttributeSetters.put(name, setter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void removeAttributeSetter(String name) {
|
||||
mAttributeSetters.remove(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Xml;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class ConvertLayoutInflater implements JsLayoutInflater {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
public ConvertLayoutInflater(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View inflate(String xml) {
|
||||
try {
|
||||
// 我靠%>_<% 弄完了xml转换以后发现android并不能动态inflate非resources的xml啊啊啊啊啊啊
|
||||
String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml);
|
||||
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
|
||||
XmlPullParser parser = factory.newPullParser();
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
parser.setInput(new StringReader(androidLayoutXml));
|
||||
return inflater.inflate(parser, null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public interface JsLayoutInflater {
|
||||
|
||||
View inflate(String xml);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/13.
|
||||
*/
|
||||
|
||||
public class JsLinearLayout extends LinearLayout {
|
||||
|
||||
private static final AttributeSetters<JsLinearLayout> LINEAR_LAYOUT_ATTRIBUTE_SETTERS = new AttributeSetters<JsLinearLayout>()
|
||||
.registerAttributeSetter("orientation", new AttributeSetter<JsLinearLayout>() {
|
||||
@Override
|
||||
public boolean putAttribute(JsLinearLayout layout, String value) {
|
||||
switch (value) {
|
||||
case "vertical":
|
||||
layout.setOrientation(VERTICAL);
|
||||
return true;
|
||||
case "horizontal":
|
||||
layout.setOrientation(HORIZONTAL);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
public JsLinearLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public JsLinearLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public JsLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public JsLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public void putAttribute(String name, String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class JsViewHelper {
|
||||
|
||||
private View mView;
|
||||
|
||||
public JsViewHelper(View view) {
|
||||
|
||||
}
|
||||
|
||||
public void w(String width) {
|
||||
float w = toPixel(width);
|
||||
|
||||
}
|
||||
|
||||
public static float toPixel(String dimen) {
|
||||
if (dimen.equals("*")) {
|
||||
return ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
}
|
||||
if (dimen.equals("auto")) {
|
||||
return ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
}
|
||||
if (Character.isDigit(dimen.charAt(dimen.length() - 1))) {
|
||||
return Float.parseFloat(dimen);
|
||||
}
|
||||
float f = Float.parseFloat(dimen.substring(0, dimen.length() - 2));
|
||||
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
|
||||
if (dimen.endsWith("dp")) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, f, metrics);
|
||||
}
|
||||
if (dimen.endsWith("sp")) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, f, metrics);
|
||||
}
|
||||
throw new IllegalArgumentException(dimen);
|
||||
}
|
||||
|
||||
public void h(String height) {
|
||||
|
||||
}
|
||||
|
||||
public void gravity(String gravity) {
|
||||
|
||||
}
|
||||
|
||||
public void align(String alignment) {
|
||||
|
||||
}
|
||||
|
||||
public void padding(String padding) {
|
||||
|
||||
}
|
||||
|
||||
public void margin(String margin) {
|
||||
|
||||
}
|
||||
|
||||
public void bg(String background) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class MethodMapper<O> {
|
||||
|
||||
public interface IMethod<O> {
|
||||
|
||||
Object call(O receiver, Object... params);
|
||||
}
|
||||
|
||||
private Class<O> mType;
|
||||
|
||||
public MethodMapper(Class<O> type) {
|
||||
mType = type;
|
||||
}
|
||||
|
||||
private Map<String, IMethod<O>> mMethodMap = new HashMap<>();
|
||||
|
||||
public void put(String methodName, String actualMethodName) {
|
||||
final Method method = getMethod(methodName);
|
||||
mMethodMap.put(methodName, new IMethod<O>() {
|
||||
@Override
|
||||
public Object call(O obj, Object... params) {
|
||||
try {
|
||||
return method.invoke(obj, params);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Method getMethod(String methodName) {
|
||||
for (Method method : mType.getMethods()) {
|
||||
if (method.getName().equals(methodName))
|
||||
return method;
|
||||
}
|
||||
throw new RuntimeException(new NoSuchMethodException(methodName));
|
||||
}
|
||||
|
||||
public void put(String methodName, IMethod<O> iMethod) {
|
||||
mMethodMap.put(methodName, iMethod);
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(String methodName, O obj, Object... params) {
|
||||
IMethod<O> iMethod = mMethodMap.get(methodName);
|
||||
if (iMethod == null)
|
||||
throw new RuntimeException(new NoSuchMethodException(methodName));
|
||||
return iMethod.call(obj, params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class UI {
|
||||
|
||||
private Context mContext;
|
||||
private JsLayoutInflater mJsLayoutInflater;
|
||||
|
||||
public UI(Context context, JsLayoutInflater layoutInflater) {
|
||||
mContext = context;
|
||||
mJsLayoutInflater = layoutInflater;
|
||||
}
|
||||
|
||||
|
||||
public UI(Context context) {
|
||||
this(context, new ConvertLayoutInflater(context));
|
||||
}
|
||||
|
||||
public JsLayoutInflater getLayoutInflater() {
|
||||
return mJsLayoutInflater;
|
||||
}
|
||||
|
||||
public View inflate(String xml) {
|
||||
return mJsLayoutInflater.inflate(xml);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class ViewAttributeSetters extends AttributeSetters<View> {
|
||||
|
||||
private static ViewAttributeSetters setters;
|
||||
|
||||
public ViewAttributeSetters() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import com.stardust.util.MapEntries;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
|
||||
public class XmlConverter {
|
||||
|
||||
private static final Map<String, String> NODE_NAME_MAP = new MapEntries<String, String>()
|
||||
.entry("linear", "LinearLayout")
|
||||
.entry("button", "Button")
|
||||
.entry("text", "TextView")
|
||||
.entry("input", "EditText")
|
||||
.map();
|
||||
|
||||
|
||||
private static final AttributeHandler ATTRIBUTE_HANDLER = new AttributeHandler.AttrNameRouter()
|
||||
.registerHandler("w", new AttributeHandler.DimenHandler("width"))
|
||||
.registerHandler("h", new AttributeHandler.DimenHandler("height"))
|
||||
.registerHandler("id", new AttributeHandler.IdHandler())
|
||||
.setDefaultHandler(new AttributeHandler.MappedAttributeHandler()
|
||||
.putAttrNameMap("align", "layout_gravity")
|
||||
.putAttrNameMap("bg", "background"));
|
||||
|
||||
public static String convertToAndroidLayout(String xml) throws IOException, SAXException, ParserConfigurationException {
|
||||
return convertToAndroidLayout(new InputSource(new StringReader(xml)));
|
||||
}
|
||||
|
||||
public static String convertToAndroidLayout(InputSource source) throws ParserConfigurationException, IOException, SAXException {
|
||||
StringBuilder layoutXml = new StringBuilder();
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document document = builder.parse(source);
|
||||
handleNode(document.getFirstChild(), "xmlns:android=\"http://schemas.android.com/apk/res/android\"", layoutXml);
|
||||
return layoutXml.toString();
|
||||
}
|
||||
|
||||
private static void handleNode(Node node, String namespace, StringBuilder layoutXml) {
|
||||
String nodeName = node.getNodeName();
|
||||
String mappedNodeName = mapNodeName(nodeName);
|
||||
layoutXml.append("<").append(mappedNodeName).append(" ").append(namespace).append("\n");
|
||||
handleText(nodeName, node.getTextContent(), layoutXml);
|
||||
handleAttributes(nodeName, node.getAttributes(), layoutXml);
|
||||
layoutXml.append(">\n");
|
||||
handleChildren(node.getChildNodes(), layoutXml);
|
||||
layoutXml.append("</").append(mappedNodeName).append(">\n");
|
||||
}
|
||||
|
||||
private static void handleText(String nodeName, String textContent, StringBuilder layoutXml) {
|
||||
if (textContent == null || textContent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (nodeName.equals("text") || nodeName.equals("button"))
|
||||
layoutXml.append("android:text=\"").append(textContent).append("\"\n");
|
||||
}
|
||||
|
||||
private static void handleChildren(NodeList nodes, StringBuilder layoutXml) {
|
||||
if (nodes == null)
|
||||
return;
|
||||
int len = nodes.getLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Node node = nodes.item(i);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
handleNode(node, "", layoutXml);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void handleAttributes(String nodeName, NamedNodeMap attributes, StringBuilder layoutXml) {
|
||||
if (attributes == null)
|
||||
return;
|
||||
int len = attributes.getLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Node attr = attributes.item(i);
|
||||
handleAttribute(nodeName, attr, layoutXml);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleAttribute(String nodeName, Node attr, StringBuilder layoutXml) {
|
||||
ATTRIBUTE_HANDLER.handle(nodeName, attr, layoutXml);
|
||||
}
|
||||
|
||||
private static String mapNodeName(String nodeName) {
|
||||
String str = NODE_NAME_MAP.get(nodeName);
|
||||
return str == null ? nodeName : str;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.stardust.autojs;
|
||||
|
||||
import org.junit.Test;
|
||||
import com.stardust.autojs.runtime.api.ui.XmlConverter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
@@ -10,8 +17,6 @@ import static org.junit.Assert.*;
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.stardust.autojs.runtime.api.ui;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/14.
|
||||
*/
|
||||
public class XmlConverterTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testNodeNameMap() throws IOException, SAXException, ParserConfigurationException {
|
||||
System.out.println(XmlConverter.convertToAndroidLayout("<linear></linear>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttrNameMap() throws IOException, SAXException, ParserConfigurationException {
|
||||
System.out.println(XmlConverter.convertToAndroidLayout("<linear w=\"*\" h=\"123\"></linear>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMappedNodeName() throws IOException, SAXException, ParserConfigurationException {
|
||||
System.out.println(XmlConverter.convertToAndroidLayout(("<others></others>")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChildrenNode() throws ParserConfigurationException, SAXException, IOException {
|
||||
System.out.println(XmlConverter.convertToAndroidLayout("<linear w=\"*\" h=\"123\"><text id=\"aaa\"/><button bg=\"#ffffff\"/></linear>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTextContent() throws ParserConfigurationException, SAXException, IOException {
|
||||
System.out.println(XmlConverter.convertToAndroidLayout("<linear><text id=\"aaa\">some text</text></linear>"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.stardust.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@@ -12,7 +13,7 @@ public class MapEntries<K, V> {
|
||||
private Map<K, V> mMap;
|
||||
|
||||
public MapEntries() {
|
||||
this(new TreeMap<K, V>());
|
||||
this(new HashMap<K, V>());
|
||||
}
|
||||
|
||||
public MapEntries(Map<K, V> map) {
|
||||
|
||||
Reference in New Issue
Block a user