信息发布软件,b2b软件,广告发布软件

 找回密码
 立即注册
搜索
查看: 2924|回复: 2
打印 上一主题 下一主题

[『 Java 图文教程』] 代理模式之Java动态代理和多种方法实例教程

  [复制链接]

65

主题

176

帖子

1557

积分

积分
1557
跳转到指定楼层
宣传软件楼主
发表于 2016-9-26 13:45:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

软件教程首图:

软件教程分类:Java 图文教程 

软件图文教程视频教程分类:软件图文教程 

软件教程难易程度:软件初级教程 

软件教程发布日期:2016-09-26

软件教程关键字:Java动态代理

① 本信息收集于网络,如有不对的地方欢迎联系我纠正!
② 本信息免费收录,不存在价格的问题!
③ 如果您的网站也想这样出现在这里,请您加好友情链接,我当天会审核通过!

④友情链接关键字:软件定制网站 网址:http://www.postbbs.com

软件教程详细描述

  1. Overview

Java在java.lang.reflect包下,定义了自己的代理。利用这个包下的类,我们可以在运行时动态地创建一个代理类,实现一个或多个接口。并将方法的调用转发到你所指定的类。因为实际代理是在运行时创建的,所以称为:动态代理。

代理模式之Java动态代理和多种方法实例教程 b2b软件

Proxy:完全由java产生的,而且实现了完整的subject接口。

InvocationHandler:Proxy上的任何方法调用都会被传入此类,InvocationHandler控制对RealSubject的访问。

因为Java已经帮助我们创建了Proxy类,我们需要有办法告诉Proxy类你要做什么,我们不能像以前一样把代码写入到Proxy类中,因为Proxy类不是我们实现的。那么我们应该放在哪里?放在InvocationHandler类中,InvocationHandler类是响应代理的任何调用。我们可以吧InvocationHandler想成是代理收到方法调用后,请求做实际工作的对象。

  2. java.lang.reflect.InvocationHandler

被代理实例所实现的一个接口,内部只有一个invoke()方法,签名如下;

Java代码

public Object invoke(Object proxy, Method method, Object[] args)

当代理的方法被调用的时候,代理就会把这个调用转发给InvocationHandler,也就会调用它的invoke()方法。


  3. java.lang.reflect.Proxy

提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类,我们经常使用的静态方式是:

Java代码

newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

  4. 示例:

情形:自己可以查看修改姓名性别,但是不能修改rate。他人可以查看姓名,性别以及修改rate,但是不能修改姓名性别。

4.1 定义一个接口:

Java代码

public interface Person {

String getName();

String getGender();

void setName(String name);

void setGender(String gender);

void setRate(int rate);

int getRate();

}

4.2 定义实现Person接口类

Java代码

public class PersonImpl implements Person {

String name;

String gender;

String interests;

int rate;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getGender() {

return gender;

}

public void setGender(String gender) {

this.gender = gender;

}

public String getInterests() {

return interests;

}


public void setInterests(String interests) {

this.interests = interests;

}

public int getRate() {

return rate;

}

public void setRate(int rate) {

this.rate = rate;

}[nextpage]

4.3 定义OwnerInvocationHandler类,表示如果为本人,则可以进行修改查看姓名性别。

Java代码

public class OwnerInvocationHandler implements InvocationHandler{

private Person personBean;

public OwnerInvocationHandler(Person personBean){

this.personBean = personBean;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws IllegalAccessException {

try {

if(method.getName().startsWith("get")){//如果方法名为get,就调用person类内的get相应方法

return method.invoke(personBean, args);

}else if(method.getName().equals("setRate")){ // 如果方法是setRate,则抛出异常

throw new IllegalAccessException("access deny");

}else if(method.getName().startsWith("set")){ //如果为set,就调用person类内的set相应方法

return method.invoke(personBean, args);

}else {

System.out.println("non method invoke");

}

} catch (InvocationTargetException e) {

e.printStackTrace();

}

return null;

}

}

4.4 定义NonInvocationHandler类,表示如果不为本人,则可以进行查看姓名性别和修改rate。

Java代码

public class NonInvocationHandler implements InvocationHandler{

//


private Person person;

public NonInvocationHandler(Person person){

this.person = person;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

if(method.getName().startsWith("setRate")){

return method.invoke(person, args);

}else if (method.getName().startsWith("get")){

return method.invoke(person, args);

} else {

System.out.println("non method invoke");

return null;

}

}

}

4.5 测试类MyDynamicProxy

Java代码

public class MyDynamicProxy {

public Person getOwnerPersonBeanProxy(Person person){

return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),

person.getClass().getInterfaces(), new OwnerInvocationHandler(person));

}

public Person getNonPersonBeanProxy(Person person){

return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),

person.getClass().getInterfaces(), new NonInvocationHandler(person));

}

public static void main(String[] args) {

MyDynamicProxy mdp = new MyDynamicProxy();

mdp.test();

}

public void test(){

//

Person person = getPersonBeanFromDB1();

Person personProxy = getOwnerPersonBeanProxy(person);

System.out.println(personProxy.getName());

try {

personProxy.setRate(2);

} catch (Exception e) {

System.out.println("can not setRate");

}

//

Person person1 = getPersonBeanFromDB1();

Person personProxy2 = getNonPersonBeanProxy(person1);

System.out.println(personProxy2.getName());

personProxy2.setRate(2);

System.out.println(personProxy2.getRate());

}

private Person getPersonBeanFromDB1(){

Person pb = new PersonImpl();

pb.setName("remy");

pb.setGender("girl");

pb.setRate(1);

return pb; }

输出结果:

Java代码

remy can not setRate remy 2



unto高性能JAVA代码之_内存管理和多方法实例教程nextJava技巧:深拷贝的两种方式

QQ截图20160923101820.jpg (8.19 KB, 下载次数: 152750)

QQ截图20160923101820.jpg
回复

使用道具 举报

65

主题

176

帖子

1557

积分

积分
1557
信息发布软件沙发
 楼主| 发表于 2016-9-26 13:46:08 | 只看该作者
本帖最后由 宣传工具 于 2016-9-26 13:47 编辑

多实例教程2


不定期整理硬盘内源代码、笔记、总结等,同时发上来分享一下。今天再发一篇关于Java动态代理的总结(貌似ItEye一天最多发5篇Blog,再多只能放草稿箱了?)
-----------------------------------------------------------
Java动态代理详解
说到动态代理,顾名思义就是动态的代理(真是废话)。
关于代理:想必大家都并不陌生,GOF的23种设计模式之一(结构型模式)。这里暂不多做介绍,有兴趣的可以关注我关于设计模式的文章。
什么是动态代理:
说起动态,其实不如先说什么是静态。所谓静态代理,个人理解为自己手写的代理类,或者用工具生成的代理类,或者别人帮你写的代理类(没说一样...)。总之,就是程序运行前就已经存在的编译好的代理类。
相反,如果代理类程序运行前并不存在,需要在程序运行时动态生成(无需手工编写代理类源码),那就是今天要说的动态代理了。
如何生成的:根据Java的反射机制动态生成。
不多说了,上程序。
目标接口TargetInterface:
Java代码  [url=][/url]

  • public interface TargetInterface {  
  •     public int targetMethodA(int number);  
  •     public int targetMethodB(int number);  
  • }  

很简单,一个普通的接口,里面有若干方法(此处写2个示范一下)
实现该接口的委托类ConcreteClass:
Java代码  [url=][/url]

  • public class ConcreteClass implements TargetInterface{  
  •   
  •     public int targetMethodA(int number) {  
  •         System.out.println("开始调用目标类的方法targetMethodA...");  
  •         System.out.println("操作-打印数字:"+number);  
  •         System.out.println("结束调用目标类的方法targetMethodA...");  
  •         return number;  
  •     }  
  •       
  •     public int targetMethodB(int number){  
  •         System.out.println("开始调用目标类的方法targetMethodB...");  
  •         System.out.println("操作-打印数字:"+number);  
  •         System.out.println("结束调用目标类的方法targetMethodB...");  
  •         return number;  
  •     }  
  •   
  • }  

很简单,一个普通的类,实现了目标接口。
代理处理器类ProxyHandler:
Java代码  [url=][/url]

  • public class ProxyHandler implements InvocationHandler{  
  •     private Object concreteClass;  
  •       
  •     public ProxyHandler(Object concreteClass){  
  •         this.concreteClass=concreteClass;  
  •     }  
  •   
  •     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  •         System.out.println("proxy:"+proxy.getClass().getName());  
  •         System.out.println("method:"+method.getName());  
  •         System.out.println("args:"+args[0].getClass().getName());  
  •          
  •         System.out.println("Before invoke method...");  
  •         Object object=method.invoke(concreteClass, args);//普通的Java反射代码,通过反射执行某个类的某方法  
  •         //System.out.println(((ConcreteClass)concreteClass).targetMethod(10)+(Integer)args[0]);  
  •         System.out.println("After invoke method...");  
  •         return object;  
  •     }  
  •   
  • }  

该类实现了Java反射包中的InvocationHandler接口。代理实例调用方法时,将对方法调用指派到它的代理处理器程序的invoke方法中。invoke方法内部实现预处理,对委托类方法调用,事后处理等逻辑。
最后是入口程序:
Java代码  [url=][/url]

  • public class DynamicProxyExample {  
  •     public static void main(String[] args){  
  •          ConcreteClass c=new ConcreteClass();//元对象(被代理对象)  
  •          InvocationHandler ih=new ProxyHandler(c);//代理实例的调用处理程序。  
  •          //创建一个实现业务接口的代理类,用于访问业务类(见代理模式)。  
  •          //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序,如ProxyHandler。  
  •          TargetInterface targetInterface=  
  •              (TargetInterface)Proxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),ih);  
  •          //调用代理类方法,Java执行InvocationHandler接口的方法.  
  •          int i=targetInterface.targetMethodA(5);  
  •          System.out.println(i);  
  •          System.out.println();  
  •          int j=targetInterface.targetMethodB(15);  
  •          System.out.println(j);  
  •     }  
  • }  

首先创建委托类对象,将其以构造函数传入代理处理器,代理处理器ProxyHandler中会以Java反射方式调用该委托类对应的方法。然后使用Java反射机制中的Proxy.newProxyInstance方式创建一个代理类实例,创建该实例需要指定该实例的类加载器,需要实现的接口(即目标接口),以及处理代理实例接口调用的处理器。
最后,调用代理类目标接口方法时,会自动将其转发到代理处理器中的invoke方法内,invoke方法内部实现预处理,对委托类方法调用,事后处理等逻辑。
使用Java动态代理机制的好处:
1、减少编程的工作量:假如需要实现多种代理处理逻辑,只要写多个代理处理器就可以了,无需每种方式都写一个代理类。
2、系统扩展性和维护性增强,程序修改起来也方便多了(一般只要改代理处理器类就行了)。
使用Java动态代理机制的限制:
目前根据GOF的代理模式,代理类和委托类需要都实现同一个接口。也就是说只有实现了某个接口的类可以使用Java动态代理机制。但是,事实上使用中并不是遇到的所有类都会给你实现一个接口。因此,对于没有实现接口的类,目前无法使用该机制。有人说这不是废话吗,本来Proxy模式定义的就是委托类要实现接口的啊!但是没有实现接口的类,该如何实现动态代理呢?
当然不是没有办法,这也是我后面抽时间要继续整理和总结原先使用过的一件神器,相关Blog会不定期发上来。那就是大名鼎鼎的CGLib...


回复 支持 反对

使用道具 举报

65

主题

176

帖子

1557

积分

积分
1557
推广工具板凳
 楼主| 发表于 2016-9-26 13:48:39 | 只看该作者
实例教程3


定义:为其他对象提供一种代理以控制对这个对象的访问。
代理模式的结构如下图所示。
动态代理使用
java动态代理机制以巧妙的方式实现了代理模式的设计理念。
代理模式示例代码
代理模式之Java动态代理和多种方法实例教程 b2b软件
public interface Subject   {     public void doSomething();   }   public class RealSubject implements Subject   {     public void doSomething()     {       System.out.println( "call doSomething()" );     }   }   public class ProxyHandler implements InvocationHandler   {     private Object proxied;          public ProxyHandler( Object proxied )     {       this.proxied = proxied;     }          public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable     {       //在转调具体目标对象之前,可以执行一些功能处理    //转调具体目标对象的方法    return method.invoke( proxied, args);          //在转调具体目标对象之后,可以执行一些功能处理  }    } 代理模式之Java动态代理和多种方法实例教程 b2b软件


代理模式之Java动态代理和多种方法实例教程 b2b软件
import java.lang.reflect.InvocationHandler;   import java.lang.reflect.Method;   import java.lang.reflect.Proxy;   import sun.misc.ProxyGenerator;   import java.io.*;   public class DynamicProxy   {     public static void main( String args[] )     {       RealSubject real = new RealSubject();       Subject proxySubject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(),      new Class[]{Subject.class},      new ProxyHandler(real));             proxySubject.doSomething();       //write proxySubject class binary data to file       createProxyClassFile();     }          public static void createProxyClassFile()     {       String name = "ProxySubject";       byte[] data = ProxyGenerator.generateProxyClass( name, new Class[] { Subject.class } );       try      {         FileOutputStream out = new FileOutputStream( name + ".class" );         out.write( data );         out.close();       }       catch( Exception e )       {         e.printStackTrace();       }     }   }   代理模式之Java动态代理和多种方法实例教程 b2b软件


动态代理内部实现
首先来看看类Proxy的代码实现 Proxy的主要静态变量
代理模式之Java动态代理和多种方法实例教程 b2b软件
// 映射表:用于维护类装载器对象到其对应的代理类缓存private static Map loaderToCache = new WeakHashMap(); // 标记:用于标记一个动态代理类正在被创建中private static Object pendingGenerationMarker = new Object(); // 同步表:记录已经被创建的动态代理类类型,主要被方法 isProxyClass 进行相关的判断private static Map proxyClasses = Collections.synchronizedMap(new WeakHashMap()); // 关联的调用处理器引用protected InvocationHandler h; 代理模式之Java动态代理和多种方法实例教程 b2b软件


Proxy的构造方法
// 由于 Proxy 内部从不直接调用构造函数,所以 private 类型意味着禁止任何调用private Proxy() {} // 由于 Proxy 内部从不直接调用构造函数,所以 protected 意味着只有子类可以调用protected Proxy(InvocationHandler h) {this.h = h;}

Proxy静态方法newProxyInstance
代理模式之Java动态代理和多种方法实例教程 b2b软件
public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces,InvocationHandler h) throws IllegalArgumentException {     // 检查 h 不为空,否则抛异常    if (h == null) {         throw new NullPointerException();     }     // 获得与指定类装载器和一组接口相关的代理类类型对象    Class cl = getProxyClass(loader, interfaces);     // 通过反射获取构造函数对象并生成代理类实例    try {         Constructor cons = cl.getConstructor(constructorParams);         return (Object) cons.newInstance(new Object[] { h });     } catch (NoSuchMethodException e) { throw new InternalError(e.toString());     } catch (IllegalAccessException e) { throw new InternalError(e.toString());     } catch (InstantiationException e) { throw new InternalError(e.toString());     } catch (InvocationTargetException e) { throw new InternalError(e.toString());     } } 代理模式之Java动态代理和多种方法实例教程 b2b软件


ProxygetProxyClass方法调用ProxyGeneratorgenerateProxyClass方法产生ProxySubject.class的二进制数据:
public static byte[] generateProxyClass(final String name, Class[] interfaces)

我们可以import sun.misc.ProxyGenerator,调用 generateProxyClass方法产生binary data,然后写入文件,最后通过反编译工具来查看内部实现原理。 反编译后的ProxySubject.java Proxy静态方法newProxyInstance
代理模式之Java动态代理和多种方法实例教程 b2b软件
import java.lang.reflect.*;   public final class ProxySubject extends Proxy       implements Subject   {       private static Method m1;       private static Method m0;       private static Method m3;       private static Method m2;       public ProxySubject(InvocationHandler invocationhandler)       {           super(invocationhandler);       }       public final boolean equals(Object obj)       {           try          {               return ((Boolean)super.h.invoke(this, m1, new Object[] {                   obj               })).booleanValue();           }           catch(Error _ex) { }           catch(Throwable throwable)           {               throw new UndeclaredThrowableException(throwable);           }       }       public final int hashCode()       {           try          {               return ((Integer)super.h.invoke(this, m0, null)).intValue();           }           catch(Error _ex) { }           catch(Throwable throwable)           {               throw new UndeclaredThrowableException(throwable);           }       }       public final void doSomething()       {           try          {               super.h.invoke(this, m3, null);               return;           }           catch(Error _ex) { }           catch(Throwable throwable)           {               throw new UndeclaredThrowableException(throwable);           }       }       public final String toString()       {           try          {               return (String)super.h.invoke(this, m2, null);           }           catch(Error _ex) { }           catch(Throwable throwable)           {               throw new UndeclaredThrowableException(throwable);           }       }       static        {           try          {               m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {                   Class.forName("java.lang.Object")               });               m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);               m3 = Class.forName("Subject").getMethod("doSomething", new Class[0]);               m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);           }           catch(NoSuchMethodException nosuchmethodexception)           {               throw new NoSuchMethodError(nosuchmethodexception.getMessage());           }           catch(ClassNotFoundException classnotfoundexception)           {               throw new NoClassDefFoundError(classnotfoundexception.getMessage());           }       }   }   代理模式之Java动态代理和多种方法实例教程 b2b软件

ProxyGenerator内部是如何生成class二进制数据,可以参考源代码。
代理模式之Java动态代理和多种方法实例教程 b2b软件
private byte[] generateClassFile() {     /*     * Record that proxy methods are needed for the hashCode, equals,     * and toString methods of java.lang.Object.  This is done before     * the methods from the proxy interfaces so that the methods from     * java.lang.Object take precedence over duplicate methods in the     * proxy interfaces.     */    addProxyMethod(hashCodeMethod, Object.class);     addProxyMethod(equalsMethod, Object.class);     addProxyMethod(toStringMethod, Object.class);     /*     * Now record all of the methods from the proxy interfaces, giving     * earlier interfaces precedence over later ones with duplicate     * methods.     */    for (int i = 0; i < interfaces.length; i++) {         Method[] methods = interfaces.getMethods();         for (int j = 0; j < methods.length; j++) {       addProxyMethod(methods[j], interfaces);         }     }     /*     * For each set of proxy methods with the same signature,     * verify that the methods' return types are compatible.     */    for (List<ProxyMethod> sigmethods : proxyMethods.values()) {         checkReturnTypes(sigmethods);     }     /* ============================================================     * Step 2: Assemble FieldInfo and MethodInfo structs for all of     * fields and methods in the class we are generating.     */    try {         methods.add(generateConstructor());         for (List<ProxyMethod> sigmethods : proxyMethods.values()) {       for (ProxyMethod pm : sigmethods) {           // add static field for method's Method object           fields.add(new FieldInfo(pm.methodFieldName,         "Ljava/lang/reflect/Method;",          ACC_PRIVATE | ACC_STATIC));           // generate code for proxy method and add it           methods.add(pm.generateMethod());       }         }         methods.add(generateStaticInitializer());     } catch (IOException e) {         throw new InternalError("unexpected I/O Exception");     }     /* ============================================================     * Step 3: Write the final class file.     */    /*     * Make sure that constant pool indexes are reserved for the     * following items before starting to write the final class file.     */    cp.getClass(dotToSlash(className));     cp.getClass(superclassName);     for (int i = 0; i < interfaces.length; i++) {         cp.getClass(dotToSlash(interfaces.getName()));     }     /*     * Disallow new constant pool additions beyond this point, since     * we are about to write the final constant pool table.     */    cp.setReadOnly();     ByteArrayOutputStream bout = new ByteArrayOutputStream();     DataOutputStream dout = new DataOutputStream(bout);     try {         /*         * Write all the items of the "ClassFile" structure.         * See JVMS section 4.1.         */            // u4 magic;         dout.writeInt(0xCAFEBABE);             // u2 minor_version;         dout.writeShort(CLASSFILE_MINOR_VERSION);             // u2 major_version;         dout.writeShort(CLASSFILE_MAJOR_VERSION);         cp.write(dout);   // (write constant pool)             // u2 access_flags;         dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER);             // u2 this_class;         dout.writeShort(cp.getClass(dotToSlash(className)));             // u2 super_class;         dout.writeShort(cp.getClass(superclassName));             // u2 interfaces_count;         dout.writeShort(interfaces.length);             // u2 interfaces[interfaces_count];         for (int i = 0; i < interfaces.length; i++) {       dout.writeShort(cp.getClass(           dotToSlash(interfaces.getName())));         }             // u2 fields_count;         dout.writeShort(fields.size());             // field_info fields[fields_count];         for (FieldInfo f : fields) {       f.write(dout);         }             // u2 methods_count;         dout.writeShort(methods.size());             // method_info methods[methods_count];         for (MethodInfo m : methods) {       m.write(dout);         }                // u2 attributes_count;         dout.writeShort(0); // (no ClassFile attributes for proxy classes)     } catch (IOException e) {         throw new InternalError("unexpected I/O Exception");     }     return bout.toByteArray(); 代理模式之Java动态代理和多种方法实例教程 b2b软件


总结
一个典型的动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))
美中不足
诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对 class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。
参考资料

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关导读
信息发布软件AIWROK软件滑动方法集合示例
AIWROK软件滑动方法集合示例
信息发布软件AIWROK软件安卓AIWROK汇集软件点击
AIWROK软件安卓AIWROK汇集软件点击
信息发布软件苹果系统点击方法综合示例
苹果系统点击方法综合示例
信息发布软件AIWROK苹果系统找图方法完整示例集合
AIWROK苹果系统找图方法完整示例集合
信息发布软件苹果系统找图方法完整示例集合
苹果系统找图方法完整示例集合
信息发布软件苹果IOS系统找字OCR方法例子
苹果IOS系统找字OCR方法例子
信息发布软件AIWORK软件数组高级示例
AIWORK软件数组高级示例
信息发布软件AIWROK软件运算符封装库示例
AIWROK软件运算符封装库示例
信息发布软件AIWROK软件语法运行小示例
AIWROK软件语法运行小示例
信息发布软件AIWROK软件JS循环小示例
AIWROK软件JS循环小示例
信息发布软件AIWROK软件H5网页被主脚本获取值用法
AIWROK软件H5网页被主脚本获取值用法
信息发布软件AIWROK软件创建可暂停恢复的多线程任务
AIWROK软件创建可暂停恢复的多线程任务
信息发布软件AIWROK软件类型转换方法例子
AIWROK软件类型转换方法例子
信息发布软件AIWROK软件H5脚本执行与进度显示
AIWROK软件H5脚本执行与进度显示 .
信息发布软件AIWROK软件根据时间段执行异步任务支持多线程并行处理
AIWROK软件根据时间段执行异步任务支持多线程并行处理
信息发布软件H5自动开关执行脚本功能演示
H5自动开关执行脚本功能演示
信息发布软件AIWROK软件H5单选脚本运行示例
AIWROK软件H5单选脚本运行示例
信息发布软件H5任务脚本选择与执行中心
H5任务脚本选择与执行中心
信息发布软件H5里CheckBox控件演示
H5里CheckBox控件演示
信息发布软件AIWROK软件正则用法实际例子
AIWROK软件正则用法实际例子
信息发布软件AIWROK软件权限管理器实现
AIWROK软件权限管理器实现
信息发布软件AIWORK软件节点方法无碍示例子
AIWORK软件节点方法无碍示例子
信息发布软件JSON.stringify 和 JSON.parse 完整示例
JSON.stringify 和 JSON.parse 完整示例
信息发布软件AIWROK软件展示JavaScript各种语句标识符的用法
AIWROK软件展示JavaScript各种语句标识符的用法
信息发布软件JS巧妙地组合使用各种条件语句
JS巧妙地组合使用各种条件语句
信息发布软件AIWROK手机数据库MySQL数据库截图片批量上传操作脚本
AIWROK手机数据库MySQL数据库截图片批量上传操作脚本
信息发布软件HID中文输入智能打字功能
HID中文输入智能打字功能
信息发布软件AIWROK软件对象工具函数库例子
AIWROK软件对象工具函数库例子
信息发布软件AIWROK软件H5交互演示黄色主题
AIWROK软件H5交互演示黄色主题
信息发布软件H5单按钮执行脚本示例
H5单按钮执行脚本示例
信息发布软件苹果H5界面完整调用脚本示例
苹果H5界面完整调用脚本示例
信息发布软件AIWROK软件平台设备信息全面检测工具例子
AIWROK软件平台设备信息全面检测工具例子
信息发布软件AIWROK创建和放大日志窗口并展示动态内容
AIWROK创建和放大日志窗口并展示动态内容
信息发布软件AIWROK软件device相关方法获取设备信息例子
AIWROK软件device相关方法获取设备信息例子[/backcolor]
信息发布软件数据库MySQL实时内容随机调用
数据库MySQL实时内容随机调用
信息发布软件AIWROK软件分享一个特效苹果H5页面
AIWROK软件分享一个特效苹果H5页面
信息发布软件数据库MYQ业务流程心跳程序启动
数据库MYQ业务流程心跳程序启动
信息发布软件数据库MySQL功能支持创建表插入中文数据查询删除功能例子
数据库MySQL功能支持创建表插入中文数据查询删除功能例子
信息发布软件AIWROK软件Zip 高级操作复杂示例
AIWROK软件Zip 高级操作复杂示例
信息发布软件AIWROK软件txt_文件读写方法小结
AIWROK软件txt_文件读写方法小结
信息发布软件AIWROK软件file文件操作方法小结
AIWROK软件file文件操作方法小结
信息发布软件AIWORK软件配置读写H5演示配套脚本
AIWORK软件配置读写H5演示配套脚本
信息发布软件AIWROK配置读写功能演示示例
AIWROK配置读写功能演示示例
信息发布软件AIWROK截图缓存工具
AIWROK截图缓存工具
信息发布软件AIWROK线程许可证工具
AIWROK线程许可证工具
信息发布软件整理了AIWROK环境下常用的Date对象和sleep对象方法
整理了AIWROK环境下常用的Date对象和sleep对象方法
信息发布软件FastUI界面普通用法
FastUI界面普通用法
信息发布软件FastUI界面类[window]方法小结
FastUI界面类[window]方法小结 方法 1:close(关闭指定窗口)方法 2:closeAll(关闭所有窗口)方法 3:loadUI(加载 UI 界面)方法 4:onClose(监听窗口关闭事件)方法 5:onLoad(监听窗口加载事件)方法 6:setFull(设置窗口全屏)方法 7:setHeight(设置窗口高度)方法 8:setHidden(隐藏窗口)方法 9:setLeft(设置窗口 X 轴坐标)方法 10:setTop(设置窗口 Y 轴坐标)方法 11:setVisable(显示隐藏的窗口)方
信息发布软件AIWROK软件按钮监听UI界面与事件监听功能演示
AIWROK软件按钮监听UI界面与事件监听功能演示.
信息发布软件AWIROK软件多选[uiCheckBox]方法小结
AWIROK软件多选方法小结 方法一:findByID 加载多选控件方法二:getAllChecked 获取所有选中项方法三:getAllSelect 获取所有选项方法四:getChecked 获取某个选项是否选中方法五:setChecked 设置某个选项是否选中方法六:setCheckeds 设置多个选项是否选中方法七:setHeight 设置高度
信息发布软件AIWROK日志演示开启日志显示 → 放大 → 关闭代码
AIWROK日志演示开启日志显示 → 放大 → 关闭代码
信息发布软件&#127983;AIWROK数组方法高级应用案例
🏯AIWROK数组方法高级应用案例
信息发布软件AIWROK软件日志悬浮窗简化版自动切换位置
AIWROK软件日志悬浮窗简化版自动切换位置
信息发布软件AIWROK软件String实例演示
AIWROK软件String实例演示
信息发布软件AIWROK软件S内置String类[String]方法小结
AIWROK软件S内置String类[String]方法小结 方法 1:charAt[/backcolor]方法 2:charCodeAt[/backcolor]方法 3:indexOf[/backcolor]方法 4:lastIndexOf[/backcolor]方法 5:length[/backcolor]方法 6:match[/backcolor]方法 7:replace[/backcolor]方法 8:replaceAll[/backcolor]方法 9:split[/backcolor]方法 10:startsWith[/backcolor]方法 11:substr[/backcolor]方法 12:substring[/backcolor]方法 13:trim[/backcol
信息发布软件AIWROK软件完整的WebSocket客户端示例
这段代码是一个完整的WebSocket客户端示例,用于连接到指定的WebSocket服务器并处理各种事件。具体来说,代码的作用如下: 定义服务器地址:首先定义了一个服务器的IP地址和端口号 var ip = "154.37.221.104:8886";。 创建WebSocket对象:尝试创建一个新的WebSocket对象 var ws = new WebSocket();。注意,这里的 new ws() 应该是 new WebSocket()。 添加事件监听器:代码中尝试为WebSocket对象添加事件监听器,但这里有一个错误。
信息发布软件AIWROK软件苹果系统中实现四种基本滑动操作
AIWROK软件苹果系统中实现四种基本滑动操作
信息发布软件hid的滑动没有百分比坐标滑动吗
hid的滑动没有百分比坐标滑动吗
信息发布软件单选控件[uiRadioButton]方法小结
单选控件方法小结 方法 1:加载单选控件[/backcolor]方法 2:获取选中项[/backcolor]方法 3:设置高度[/backcolor]方法 4:设置选中项[/backcolor]
信息发布软件AIWROK软件无障碍触摸操作示例:点击、左右滑动、上下滑动实例
AIWROK软件无障碍触摸操作示例:点击、左右滑动、上下滑动实例
信息发布软件AIWROK软件安卓随机工具应用函数生成
AIWROK软件安卓随机工具应用函数生成
信息发布软件用在AIWORK软件代码中的实用符号分类整理2
用在AIWORK软件代码中的实用符号分类整理2 软件IDE用Emoji符号分类整理(含用途说明)一、表情与情感1. 微笑 [*]😀 笑脸(基础开心反馈,用于操作成功后的友好提示) [*]😃 笑脸大眼睛(强化开心情绪,用于重要任务完成后的积极反馈) [*]😄 笑脸和微笑的眼睛(温和友好的状态,用于日常交互中的正向回应) [*]😁 带着微笑的眼睛(轻松愉悦的反馈,用于轻度成功或趣味操作) [*]
信息发布软件AIWROK软件图像二值化的各种方法和应用场景
AIWROK软件图像二值化的各种方法和应用场景
信息发布软件AIWROK软件找图区分页面变化和卡死状态
AIWROK软件找图区分页面变化和卡死状态
信息发布软件AIWROK苹果系统Map 数据管理[map]小结
AIWROK苹果系统Map 数据管理[map]小结 方法一:add(添加键值对)[/backcolor]方法二:delete(删除指定键值对)[/backcolor]方法三:clear(清空所有键值对)[/backcolor]方法四:get(根据键获取值)[/backcolor]方法五:getAllValue(获取所有值)[/backcolor]方法六:toString(转换为字符串)[/backcolor]完整示例:

QQ|( 京ICP备09078825号 )

本网站信息发布软件,是可以发布论坛,发送信息到各大博客,各大b2b软件自动发布,好不夸张的说:只要手工能发在电脑打开IE能发的网站,用这个宣传软件就可以仿制动作,进行推送发到您想发送的B2B网站或是信息发布平台上,不管是后台,还是前台,都可以进行最方便的广告发布,这个广告发布软件,可以按月购买,还可以试用软件,对网站的验证码也可以完全自动对信息发布,让客户自动找上门,使企业轻松实现b2b发布,这个信息发布软件,均是本站原创正版开发,拥有正版的血统,想要新功能,欢迎提意见给我,一好的分类信息群发软件在手,舍我其谁。QQ896757558

GMT+8, 2026-2-4 10:53 , Processed in 0.324810 second(s), 50 queries .

宣传软件--信息发布软件--b2b软件广告发布软件

快速回复 返回顶部 返回列表