RequestFactory在Android上运行缓慢

4
我正在使用RequestFactory与appengine和android。它一直表现很好,但是当我检索任何大小(约为400)的对象列表时,响应非常延迟。数据传输似乎很快(约4秒),但在很久以后(1-2分钟或更长时间)才会得到onSuccess()回调。我猜测这可能是requestfactory内部解析性能较慢的原因。我的对象只是具有10个文本字段和长整型的POJO。
我的问题是,有人遇到过这种情况吗?是否有更有效的方法快速从appengine中获取大量数据并在android中处理?
更新:当使用RF处理大量实体(3000+)时,我也遇到了OutOfMemoryErrors。我改用GSON库直接使用json进行解析,解析速度更快,且没有出现内存问题。
我正在发送的特定实体如下(我在使用Objectify)。
@Cached
@Entity
public class InterestPoint
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private Long groupId;
private String more, data;
@Unindexed
private int lat, longi;
@Unindexed
private String address, city, state;
@Unindexed
private int num1, num2, num3;
@Unindexed
private int num4,num5,num6;
@Unindexed
private String name;
@Unindexed
private int moreData;
@Unindexed
private String notes;
}

它是什么类型的对象?换句话说,我们需要为此设置一个测试用例。它有子对象吗?您能提供对象源码,也许带有重命名的参数? - Brandon
@Branflake2267添加了实体的源代码(名称已更改)。这里没有什么花哨的东西,只有整数、字符串和长整型。 - Patrick Jackson
1个回答

2

在作者对问题的描述中,我们正在检索8个相对较小的对象,每个对象都有一个到四个微小的子对象:

以下是从服务器返回响应后堆栈的示例,一分钟后它位于org.json包或com.google.web.bindery中,我们的CPU使用率很高:

java.lang.AbstractStringBuilder append0 AbstractStringBuilder.java  143 false   
java.lang.StringBuilder append  StringBuilder.java  125 false   
org.json.JSONStringer   string  JSONStringer.java   344 false   
org.json.JSONStringer   value   JSONStringer.java   252 false   
org.json.JSONObject quote   JSONObject.java 713 false   
com.google.web.bindery.autobean.shared.impl.StringQuoter    quote   StringQuoter.java   69  false   
com.google.web.bindery.autobean.shared.impl.StringQuoter    create  StringQuoter.java   50  false   
com.google.web.bindery.autobean.shared.ValueCodex$Type$13   encode  ValueCodex.java 193 false   
com.google.web.bindery.autobean.shared.ValueCodex   encode  ValueCodex.java 315 false   
com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl$ValueCoder    extractSplittable   AutoBeanCodexImpl.java  500 false   
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean    setProperty AbstractAutoBean.java   277 false   
com.google.web.bindery.autobean.vm.impl.ProxyAutoBean   setProperty ProxyAutoBean.java  253 false   
com.google.web.bindery.autobean.vm.impl.BeanPropertyContext set BeanPropertyContext.java    44  false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$3  visitValueProperty  AbstractRequestContext.java 910 false   
com.google.web.bindery.autobean.vm.impl.ProxyAutoBean   traverseProperties  ProxyAutoBean.java  289 false   
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean    traverse    AbstractAutoBean.java   166 false   
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean    accept  AbstractAutoBean.java   101 false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext    processReturnOperation  AbstractRequestContext.java 879 false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext    processReturnOperations AbstractRequestContext.java 1215    false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext    access$600  AbstractRequestContext.java 76  false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect processPayload  AbstractRequestContext.java 347 false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$5  onTransportSuccess  AbstractRequestContext.java 1108    false   
com.whichfestival.AndroidRequestTransport   send    AndroidRequestTransport.java    68  false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext    doFire  AbstractRequestContext.java 1102    false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext    fire    AbstractRequestContext.java 569 false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequest   fire    AbstractRequest.java    54  false   
com.google.web.bindery.requestfactory.shared.impl.AbstractRequest   fire    AbstractRequest.java    59  false   
com.whichfestival.FetchTopService   getEvents   FetchTopService.java    99  false   
com.whichfestival.FetchTopService   onHandleIntent  FetchTopService.java    56  false   
android.app.IntentService$ServiceHandler    handleMessage   IntentService.java  59  false   
android.os.Handler  dispatchMessage Handler.java    99  false   
android.os.Looper   loop    Looper.java 130 false   
android.os.HandlerThread    run HandlerThread.java  60  false   

我们看到GC大约触发了25次:

11-16 22:30:28.464: D/dalvikvm(416): GC_CONCURRENT freed 930K, 51% free 3321K/6727K, external 1654K/2137K, paused 15ms+10ms

11-16 22:30:33.605: D/dalvikvm(416): GC_CONCURRENT freed 515K, 49% free 3452K/6727K, external 1654K/2137K, paused 10ms+13ms

11-16 22:30:37.554: D/dalvikvm(416): GC_CONCURRENT freed 638K, 49% free 3497K/6727K, external 1654K/2137K, paused 11ms+10ms

11-16 22:30:43.424: D/dalvikvm(416): GC_CONCURRENT freed 681K, 47% free 3572K/6727K, external 1654K/2137K, paused 6ms+9ms

需要处理大约15个小型POJO对象...非常需要帮助。绝对迫切需要解决此问题。


Shermus,这正是我所期望的,但我从未深入研究过它。谢谢您的帖子。当我检索大量对象时,这是一个大问题。我正在考虑其他不使用requestfactory的方法。不幸的是,因为在Android和Appengine上拥有相同的代码非常好用! - Patrick Jackson
更新:为了我的目的,我不使用RF来传输大量实体。我已经使用CSV和自定义servlet以及HTTP请求进行了实现。在我的情况下,这相当容易,因为我处理的是简单对象。结果要快得多(10倍-20倍更快!)。 - Patrick Jackson
这里的问题与标准 Web 浏览器应用程序相同。虽然请求确实是异步的,但在请求传输回调和我的接收器之间的所有操作都需要很长时间,并且会冻结整个视图。根据我的研究,问题出现在 AbstractRequestContext#processReturnOperations 中(就像 Sheamus 发现的那样)。除了完全切换请求工厂之外,您是否有任何其他建议呢? :) - omnomnom
这个问题解决了吗?与此有关吗?http://code.google.com/p/google-web-toolkit/issues/detail?id=7231 - Daniel Gerson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接