Using volley and Glide to download, display and cache images - android

I can't wrap my head around this, probably because of lack of my experience. I have images on server, I get their path in JSON along with description and a name. I am getting all of that data with Volley.
private static final String TAG = "StoreActivity";
private RecyclerView shopsRecyclerView;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Store> stores;
private StoreAdapter storeAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store);
shopsRecyclerView = (RecyclerView) findViewById(R.id.shopsRecyclerView);
shopsRecyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
shopsRecyclerView.setLayoutManager(layoutManager);
stores = new ArrayList<>();
storeAdapter = new StoreAdapter(getApplicationContext(), stores);
shopsRecyclerView.addOnItemTouchListener(new StoreAdapter.RecyclerTouchListener(getApplicationContext(), shopsRecyclerView, new StoreAdapter.ClickListener() {
#Override
public void onClick(View view, int position) {
Intent i = new Intent(StoreActivity.this, ProductsActivity.class);
startActivity(i);
}
#Override
public void onLongClick(View view, int position) {
}
}));
fetchStores();
}
private void fetchStores() {
JsonObjectRequest fetchAllStores = new JsonObjectRequest(Request.Method.POST, API.GET_STORES, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Fetch Stores: " + response);
showStores(response);
shopsRecyclerView.setAdapter(storeAdapter);
storeAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Fetch Stores Error: " + error.getMessage());
}
});
ApplicationController.getInstance().addToRequestQueue(fetchAllStores);
}
private void showStores(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("images");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Store store = new Store();
store.setId(jsonObject.getString("id"));
store.setImage_url(jsonObject.getString("url"));
store.setTitle(jsonObject.getString("name"));
stores.add(store);
}
} catch (JSONException e) {
Log.d(TAG, "Show Stores: " + e.getMessage());
}
}
Then I put that path/url I got from Volley in Glide and load all of the images in RecyclerView.
#Override
public void onBindViewHolder(StoreViewHolder holder, final int position) {
Store store = stores.get(position);
holder.tvDescription.setText(store.getTitle());
Glide.with(context)
.load(store.getImage_url())
.placeholder(android.R.drawable.ic_menu_upload_you_tube)
.error(android.R.drawable.stat_notify_error)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(holder.ivImage);
}
Next time I turn on the same activity, the request is sent again and images are downloaded again? Or are they previously cached somehow and they are loaded from cache?
When I turn off internet and turn on the same activity, nothing happens, because the volley request can't be sent, and the images I thought were cached aren't shown.
What would be the best approach for my problem? Basically, I need to get the images's path from server and place them in my recyclerview but I also want them to be cached so they are not downloaded every time.

I would like to suggest you to use Glide lib, very simple and caches images for your app, I have tried it myself. You can also add signature to the url so that next time it is updated it has to change.
Glide Url
Below is code Snippet :
dependencies {
// glide
compile 'com.github.bumptech.glide:glide:3.7.0'
}
String imgUrl = "http://imageurl";
ImageView imageView = (ImageView) view.findViewById(R.id.thumbnail);
Glide.with(mContext).load(imgUrl)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
Hope this Helps.

Related

Cannot assign variables when doing JSON in android studio

I want to execute taking data from JSON as shown below. But when
Toast.makeText(this, MangIDtrailer.size () + "..... check size of Array IDtrailer .....", Toast.LENGTH_LONG).show();
it returns 0.
I don't know what the cause is.
public class Main2Activity extends AppCompatActivity {
ListView Listmovie;
ArrayList<String> MangIDtrailer;
public static ArrayList<InfoMovie> inforMovieArrayList;
AdapterMovie adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
BottomNavigationView navView = findViewById(R.id.nav_view);
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
String url1 ="http://the....ying";
inforMovieArrayList = new ArrayList<>();
MangIDtrailer = new ArrayList<>();
MangIDtrailer = GetIDMovie(url1);
inforMovieArrayList = DataMovie(MangIDtrailer);
Listmovie = (ListView) findViewById(R.id.ListMovie);
adapter = new AdapterMovie(this, R.layout.movielist, inforMovieArrayList);
Listmovie.setAdapter(adapter);
Listmovie.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(Main2Activity.this,Review_Movie.class);
intent.putExtra("IDmovie",i);
//Toast.makeText(MainActivity.this, ""+i, Toast.LENGTH_SHORT).show();
startActivity(intent);
}
});
}
public ArrayList<String> GetIDMovie (String Url) {
final ArrayList<String> ArrayID = new ArrayList<>();
final RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, Url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String IDTrailer;
JSONArray jsonArrayFreeMovies = response.getJSONArray("FreeMovies");
for (int i=0; i < jsonArrayFreeMovies.length(); i++) {
JSONObject jsonObjectFreeMovies = jsonArrayFreeMovies.getJSONObject(i);
IDTrailer = jsonObjectFreeMovies.getString("trailer_id");
ArrayID.add(IDTrailer);
Toast.makeText(Main2Activity.this, i+"************", Toast.LENGTH_SHORT).show();
}
Toast.makeText(Main2Activity.this, MangIDtrailer.get(2)+"check Data ", Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsonObjectRequest);
queue.cancelAll(jsonObjectRequest);
return ArrayID;
}
public ArrayList <InfoMovie> DataMovie (ArrayList<String> MangIDtrailer) {
final ArrayList<InfoMovie> inforMovieArray = new ArrayList<>();
final String linkDetail = "http://tk/api/trailers/movDetail?trailer_id=";
final RequestQueue queue2 = Volley.newRequestQueue(this);
//////////////Check that MangIDtrailer.size () has no data////////////////////////////////////
Toast.makeText(this, MangIDtrailer.size()+".....check size of Array IDtrailer .....",Toast.LENGTH_LONG).show();
for (int i=0; i<MangIDtrailer.size(); i++) {
JsonObjectRequest jsonObjectRequest2 = new JsonObjectRequest(Request.Method.GET, linkDetail + MangIDtrailer.get(i) + "&test_fullVer=1", null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String linkposter, linkbackdrop, namemovie, overviewmovie, Release_date, Urltrailer;
Float Vote_average;
String linkHot = "https://image.tmdb.org/t/p/w500/";
JSONObject jsonObjectInfo = null, jsonObjectMore = null;
JSONObject jsonopFreeMovies1 = response.getJSONObject("FreeMovies");
if (jsonopFreeMovies1.has("FreeMovies")) {
//Toast.makeText(MainActivity.this, "Cos ", Toast.LENGTH_SHORT).show();
JSONObject jsonObjectFreeMovies2 = jsonopFreeMovies1.getJSONObject("FreeMovies");
jsonObjectInfo = jsonObjectFreeMovies2.getJSONObject("Info");
jsonObjectMore = jsonObjectFreeMovies2.getJSONObject("More");
} else {
//Toast.makeText(MainActivity.this, "Khoong cos", Toast.LENGTH_SHORT).show();
jsonObjectInfo = jsonopFreeMovies1.getJSONObject("Info");
jsonObjectMore = jsonopFreeMovies1.getJSONObject("More");
}
namemovie = jsonObjectInfo.getString("title");
Urltrailer = jsonObjectInfo.getString("trailer_urls");
linkposter = linkHot + jsonObjectInfo.getString("thumbnail");
overviewmovie = jsonObjectMore.getString("overview");
linkbackdrop = linkHot + jsonObjectMore.getString("backdrop_path");
Release_date = jsonObjectMore.getString("release_date");
Vote_average = Float.valueOf(jsonObjectMore.getLong("vote_average"));
inforMovieArray.add(new InfoMovie(namemovie, overviewmovie, linkposter, linkbackdrop, Vote_average, Release_date));
Toast.makeText(Main2Activity.this,namemovie + "-" + overviewmovie + "-" + Vote_average, Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
Toast.makeText(Main2Activity.this, "Lỗi", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Main2Activity.this, "Lỗi Try catch", Toast.LENGTH_SHORT).show();
}
});
queue2.add(jsonObjectRequest2);
}
return inforMovieArray;
}
}
As you suggested
Toast.makeText(this, MangIDtrailer.size()+".....check size of Array IDtrailer .....",Toast.LENGTH_LONG).show();
This is where you are getting size zero, which is absolutely true, because you have only initialized your array MangIDtrailer and it is an empty array. Your function GetIDMovie(url1); has a loop which populates your MangIDtrailer array which is below where you have called the toast. So your array is empty and thus its size returns zero.
One handy tip for you, you should name your functions in camelCase with first letter of your word in lowercase. GetIDMovie(url1) seems more like a class constructor. :)
EDIT:
The above solves your initial problem.
To fully solve your problem, you have to understand that Network Operations are asynchronous, meaning they will execute after sometime or they may return no value at all depending on various conditions, like network bandwidth, your server state, the parameters passed to your HTTP requests, etc.
You have two network calls in your above code; in functions: GetIDMovie() and DataMovie(). The second function requires an array of IDs which is only available if your first request is complete and returns an array of ids. So what you would want to do is, only after you get the array of ids ie. in onResponse of GetIDMovie() after the for loop, you should make a call to DataMovie().
This however is really ugly solution. I hope you will research further for better solution.

Arraylist that sometimes contain data, and sometimes not

A newbie for here.
I'm working in an app with Android and a strange thing happens to me with a While loop. I make a series of requests to the database with volley library and it returns the data well. No problem.
The problem, i think, is in the last function DameColorPlato(), because sometimes the code accesses the while loop and it passes through it well, but sometimes it does not, and it returns the default value of the CC variable (#000000) and it does not show me well the colors of the text.
This is my code (In summary):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
Bundle datos = getIntent().getExtras();
id_usuario = datos.getString("id_usuario");
idCentro = datos.getString("id_centro");
fecha_actual = datos.getString("fechaActual");
fecha_actual_SQL = datos.getString("fechaActualSQL");
plato1 = (TextView)findViewById(R.id.textView4);
plato2 = (TextView)findViewById(R.id.textView3);
ObtPlatos_volley(idCentro, fecha_actual_SQL);
ObtColores_volley();
public void ObtPlatos_volley(final String id_centro, final String fecha_actual_SQL){
String url = "http://neton.es/WS_neton/menu_dia.php?id_centro="+id_centro+"&fecha_actual_SQL="+fecha_actual_SQL;
StringRequest eventfulRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i=0; i<jsonArray.length(); i++) {
platouno = jsonArray.getJSONObject(i).getString("plato1");
platodos = jsonArray.getJSONObject(i).getString("plato2");
platounoColor = jsonArray.getJSONObject(i).getInt("tipo1");
platodosColor = jsonArray.getJSONObject(i).getInt("tipo2");
}
plato1.setText(platouno);
String co1 = DameColorPlato(CodTipoPlato, ColorLetra, platounoColor);
plato1.setTextColor(Color.parseColor(co1));
plato2.setText(platodos);
String co2 = DameColorPlato(CodTipoPlato, ColorLetra, platodosColor);
plato2.setTextColor(Color.parseColor(co2));
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error: ", error.toString());
}
});
VolleySingleton.getInstance(this)
.addToRequestQueue(eventfulRequest);
}
public void ObtColores_volley(){
String url = "http://neton.es/WS_neton/color_platos.php";
StringRequest eventfulRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
int cod_color_letra;
String color_letra;
JSONArray jsonArray = new JSONArray(response);
for (int i=0; i<jsonArray.length(); i++){
cod_color_letra = jsonArray.getJSONObject(i).getInt("cod_tipoplato");
color_letra = jsonArray.getJSONObject(i).getString("color");
CodTipoPlato.add(cod_color_letra);
ColorLetra.add(color_letra);
}
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error: ", error.toString());
}
});
VolleySingleton.getInstance(this)
.addToRequestQueue(eventfulRequest);
}
public String DameColorPlato(ArrayList<Integer> CodColorL, ArrayList<String> ColorL, int tipoplato){
String CC="#000000";
int i=0;
boolean encontrado=false;
while (i < CodColorL.size() && !encontrado) {
if (tipoplato == CodColorL.get(i)) {
CC = ColorL.get(i);
encontrado = true;
}else {
i++;
}
}
return CC;
}
}
With a Toast I have found that ArrayList CodColorL and ArrayList ColorL variables sometimes come with values, and sometimes they come empty. But i cannot found the error.
Thanks in advance!
(sorry for my bad English)
As I explained out in the comments, for anyone else looking at this question, the reason why OP was seeing the issue of unreliable data is because they are making two Volley requests and expecting one to finish before implicitly.
By default, Volley requests are run in a queue but are Asynchronous which means that the requests won't necessarily finish in the order that they were started in the queue. Since OP's one request is dependent on the data from the other the correct way to do this is by synchronously running the requests. This can be done in a few ways such as using a callback from the first request or through starting the second request in the onResponse block of the first one.
One more way to achieve the same is to create your own architecture of running requests where you have a way to run all the requests on a single thread but that is over optimizing for this particular case.

Issues with Volley caching mechanism

I have a website which publishes news on daily basis.
Now, I'm sending a JsonArrayRequest to retrieve and parse the title and summary of each news published on the website. The parsed items are then used to populate RecyclerView.
The problem I'm having is the way volley implements caching .
Let's take this scenario: the app is installed, launched and the RecyclerView is populated. The user reads the news and forgets about the app
Later, the user launches the app and the items are fetched and RecyclerView is populated.
Between the first and the second launch, new news are published on the website. But in the second launch, these new items are not displayed. However, if the user manually go to app settings and clear cache of the app, and relaunch, the new items are displayed.
You get my point?
While I don't want to disable Volley caching, how do I make it to always fetch new items?
EDIT
MainActivity
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
//Creating a list of newss
private List<NewsItems> mNewsItemsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate called");
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.news_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing the newslist
mNewsItemsList = new ArrayList<>();
adapter = new NewsAdapter(mNewsItemsList, this);
recyclerView.setAdapter(adapter);
if (NetworkCheck.isAvailableAndConnected(this)) {
//Calling method to get data
getData();
} else {
//Codes for building Alert Dialog
alertDialogBuilder.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (!NetworkCheck.isAvailableAndConnected(mContext)) {
alertDialogBuilder.show();
} else {
getData();
}
}
});
alertDialogBuilder.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialogBuilder.show();
}
}
//This method will get data from the web api
private void getData(){
Log.d(TAG, "getData called");
//Codes for Showing progress dialog
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL + getNumber(),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
if (mProgressDialog != null) {
mProgressDialog.hide();
}
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//This method will parse json data
private void parseData(JSONArray array){
Log.d(TAG, "Parsing array");
for(int i = 0; i<array.length(); i++) {
NewsItems newsItem = new NewsItems();
JSONObject jsonObject = null;
try {
jsonObject = array.getJSONObject(i);
newsItem.setNews_title(jsonObject.getString(ConfigNews.TAG_VIDEO_TITLE));
newsItem.setNews_body(jsonObject.getString(ConfigNews.TAG_VIDEO_BODY));
} catch (JSONException w) {
w.printStackTrace();
}
mNewsItemsList.add(newsItem);
}
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy called");
if (mProgressDialog != null){
mProgressDialog.dismiss();
Log.d(TAG, "mProgress dialog dismissed");
}
}
}
Option 1) Delete Cache
before you make a call you can delete the whole cache by myDiskBasedCache.clear() or specific entries by myDiskBasedCache.remove(entryUrl)
Option 2) Custom CacheParser (in the Request)
#Override
protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
Response<Bitmap> resp = super.parseNetworkResponse(response);
if(!resp.isSuccess()) {
return resp;
}
long now = System.currentTimeMillis();
Cache.Entry entry = resp.cacheEntry;
if(entry == null) {
entry = new Cache.Entry();
entry.data = response.data;
entry.responseHeaders = response.headers;
entry.ttl = now + 60 * 60 * 1000; //keeps cache for 1 hr
}
entry.softTtl = 0; // will always refresh
return Response.success(resp.result, entry);
}
Option 3) send requests that does not cache
myRequest.setShouldCache(false);
Option 4) use custom Cache implementation
UPDATE:
Example with your code:
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigNews.GET_URL + getNumber(),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
if (mProgressDialog != null) {
mProgressDialog.hide();
}
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
Response<JSONArray> resp = super.parseNetworkResponse(response);
if(!resp.isSuccess()) {
return resp;
}
long now = System.currentTimeMillis();
Cache.Entry entry = resp.cacheEntry;
if(entry == null) {
entry = new Cache.Entry();
entry.data = response.data;
entry.responseHeaders = response.headers;
entry.ttl = now + 60 * 60 * 1000; //keeps cache for 1 hr
}
entry.softTtl = 0; // will always refresh
return Response.success(resp.result, entry);
}
};
UPDATE 2
Http protocol caching supports many ways to define how the client can cache responses and when to update them. Volley simplifies those rules to:
entry.ttl (time to live in ms) if greater than the current time then cache can be used otherwise fresh request needs to be made
and
entry.softTtl (soft time to live in ms :) if greater than the current time
cache is absolutely valid and no request to the server needs to be made, otherwise new request is still made (even if the ttl is good) and if there is a change new response will be delivered.
note that if ttl is valid and softTtl is not you can receive 2 onResponse calls

JSON Download # onCreateView leaves recyclerView empty

if (isConnected()) {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter = new RecyclerAdapter(theEvents);
recyclerView.setAdapter(rAdapter);
progrsBar.setVisibility(View.GONE);
....
This is part of the code that runs at "onCreateView". The method downloadEvents uses Volley to download JSON data, extract it and return a list of items (theEvents). Now when my app starts, the recycler view is empty. If I go to my home screen out of the app and then run my app again, this time the data sometimes gets downloaded.
I debugged step by step, and at first launch (i mean when the app is not just resuming), theEvents is empty, so the download didn't return or manage to return anything...
Suggestions on how to execute things before the UI has been shown to the user or what actually needs to be done to approach this task better?
Also, I use a swipeRefreshLayout and at its onRefresh method I do:
public void onRefresh() {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
but it doesn't work. I also tried to
rAdapter = new RecyclerAdapter(theEvents);
rAdapter.notifyDataSetChanged();
recyclerView.swapAdapter(rAdapter, false);
still not working.
EDIT: My downloadEvents method implementing Volley:
public List<Event> downloadEvents(String urlService, Context context) {
eventsList = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(context);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
String durationStr = null;
for (int i = 0; i < response.length(); i++) {
JSONObject eventJson = response.getJSONObject(i);
String title = eventJson.getString("EventTitle");
String body = eventJson.getString("EventBody");
String date = eventJson.getString("EventDate");
String time = eventJson.getString("EventTime");
int duration = Integer.parseInt(eventJson.getString("EventDuration"));
if (duration > 60) {
durationStr = "Duration: " + duration / 60 + " h";
} else if (duration < 60) {
durationStr = "Duration: " + duration + " m";
}
String place = eventJson.getString("EventPlace");
String organ = eventJson.getString("Organization");
Event event = new Event(title, body, date, time, durationStr, place, organ);
eventsList.add(event);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY ERROR", "" + error);
}
}
);
requestQueue.add(jsonArrayRequest);
return eventsList;
}
You can use EventBus for your purpose that is a simple and truth way.
Here, i write an example for how to use EventBus with volley.
Consider that i want to download some data.
This is the class that my download methods is inside it (you can add more methods to it in the future):
Im used volley to download my data:
// Download methods is inside volley
public class MyDownloader{
public static void downloadData(){
DownloadDataEvent dlDataEvent=new DownloadDataEvent();
List<String> myResult=new ArrayList<>();
...
#Override
public void onResponse(JSONArray response) {
super.onResponse(response);
if(respone!=null){
// Do what i want with my received data
dlDataEvent.setData(response);
}
// Post my event by EventBus
EventBus.getDefault().post(dlDataEvent);
...
}
}
}
This is my event:
public class DownloadDataEvent{
private JSONArray mData;
public void setData(JSONArray data){
mData=data;
}
public JSONArray setData(){
return mData;
}
}
Now i want to use my downloadData() method inside my MainActivity:
(I called my downloadData method inside onCreate.)
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
// I have to register this class for EventBus subscriber:
if(!EventBus.getDefault().isRegister(this)){
EventBus.getDefault().registerSticky(this);
}
// Call my downloadData method
if(isConnected()){
MyDownloader.downloadData();
}
}
// And for receive the data through EventBus, i have to create a
// method (subscriber) in this template:
public void onEventMainThread(DownloadDataEvent downloadDataEvent){
JSONArray result=downloadDataEvent.getData();
// Do what i want with my received data
}
}
you can create more than one subscriber every where you want to use received data.
I passed JSONArray to my DownloadDataEvent that it is not good. you can deserialize your received data and pass it to your DownloadDataEvent.
I used Volley to download data
Maybe my descriptions were confusing, but EventBus is a well-known library and is very easy to use.

How to set Bitmap on ImageView using library Volley

I'm trying to use the library to perform volley download images from my server.
In my activity I add items dynamically and then realize the exchange of image at runtime.
Below is the code of the attempt to get the picture:
public void updateThumbnails(ArrayList<Book> arrBook,ArrayList<View> arrView){
if(arrBook.size()<= 0){
return;
}
if(arrView.size() <= 0){
return;
}
int intBooks = arrView.size();
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
for(int intIndex = 0; intIndex < intBooks; intIndex++){
View _view = arrView.get(intIndex);
final View _viewLoader = _view;
imageLoader.get(Const.START_REQUEST_BOOK_IMAGE + arrBook.get(intIndex).getId().toString() + ".jpg", new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
ImageView imgBook = (ImageView) _viewLoader.findViewById(R.id.img_book);
animationChangeImage(imageContainer.getBitmap(),imgBook);
}
#Override
public void onErrorResponse(VolleyError volleyError) {
}
});
TextView txtTitleBook = (TextView) _view.findViewById(R.id.name_book);
txtTitleBook.setVisibility(View.INVISIBLE);
}
}
You need to check that the returned bitmap (imageContainer.getBitmap()) isn't null before going ahead and assigning it.
Try and adding log prints to see if you're getting errors or a null bitmap, which could mean you're performing a bad request or server error, or perhaps the fault is in the animationChangeImage method if the bitmap is received successfully.
Did you try using the ImageRequest class? For example:
ImageRequest irq = new ImageRequest(imgUrl, new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
imView.setImageBitmap(response);
}
}, 0, 0, null, null);

Categories

Resources