- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个简单的 android 应用程序,它只解析来自苹果网站的 XML。它有解析前 10 名“歌曲”、“付费应用程序”或“免费应用程序”的菜单。
对于网络调用,我使用 volley。现在,当我在旋转设备时看到日志时,processXml() - 从 URL 获取 xml 并将其放在 ListView 中 - 调用多次,在 onCreate() 和 onRestoreInstanceState() 中。恕我直言,这可能是多余的下载。
我的问题:
非常感谢
这是日志
// start of app
04-13 09:14:36.456 MainActivity: onCreate: processXml() called
// select "songs" from menu
04-13 09:14:49.627 MainActivity: onOptionsItemSelected: processXml() called
// rotate device
04-13 09:14:55.758 MainActivity: onCreate: processXml() called
这是我在 MainACtivity.java 上的源代码公共(public)类 MainActivity 扩展 AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String KEY_RSS_URL = "KEY_RSS_URL";
private static final String KEY_FEED_LIMIT = "KEY_FEED_LIMIT";
private String rssUrl = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topfreeapplications/limit=%d/xml";
private int feedLimit = 10;
private ListView xmlListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.xmlListView = (ListView) findViewById(R.id.xmlListView);
if (savedInstanceState != null) {
this.rssUrl = savedInstanceState.getString(KEY_RSS_URL);
this.feedLimit = savedInstanceState.getInt(KEY_FEED_LIMIT);
}
// need to put it here because when app start, it should already display top 10 free aps
processRss(String.format(this.rssUrl, this.feedLimit));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
... create menu
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case R.id.mnuFree:
this.rssUrl = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topfreeapplications/limit=%d/xml";
break;
case R.id.mnuPaid:
this.rssUrl = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppaidapplications/limit=%d/xml";
break;
case R.id.mnuSongs:
this.rssUrl = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topsongs/limit=%d/xml";
break;
default:
return super.onOptionsItemSelected(item);
}
processRss(String.format(this.rssUrl, this.feedLimit));
Log.d(TAG, "onOptionsItemSelected: processRss() called");
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_RSS_URL, this.rssUrl);
outState.putInt(KEY_FEED_LIMIT, this.feedLimit);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
this.rssUrl = savedInstanceState.getString(KEY_RSS_URL);
this.feedLimit = savedInstanceState.getInt(KEY_FEED_LIMIT);
processRss(String.format(this.rssUrl, this.feedLimit));
Log.d(TAG, "onRestoreInstanceState: processRss() called");
}
private void processRss(String rssUrl) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, rssUrl, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
ParseApplication parseApplication = new ParseApplication();
if (parseApplication.parse(response)) {
ArrayAdapter<FeedEntry> arrayAdapter = new FeedAdapter(
MainActivity.this,
R.layout.list_record,
parseApplication.getApplications(),
VolleySingleton.getInstance(MainActivity.this).getImageLoader());
xmlListView.setAdapter(arrayAdapter);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: from volley : " + error.getMessage());
}
});
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
对于 VolleySingleton,我使用这段代码,getRequestQueue 使用缓存
公共(public)类 VolleySingleton {
private static VolleySingleton mInstance;
private static Context mCtx;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private VolleySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized VolleySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new VolleySingleton(context);
}
return mInstance;
}
private RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
File cacheDir = new File(mCtx.getCacheDir(), "VOLLEY_CACHE_DIR");
mRequestQueue = new RequestQueue(
new DiskBasedCache(cacheDir, 512 * 512),
new BasicNetwork(new HurlStack()));
mRequestQueue.start();
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
最佳答案
- am I put processXml() on a wrong place? If so, where is the correct place to avoid redundant network call?
是的,您在两个地方调用了该方法。不要在 onRestoreInstanceState
中重复相同的调用,您应该保留对正在进行的请求的引用。有几种方法可以做到这一点。其中一些是:
使用 Service并将网络响应广播到您的 Activity ( http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/ )
使用 Loaders ( https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832 )
- since I use volley, is there any way to cache response and use it when device rotate? I think I've write the cache on VolleySingleton, but I don't know if my implementation is correct
您正在使用 DiskBasedCache
,它看起来与 Android documentation 中的示例相同.您可以通过关闭网络连接(数据和 wifi)并旋转您的设备来轻松检查它是否正常工作。您还可以检查 Volley 代码以了解它如何使用缓存。
关于java - 使用 volley 避免 Android 设备旋转时的冗余网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43382700/
我目前正在测试 Volley 库。但是当请求失败 (404) 时,它不会再次执行,或者至少没有错误。但是缺少数据。如果请求失败,这是重试请求的正确方法吗? 提前致谢 req.setRetryPolic
我是新来从事Volley和缓存工作的:P。尽管我已经看过许多与Volley进行图像缓存有关的文章和帖子,但是我仍然不清楚采用Volley进行图像缓存的最佳/首选方式。像磁盘缓存还是内存? Volley
我想使用 Volley 从我的 Android 应用发送请求。 我已经把它包含在 build.gradle 中了 dependencies { ... compile 'com.andr
我的目标是从另一个类调用 Volley,这是一种非常简洁、模块化的方式,即: VolleyListener newListener = new VolleyListener()
我的代码是: class MyService extends Service{ public void onCreate(){ new ImageLoader(mReque
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我需要帮助来解决 Volley 库错误。我已使用 nodejs api 向服务器发送一些凭据以进行用户注册。在成功的情况下,当我的所有凭据对于创建新用户帐户都是唯一的时,它会向我显示所有响应等的所有内
我正在尝试完善我的应用程序中的错误处理,但我找不到 Volley 触发某些错误的集中位置以及原因。例如,我想知道如果我的请求的状态代码是 500 或更大,它肯定会触发 ServerError,但我似乎
当我在调试器中运行该方法时,数据按预期显示,但是每当我尝试使用它执行任何操作时,parentObject 的值都会返回为 null。 我只是想从服务器获取响应并将其存储为 JSONObject 以便在
我正在使用 Android Volley 缓存请求,这在我使用 GET 时工作正常,但由于某些原因我改用 POST。现在我想用不同的 POST 数据缓存相同的 URL。 请求 1 -> URL1,PO
我的情况是使用 Android-volley至 POST我的 json 对象,我可以成功发布所有内容,我的数据在服务器中可见,但服务器响应为 String不像 json ,这就是出现错误的原因。 co
我正在使用 volley 从 REST api 解析电影详细信息,并将解析的数据保存在名为 detailsMovies 的对象数组列表中。但是我无法在 onResponse 方法之外访问 ArrayL
我想知道如何解决这个问题。已完成代码的研究和替换,但问题仍然存在。 这是我使用 volley 的代码。 private void Regist(){ loading.setVisibility
如何创建一个单独的类,在其中定义所有关于 volley在另一个 Activity 中,我们直接传递 URL、CONTEXT 和 Get Response... 最佳答案 首先在Activity中创建回
我正在使用 volley 库并以 XML 格式获取响应。我想知道我们如何使用/volley 库解析响应。谢谢。 最佳答案 StringRequest req = new StringReque
当我在android studio中搜索 Volley 时,同时获取com.mcxiaoke.volley:library:1.0.19和com.mcxiaoke.volley:library-aar
我是 volley 和 android 的新手,我已经用 gradle 安装了 volley 并做了与官方教程相同的操作。但是没有响应,这意味着 Errorlistener 和 Responselis
当我在 Volley 中发出请求时,我收到 com.android.volley.ServerError 和响应代码 400。 我正在做这样的事情(通用示例代码): final String para
我引用了http://www.androidhive.info/2016/02/android-push-notifications-using-gcm-php-mysql-realtime-chat
当我将以下行添加到依赖项的 build.gradle 行时,Android Studio 显示此错误消息:compile 'com.android.volley:volley:1.0.0' apply
我是一名优秀的程序员,十分优秀!