I'm making this netflix style app in which images are loaded into different categories. Let's say Dog videos (has 15 images), Cat videos (15 images), etc... All the images are loaded from a URL, it kind of takes a while for all to load. I was wondering if there was anything I could do to speed up the process? Or maybe show an empty container then fill it as the images load (that would be cool).
This is what I have done:
I have multiple async calls in one Activity, (1 async call per category)
JSONTask1 dogTask = new JSONTask1();
JSONTask2 catTask = new JSONTask2();
JSONTask3 pigTask = new JSONTask3();
JSONTask4 horseTask = new JSONTask4();
dogTask.execute("");
catTask.execute("");
pigTask.execute("");
horseTask.execute("");
I have all of those in a row in my actual code. Thanks.
I would use the "proxy pattern". Basically, you need to create a class that contains the minimal informations required for the display. In which, you have a preview image.
When ever you load everything you start by showing the preview content, ie : a loading gif for everypicture with the title of the movie or whatever. and basically the proxy would have a "loadImage" method that would make an ajax call or async call and the photos would load one by one. Plus, to make the loading easier, make sure the photos are not oversized.
You can see Picasso answers , in picasso i suggest you this way :
Picasso.with(getApplicationContext()).load("your url").placeholder(R.drawable.your_place_holder).error(R.drawable.showing_when_error_occured)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
}
});
Also another suggestion from me : convert your thumb images to base64 format in backend, then firstly retrieve your thumbs and show them. Then start an async task and change images when successfull.
Like whatsapp. In whatsapp you have thumb images they have so low resolution and super fast. When you click image if you have internet connection they load actual thumb images, and click again they load larger image.
Picasso website :http://square.github.io/picasso/
Load them asynchronously with Picasso, you can even show a placeholder image until the real one is loaded
Related
Relevant code:
YouTubeThumbnailView first_video = (YouTubeThumbnailView) findViewById(R.id.main_video);
first_video.initialize(Config.YOUTUBE_API, new YouTubeThumbnailView.OnInitializedListener() {
#Override
public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
final String video = getResources().getString(R.string.principal_funcoes);
youTubeThumbnailLoader.setVideo(video);
}
The time it takes for the method 'youTubeThumbnailLoader.setVideo(String s)" to work is absurd.
It takes 30+ seconds for a thumbnail to show up, with full cabled connection (100mbps).
It's definitely impossible for a user to wait more than 2 seconds for the thumbnail to show up, and have a completely blank screen while he waits for that to happen.
What can I do to load the video thumbnail any faster, or at least make YouTubeThumbnailView show a loading image while it fetches the thumbnail?
You can use direct youtube api urls for getting youtube thumbnails and they are way to faster too. here are urls you can try.
Start:-- It is only give you default size thumbnails.
https://ytimg.googleusercontent.com/vi/<insert-youtube-video-id-here>/default.jpg
For the high quality version of the thumbnail use a url similar to this:
https://ytimg.googleusercontent.com/vi/<insert-youtube-video-id-here>/hqdefault.jpg
There is also a medium quality version of the thumbnail, using a url similar to the HQ:
https://ytimg.googleusercontent.com/vi/<insert-youtube-video-id-here>/mqdefault.jpg
For the standard definition version of the thumbnail, use a url similar to this:
https://ytimg.googleusercontent.com/vi/<insert-youtube-video-id-here>/sddefault.jpg
For the maximum resolution version of the thumbnail use a url similar to this:
https://ytimg.googleusercontent.com/vi/<insert-youtube-video-id-here>/maxresdefault.jpg
It helps me to develop youtube application, Hope it also help you.
I am building my application using Android Studio, this app can upload an image from raspberry to my emulator. It works fine. What I want to do now is uploading this image and showing it directly to the user without searching it in the gallery. I thought about creating another class and setting this image as a background image in my xml file, but this is too much like I have to create another class every time I want to upload an image from my raspberry.
Can someone help me please. Thank you
If I'm understanding your question correctly, you'd like to load an image from the Android filesystem into your app and display it to the user.
Drawable, Android's generalized image class, allows you to load from file via Drawable#createFromPath.
This SO question suggests Drawable#createFromPath doesn't work on paths beginning with file://, so depending on your use case you may want to precede that with Uri#parse/Uri#getPath.
Once you have a Drawable, you can display it in one of two ways: put an ImageView in your app and call its setImageDrawable method, or set the Drawable as your background image via View#setBackground (note that setBackground was only added in API 16 - in prior versions, you should call View#setBackgroundDrawable).
Putting all of this together, we end up with the following (untested):
private void loadImage(String imagePath) {
Uri imageUri;
String fullImagePath;
Drawable image;
ImageView imageDisplay;
imageUri = Uri.parse(imagePath);
fullImagePath = imageUri.getPath();
image = Drawable.createFromPath(fullImagePath);
imageDisplay = (ImageView) findViewById(R.id.imageDisplay);
/*if image is null after Drawable.createFromPath, this will simply
clear the ImageView's background */
imageDisplay.setImageDrawable(image);
/*if you want the image in the background instead of the foreground,
comment the line above and uncomment this bit instead */
//imageDisplay.setBackground(image);
}
You should be able to modify this to work with any View just by replacing imageDisplay's declared type with the appropriate View type and changing the cast on findViewById. Just make sure you're calling setBackground, not setImageDrawable, for a non-ImageView View.
So at certain times I need to clear the Picasso cache within my application, however when I clear it, the image is the same. If the image URL changes, then it pulls the new image but if the image url is the same, then the old image remains.
Can anyone help me clear the cache so that the image is removed?
This is how I set Picasso up:
Cache picassoCache = new LruCache(MEMORY_CACHE_SIZE);
picassoCacheClearer = new PicassoCacheClearerImpl(picassoCache);
picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(context.getCacheDir(), IMAGE_CACHE_SIZE))
.memoryCache(picassoCache)
.build();
and then try and clear it by:
cache.clear();
Below is the code which actually loads the image:
picasso.load(carouselAction.getImageUrl())
.placeholder(R.drawable.ic_placeholder)
.into(viewHolder.plistImageView);
I can see that the Invalidate() method is now deprecated, so what else can i do?
I have had this same problem and I used this hacky method to get around it. To force it to refresh i would just change the url adding a version tag to it. This is used commonly in web development to make sure things aren't used from the cache.
For example i would load an image from example.com/mypic.png?version=1234
and since the url is different it wouldn't load it from cache.
String versionTag = "?version=" + new Date().getTime();
picasso.load(carouselAction.getImageUrl() + versionTag)
.placeholder(R.drawable.ic_placeholder)
.into(viewHolder.plistImageView);
So found out what the issue was. Turns out for this carousel it was using a different instance of Picasso.
I also had to extend OkHttpDownloader to expose the getClient() method in order to get the cache to delete.
I realised it was a different instance of Picasso by enabling the indicators which can be done by setting the following in the builder
.indicatorsEnabled(true);
What I would like to have is an activity indicator, which is displayed after my app is up and running, but while GWT is making AJAX calls.
For example have a look at following site : http://www.foodtrucksmap.com/#
Any ideas on how to achieve it?
You can use an activity indicator from here, they are animated gifs so you can display one like this:
<g:Image ui:field="activityImage"/>
MyResources resources = GWT.create(MyResources.class);
this.activityImage.setResource(resources.activityImage());
and in your resources interface you would set the image:
public interface MyResources extends ClientBundle{
// use the actual path to your image
#Source("../resources/images/activityImage.gif")
ImageResource activityImage();
}
When you make your async calls:
loadingImage.setVisible(true);
and in the callback:
loadingImage.setVisible(false);
I had to deal with the same kind of stuff few days back. The way I did was, created an Icon and Overlayed on the map.
Icon icon = Icon.newInstance("loading.gif"); // load you gif as icon
MarkerOptions options = MarkerOptions.newInstance();
options.setIcon(icon);
Marker indicator = new Marker(point, options);
So before the Async call and after you map is up, just add the icon to the map using
map.addOverlay(indicator);
and after the Async call remove the overlay using
map.removeOverlay(indicator);
I am not sure how correct this approach is, but this is what I did and it worked.
In my application I'd like to show some animations at the startup in some special events like Halloween, Thanksgiving, Christmas etc.
I didn't find a hot to show an animated .gif in a View. The closest solution I found is to make an AnimationDrawable with the gif frames.
I'm trying to implement that but have some questions about how to store (currently i'm using a LAMP server), transfer and recover the resources needed from the server to the Android device.
Downloading the .gif data to the phone and extract there the frames and framerate programmatically is a nice solution or it will add an unnecessary load to the client? If its appropriated is there some library or source for guiding me in with that task?
If I want to handle the gif in the server and then I want to serve it to the client frame-by-frame, how can I do that? I've thought in making a JSON with the URL's of the images and download them but maybe is not a nice option since I'd need a lot of http connections and the load could be slower if the network latency is high
Where can I find the internal structure of a gif? I have searched in Google but nothing found
Thanks in advance
Downloading the .gif data to the phone and extract there the frames and framerate
programmatically is a nice solution or it will add an unnecessary load to the client?
If its appropriated is there some library or source for guiding me in with that task?
if you want to extract the gif file to get the frames and the frame rate you need a GIF decoder and then applay them to the AnimationDrawable this will help you to add frames diagrammatically.
this two links can help you to extract the gif image in android
http://www.basic4ppc.com/android/help/gifdecoder.html
http://code.google.com/p/loon-simple/source/browse/trunk/android/LGame-Android-0.2.6S/org/loon/framework/android/game/core/GIFDecoder.java?r=7
Definitely do it on the client side. Have you seen this? Splitting the animation into multiple images and rendering it on the client side with an AnimationDrawable may be the only way to go.
You will require to extend a view to make it to play .gif
Consider the following code
private class GifView extends View{
Movie movie;
InputStream in=null;
long moviestart;
Url url
public GifView(Context context,String downloadUrl) {
super(context);
this.url=new Url(downloadUrl);
URLConnection con = url.openConnection();
in=con.getInputStream()
movie=Movie.decodeStream(in);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
super.onDraw(canvas);
long now=android.os.SystemClock.uptimeMillis();
Log.v("tag","now="+now);
if (moviestart == 0) { // first time
moviestart = now;
}
Log.v("tag","\tmoviestart="+moviestart);
int relTime = (int)((now - moviestart) % movie.duration()) ;
Log.v("tag""time="+relTime+"\treltime="+movie.duration());
movie.setTime(relTime);
movie.draw(canvas,this.getWidth()/2-20,this.getHeight()/2-40);
this.invalidate();
}
}
Use This view in you xml and supply the url,
If network Latency is present download the gif in separate thread and supply the input stream to the constructor
Change it to
public GifView(Context context,InputStream in) {
super(context);
movie=Movie.decodeStream(in);
}