这篇文章主要围绕在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue和_:updatedTransactions:?展开,旨在为您提供一份详细的参考资料。我们将全面介绍在队列中添加
这篇文章主要围绕在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue和_:updatedTransactions:?展开,旨在为您提供一份详细的参考资料。我们将全面介绍在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue的优缺点,解答_:updatedTransactions:?的相关问题,同时也会为您带来AbstractQueuedSynchronizer源代码分析(未完成)、c – SKPaymentQueue addPayment并不总是触发本机确认对话框、Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query、com.facebook.react.bridge.queue.ReactQueueConfigurationSpec的实例源码的实用方法。
本文目录一览:- 在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue(_:updatedTransactions:)?
- AbstractQueuedSynchronizer源代码分析(未完成)
- c – SKPaymentQueue addPayment并不总是触发本机确认对话框
- Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
- com.facebook.react.bridge.queue.ReactQueueConfigurationSpec的实例源码
在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue(_:updatedTransactions:)?
如何解决在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue(_:updatedTransactions:)??
在添加新的交易观察者时,总是会调用SKPaymentTransactionObserver
函数func paymentQueue(_ queue: SKPaymentQueue,updatedTransactions transactions: [SKPaymentTransaction])
之类的功能,并且我在付款队列中留下未完成的purchased
状态交易。我尝试使用自动可更新订阅和消耗性订阅,并得到了相同的行为。这是预期的吗?
如果不总是调用它。我不确定我是否可以依靠paymentQueue(_:updatedTransactions:)
在应用启动时处理未完成的交易。还是我应该手动阅读paymentQueue.transactions
并从那里拿走它。有什么建议吗?
在此documentation中,应在从后台启动或恢复时调用此功能。
未完成的交易留在付款队列中。每当从后台启动或从后台恢复运行时,StoreKit都会调用该应用程序的永久观察者的paymentQueue(_:updatedTransactions :),直到该应用程序完成这些交易为止。结果,App Store可能会反复提示用户对他们的购买进行身份验证,或阻止他们从该应用程序购买产品。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
AbstractQueuedSynchronizer源代码分析(未完成)
Node
exclusive lock(独占锁)
ReentrantLock
ReentrantLock实现了公平锁与非公平锁,公平锁提供顺序获取锁的方式,而非公平锁提供抢占式获取锁的方式。
公平锁: 线程A占用锁,B等待,然后依次获取锁,其中B会被挂起或者是自旋,然后当线程A释放锁后,线程B再被唤醒,以此类推,按照申请锁的先后顺序来。
非公平锁: 线程A占用锁,B等待,于此同时C请求锁,由于B线程被唤醒需要时间,所以C有可能在B被唤醒钱就释放锁,以此类推,按照锁空闲时申请锁的线程为优先。
世界应该是公平公正的不是吗?好了,别白日做梦了,由于线程的唤醒是一个比较耗时的操作(切换线程上下文,调用OS等)如果线程持有锁的时间很长,那么公平锁就比较有优势
NonfairSync
NonfairSync中lock的实现如下:
final void lock() {
// CAS操作设置AbstractQueuedSynchronizer中的volatile int state
// 如果设置成功将现有的线程setExclusiveOwnerThread
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
// CAS失败了就调用acquire()方法
acquire(1);
}
acquire方法由AbstractQueuedSynchronizer提供
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
tryAcquire在AbstractQueuedSynchronizer中是一个protected方法并且没有给出实现,可见是希望由它的子类去扩展
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
回去再看NonfairSync中tryAcquire的实现
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
// 获取同步state
int c = getState();
// 这个判断很有意思,由于调用这个方式是第一次尝试CAS失败才会进入该方法
// 这里重新再判断一次同步state,可以避免之前的线程已经释放lock,而继续将
// 该线程放入等待队列的情况,和lock()的第一段代码含义相同设置同步state
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 接下来判断是否是同一个线程,这个判断是因为ReentrantLock是可重入的lock
else if (current == getExclusiveOwnerThread()) {
// 将state++,这里的lock的获取就是通过同步state的值来控制的
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
这段代码大概的意思就是如果还没有线程占用锁就设置state为1,如果是已经占用该锁的线程再次访问就累计state的值,返回true,如果已经被占用返回false
回过头来继续看acquire,!tryAcquire(arg)意味着获取锁失败,然后执行acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
进入addWaiter方法
/**
* 1. 初始化: 如果tail和head没有被初始化,那么创建一个node并且指向它
* +------+
* | Node | <---- tail, head
* |(Head)|
* +------+
*
* 2. 添加新的节点进入队列
* +------+ prev +------+
* head ----> | Node | <---- | Node | <---- tail
* |(Head)| ----> |Thread|
* +------+ next +------+
*/
private Node addWaiter(Node mode) {
// 创建一个node使用EXCLUSIVE模式
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
// 如果队列不是null(已经有线程再等待锁)那么将该新增的node加入队列
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
// 如果上述代码没有成功,这里是使用自旋的方式继续加入等待队列
enq(node);
// 入队成功后返回新增node节点
return node;
}
// 将新的node节点入队并返回之前的tail节点
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
// 典型的入队操作将tail指向新增的node
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
然后再看acquireQueued,此时的node参数是之前我们分析的新增入队列的node节点
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
// 返回node的前一个节点
final Node p = node.predecessor();
/**
* 如果该新增node的prev-node是head-node.如下图这种状态
* 也就是说在等待队列中只有一个node,Head-node不包含在
* 内,并且调用tryAcquire方法成功(即成功的设置了同步state)
*
*
* +------+ prev +------+
* head ----> | Node | <---- | Node | <---- tail
* |(Head)| ----> |Thread|
* +------+ next +------+
*
* 那么将head指向改node,原来的head的next节点为null
*
* +-------------+
* head ----> | Node | <---- tail
* |Thread = null|
* +-------------+
*
*/
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
接下来是shouldParkAfterFailedAcquire,顾名思义该方法返回是否在获取lock失败后堵塞线程,该方法会忽略并移出队列中node.waitStatus = CANCELLED的node
/**
* 该方的参数是 pred是Thread-A所在的node,node是Thread-B所在的node
* 这个必须得理解
*
* +------+ prev +--------------+ prev +--------+
* head ----> | Node | <---- | Node | <---- | Node |<---- tail
* |(Head)| ----> |Thread-A | ----> |Thread-B|
* +------+ next |waitStatus = 0| | |
* +--------------+ +--------+
*
* +------+ prev +---------------+ prev +--------+
* head ----> | Node | <---- | Node | <---- | Node |<---- tail
* |(Head)| ----> |Thread-A | ----> |Thread-B|
* +------+ next |waitStatus = -1| | |
* +---------------+ +--------+
*
* static final int CANCELLED = 1;
* static final int SIGNAL = -1;
* static final int CONDITION = -2;
* static final int PROPAGATE = -3;
*
* 同时这个方法又分为2步(似乎整个AQS中都充斥着延迟初始化的概念)
* 1. 初始化: 设置形参pred的waitStatus属性为Node.SIGNAL
* 2. 由于调用shouldParkAfterFailedAcquire()方法的acquireQueued()方法
* 还在自旋中,所以该方法会被调用第2次,这次才真正返回true,如果waitStatus
* 被设置成CANCELLED,那么会忽略等待队列中的这些node
*
*/
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
/*
* This node has already set status asking a release
* to signal it, so it can safely park.
*/
return true;
if (ws > 0) {
/*
* Predecessor was cancelled. Skip over predecessors and
* indicate retry.
*/
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* waitStatus must be 0 or PROPAGATE. Indicate that we
* need a signal, but don''t park yet. Caller will need to
* retry to make sure it cannot acquire before parking.
*/
// 这里就是初始化的代码,设置形参pred的waitStatus属性为Node.SIGNAL
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
parkAndCheckInterrupt()方法,使用LockSupport堵塞当前node对应的thread,并返回中断标识,当这个方法被调用时才真正的意味着lock.lock()方法完成了它的使命
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
补充说明
unsafe类
c – SKPaymentQueue addPayment并不总是触发本机确认对话框
背景:
该应用程序使用cocos2dx与javascript绑定进行交叉平台化.我们正在进入iOs原生部门,以实现商店处理.
这些调用都正常工作:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [SKPaymentQueue canMakePayments]; [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
关于最后一个的说明.检查所有产品ID并在productsRequest:request didReceiveResponse:response callback中返回有效,但前提是我没有在发送的标识符中包含bundle id.我看到的大多数示例都说这是必需的,但如果包含它们,它们都将作为invalidProductIdentifiers返回.这可能表明存在问题吗?
因此,目前一些产品在将(先前已验证的)ID传递给[[SKPaymentQueue defaultQueue] addPayment:payment]之后调出本机购买确认对话框.他们中的大多数人后来什么都不做. payQueue上没有回调:queue更新事务:事务,没有错误代码,没有崩溃.
我无法看到为什么有些工作而大多数工作没有的模式.至少一个消耗品,非消耗品和订阅工作,所以我不认为这是.我发现,如果我在[[SKPaymentQueue defaultQueue] addPayment:payment]之后暂停并逐步执行代码暂停,那么一些产品可能会更频繁地工作,尽管它不一致.这让我觉得它可能是一个线程问题,但你可以看到我在下面尝试过的内容并没有帮助.
我试过的事情:
阅读SO和其他地方,人们建议changing test users,clearing the queue [[SKPaymentQueue defaultQueue] finishTransaction:transaction],Apple的沙盒服务器有时“有问题”.但这一切都没有解决它,并且让我感到奇怪的是我没有遇到崩溃或错误,它只是对某些产品ID没有反应.
这是我尝试过的一些事情的实际调用:
- (void)purchaseProductWithId:(const char*)item_code { /** OCCASIONALLY MAY NEED TO CLEAR THE QUEUE ** NSArray *transactions = [[SKPaymentQueue defaultQueue] transactions]; for(id transaction in transactions){ [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; }// */ // dispatch_async(dispatch_get_main_queue(),^ { SKPayment *payment = [SKPayment paymentWithProductIdentifier:[Nsstring stringWithUTF8String:item_code]]; // [[SKPaymentQueue defaultQueue] performSelectorOnMainThread:@selector(addPayment:) withObject:payment waitUntilDone:NO]; [[SKPaymentQueue defaultQueue] addPayment:payment]; // } ); }
如果有任何其他代码可能有用,请告诉我.
谢谢你的帮助.
编辑:
我已经从this问题添加了hasAddobserver检查,这也不是问题.
解决方法
所以如果你有类似的问题可能需要休息一下,以后再回来?
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy30.updateCustomer(Unknown Source)
at com.qingmu.CusytomerDaoTest.updateCustomer(CusytomerDaoTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:364)
at com.sun.proxy.$Proxy32.executeUpdate(Unknown Source)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:238)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:454)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:432)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 36 more
我遇到的这个异常是因为没有添加事务,然后将
@Transactional
@Rollback(false)
然后将这两个注解打上去以后,就可以正常使用
com.facebook.react.bridge.queue.ReactQueueConfigurationSpec的实例源码
/** * @return a CatalystInstance mock that has a default working ReactQueueConfiguration. */ public static CatalystInstance createMockCatalystInstance() { ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder() .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .build(); ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create( spec,new QueueThreadExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }); CatalystInstance reactInstance = mock(CatalystInstance.class); when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration); when(reactInstance.getNativeModule(UIManagerModule.class)) .thenReturn(mock(UIManagerModule.class)); return reactInstance; }
@Override public CatalystInstance build() { return new CatalystInstanceImpl.Builder() .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault()) .setJSExecutor(new JSCJavaScriptExecutor(new WritableNativeMap())) .setRegistry(mNativeModuleRegistryBuilder.build()) .setJSModulesConfig(mJSModulesConfigBuilder.build()) .setJSBundleLoader(JSBundleLoader.createFileLoader( mContext,"assets://AndroidTestBundle.js")) .setNativeModuleCallExceptionHandler( new NativeModuleCallExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }) .build(); }
/** * @return a CatalystInstance mock that has a default working ReactQueueConfiguration. */ public static CatalystInstance createMockCatalystInstance() { ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder() .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .build(); ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create( spec,new QueueThreadExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }); CatalystInstance reactInstance = mock(CatalystInstance.class); when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration); when(reactInstance.getNativeModule(UIManagerModule.class)) .thenReturn(mock(UIManagerModule.class)); return reactInstance; }
@Override public CatalystInstance build() { return new CatalystInstanceImpl.Builder() .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault()) .setJSExecutor(new JSCJavaScriptExecutor(new WritableNativeMap())) .setRegistry(mNativeModuleRegistryBuilder.build()) .setJSModulesConfig(mJSModulesConfigBuilder.build()) .setJSBundleLoader(JSBundleLoader.createFileLoader( mContext,"assets://AndroidTestBundle.js")) .setNativeModuleCallExceptionHandler( new NativeModuleCallExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }) .build(); }
/** * @return a CatalystInstance mock that has a default working ReactQueueConfiguration. */ public static CatalystInstance createMockCatalystInstance() { ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder() .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .build(); ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create( spec,new QueueThreadExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }); CatalystInstance reactInstance = mock(CatalystInstance.class); when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration); when(reactInstance.getNativeModule(UIManagerModule.class)) .thenReturn(mock(UIManagerModule.class)); return reactInstance; }
@Override public CatalystInstance build() { return new CatalystInstanceImpl.Builder() .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault()) .setJSExecutor(new JSCJavaScriptExecutor(new WritableNativeMap())) .setRegistry(mNativeModuleRegistryBuilder.build()) .setJSModulesConfig(mJSModulesConfigBuilder.build()) .setJSBundleLoader(JSBundleLoader.createFileLoader( mContext,"assets://AndroidTestBundle.js")) .setNativeModuleCallExceptionHandler( new NativeModuleCallExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }) .build(); }
/** * @return a CatalystInstance mock that has a default working ReactQueueConfiguration. */ public static CatalystInstance createMockCatalystInstance() { ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder() .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .build(); ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create( spec,new QueueThreadExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }); CatalystInstance reactInstance = mock(CatalystInstance.class); when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration); when(reactInstance.getNativeModule(UIManagerModule.class)) .thenReturn(mock(UIManagerModule.class)); return reactInstance; }
/** * @return a CatalystInstance mock that has a default working ReactQueueConfiguration. */ public static CatalystInstance createMockCatalystInstance() { ReactQueueConfigurationSpec spec = ReactQueueConfigurationSpec.builder() .setJSQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .setNativeModulesQueueThreadSpec(MessageQueueThreadSpec.mainThreadSpec()) .build(); ReactQueueConfiguration ReactQueueConfiguration = ReactQueueConfigurationImpl.create( spec,new QueueThreadExceptionHandler() { @Override public void handleException(Exception e) { throw new RuntimeException(e); } }); CatalystInstance reactInstance = mock(CatalystInstance.class); when(reactInstance.getReactQueueConfiguration()).thenReturn(ReactQueueConfiguration); when(reactInstance.getNativeModule(UIManagerModule.class)) .thenReturn(mock(UIManagerModule.class)); return reactInstance; }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,final JavaScriptExecutor jsExecutor,final NativeModuleRegistry registry,final JavaScriptModuleRegistry jsModuleRegistry,final JSBundleLoader jsBundleLoader,NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler) { FLog.d(ReactConstants.TAG,"Initializing React Xplat Bridge."); mHybridData = initHybrid(); mReactQueueConfiguration = ReactQueueConfigurationImpl.create( ReactQueueConfigurationSpec,new NativeExceptionHandler()); mBridgeIdleListeners = new copyOnWriteArrayList<>(); mJavaRegistry = registry; mJSModuleRegistry = jsModuleRegistry; mJSBundleLoader = jsBundleLoader; mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler; mNativeModulesQueueThread = mReactQueueConfiguration.getNativeModulesQueueThread(); mTraceListener = new JSProfilerTraceListener(this); FLog.d(ReactConstants.TAG,"Initializing React Xplat Bridge before initializeBridge"); initializeBridge( new BridgeCallback(this),jsExecutor,mReactQueueConfiguration.getJSQueueThread(),mNativeModulesQueueThread,mJavaRegistry.getJavaModules(this),mJavaRegistry.getCxxModules()); FLog.d(ReactConstants.TAG,"Initializing React Xplat Bridge after initializeBridge"); mMainExecutorToken = getMainExecutorToken(); }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler) { FLog.w(ReactConstants.TAG,new NativeExceptionHandler()); mBridgeIdleListeners = new copyOnWriteArrayList<>(); mJavaRegistry = registry; mJSModuleRegistry = jsModuleRegistry; mJSBundleLoader = jsBundleLoader; mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler; mNativeModulesQueueThread = mReactQueueConfiguration.getNativeModulesQueueThread(); mTraceListener = new JSProfilerTraceListener(this); FLog.w(ReactConstants.TAG,mJavaRegistry.getCxxModules()); FLog.w(ReactConstants.TAG,"Initializing React Xplat Bridge after initializeBridge"); mMainExecutorToken = getMainExecutorToken(); }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,final JavaScriptModulesConfig jsModulesConfig,"Initializing React Bridge."); mReactQueueConfiguration = ReactQueueConfigurationImpl.create( ReactQueueConfigurationSpec,new NativeExceptionHandler()); mBridgeIdleListeners = new copyOnWriteArrayList<>(); mJavaRegistry = registry; mJSModuleRegistry = new JavaScriptModuleRegistry(CatalystInstanceImpl.this,jsModulesConfig); mJSBundleLoader = jsBundleLoader; mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler; mTraceListener = new JSProfilerTraceListener(); try { mBridge = mReactQueueConfiguration.getJSQueueThread().callOnQueue( new Callable<ReactBridge>() { @Override public ReactBridge call() throws Exception { Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,"initializeBridge"); try { return initializeBridge(jsExecutor,jsModulesConfig); } finally { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } } }).get(); } catch (Exception t) { throw new RuntimeException("Failed to initialize bridge",t); } }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,t); } }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,t); } }
private CatalystInstanceImpl( final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,new NativeExceptionHandler()); mBridgeIdleListeners = new copyOnWriteArrayList<>(); mJavaRegistry = registry; mJSModuleRegistry = jsModuleRegistry; mJSBundleLoader = jsBundleLoader; mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler; mTraceListener = new JSProfilerTraceListener(this); initializeBridge( new BridgeCallback(this),mReactQueueConfiguration.getNativeModulesQueueThread(),mJavaRegistry.getModuleRegistryHolder(this)); mMainExecutorToken = getMainExecutorToken(); }
public Builder setReactQueueConfigurationSpec( ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { mReactQueueConfigurationSpec = ReactQueueConfigurationSpec; return this; }
public Builder setReactQueueConfigurationSpec( ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { mReactQueueConfigurationSpec = ReactQueueConfigurationSpec; return this; }
public Builder setReactQueueConfigurationSpec( ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { mReactQueueConfigurationSpec = ReactQueueConfigurationSpec; return this; }
public Builder setReactQueueConfigurationSpec( ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { mReactQueueConfigurationSpec = ReactQueueConfigurationSpec; return this; }
public Builder setReactQueueConfigurationSpec( ReactQueueConfigurationSpec ReactQueueConfigurationSpec) { mReactQueueConfigurationSpec = ReactQueueConfigurationSpec; return this; }
关于在队列中添加未完成交易的新观察者时,是否总是调用paymentQueue和_:updatedTransactions:?的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于AbstractQueuedSynchronizer源代码分析(未完成)、c – SKPaymentQueue addPayment并不总是触发本机确认对话框、Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query、com.facebook.react.bridge.queue.ReactQueueConfigurationSpec的实例源码等相关内容,可以在本站寻找。
本文标签: