在Java中,我有一个具有许多SQLite CRUD函数的类,它们都属于同一个类SQLiteCrudHelper
。
让所有这些函数在UI线程之外运行的唯一方法是为每个CRUD函数编写一个包装器函数,启动一个新线程,运行CRUD函数,然后返回一个回调,这样你就可以实现什么它完成后会发生吗?
或者有没有办法制作一个通用的线程/回调函数来接受你给它的任何函数并以这种方式处理它?</ p>
答案 0 :(得分:0)
问题是:java没有允许你使用任何函数的含义。
因此,在java之前,您通常会传递Runnable的某个实例或使用ExecutorService传递Callables。
使用Java8,您可以与functional interfaces一起查看method references。
长话短说。你可以创建一些带有一些“void *”指针的代码,就像在C的好日子里一样;但你有几个选择如何接近它。
最后:我的“个人”选择是查看ExecutorServices而不是使用“裸机线程”(或线程池);因为可以使用"same thread executor service"轻松替换它们,这使得将多线程代码转换回“单线程”以进行单元测试非常容易。
答案 1 :(得分:0)
您可以使用Proxy
。
如果你有这样的界面:
public interface ICL1 {
public String foo();
public String bar(String x);
}
和这样的课程:
public class CL1 implements ICL1 {
@Override
public String foo() {
return "foo";
}
@Override
public String bar(String foo) {
return foo + "bar";
}
}
你可以像这样代理:
public class TProxy<T> implements InvocationHandler {
private final ExecutorService exe = Executors.newCachedThreadPool();
public final Object object;
private TProxy(T object) {
this.object = object;
}
public static <U> U getProxy(Class<U> intf, U target) {
return (U) Proxy.newProxyInstance(target.getClass().getClassLoader(), new Class[]{intf}, new TProxy(target));
}
@Override
public Object invoke(Object target, Method method, Object[] args) throws Throwable {
Future f = exe.submit(() -> method.invoke(object, args));
return f.get();
}
}
然后您可以像这样使用代理:
System.out.println(TProxy.getProxy(ICL1.class, new CL1()).foo());
Spring总是这么做;)。享受。
注意:这不会处理回调。我的建议是使用您自己的家庭烹饪注释来注释您的方法,其中包含对回调的引用,可能是另一个Runnable
或您界面中方法的名称。然后,您可以在代理的invoke
方法中使用注释。确保您的注释具有保留Runtime
。