Here the below example shows how to access .gif images from web and shown in android programmatically(Load animated GIF from Internet)
when an application attempts to perform a networking(Internet) operation(i.e connecting to internet,dowload images etc..) on its main thread.we will get "NetworkOnMainThreadException"
In such cases we should implement this requirement using background task like(asynctask,threads)
Here the below code to load gif image from URL
1) Create ShowGifView.java class which extends View
This is the main class ShowGifView takes input as context object and url of .gif image .
get the image from url and reload view.
package com.androidsurya.giffromurl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
public class ShowGifView extends View {
// Set true to use decodeStream
// Set false to use decodeByteArray
private static final boolean DECODE_STREAM = true;
private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;
static String gifURL;
public ShowGifView(Context context, String a) {
super(context);
gifURL = a;
init(context);
}
public ShowGifView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ShowGifView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(final Context context) {
setFocusable(true);
gifMovie = null;
movieWidth = 0;
movieHeight = 0;
movieDuration = 0;
Loder task = new Loder();
task.execute(new String[] { gifURL });
}
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int len;
try {
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
} catch (java.io.IOException e) {
}
return os.toByteArray();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}
public int getMovieWidth() {
return movieWidth;
}
public int getMovieHeight() {
return movieHeight;
}
public long getMovieDuration() {
return movieDuration;
}
@Override
protected void onDraw(Canvas canvas) {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (gifMovie != null) {
int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}
int relTime = (int) ((now - mMovieStart) % dur);
gifMovie.setTime(relTime);
gifMovie.draw(canvas, 0, 0);
invalidate();
}
}
private class Loder extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
URL gifURL;
try {
gifURL = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) gifURL
.openConnection();
gifInputStream = connection.getInputStream();
// Insert dummy sleep
// to simulate network delay
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (DECODE_STREAM) {
gifMovie = Movie.decodeStream(gifInputStream);
} else {
byte[] array = streamToBytes(gifInputStream);
gifMovie = Movie.decodeByteArray(array, 0, array.length);
}
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
invalidate();
requestLayout();
}
}
}
when an application attempts to perform a networking(Internet) operation(i.e connecting to internet,dowload images etc..) on its main thread.we will get "NetworkOnMainThreadException"
In such cases we should implement this requirement using background task like(asynctask,threads)
Here the below code to load gif image from URL
1) Create ShowGifView.java class which extends View
This is the main class ShowGifView takes input as context object and url of .gif image .
get the image from url and reload view.
package com.androidsurya.giffromurl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
public class ShowGifView extends View {
// Set true to use decodeStream
// Set false to use decodeByteArray
private static final boolean DECODE_STREAM = true;
private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;
static String gifURL;
public ShowGifView(Context context, String a) {
super(context);
gifURL = a;
init(context);
}
public ShowGifView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ShowGifView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(final Context context) {
setFocusable(true);
gifMovie = null;
movieWidth = 0;
movieHeight = 0;
movieDuration = 0;
Loder task = new Loder();
task.execute(new String[] { gifURL });
}
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int len;
try {
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
} catch (java.io.IOException e) {
}
return os.toByteArray();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}
public int getMovieWidth() {
return movieWidth;
}
public int getMovieHeight() {
return movieHeight;
}
public long getMovieDuration() {
return movieDuration;
}
@Override
protected void onDraw(Canvas canvas) {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (gifMovie != null) {
int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}
int relTime = (int) ((now - mMovieStart) % dur);
gifMovie.setTime(relTime);
gifMovie.draw(canvas, 0, 0);
invalidate();
}
}
private class Loder extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
URL gifURL;
try {
gifURL = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) gifURL
.openConnection();
gifInputStream = connection.getInputStream();
// Insert dummy sleep
// to simulate network delay
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (DECODE_STREAM) {
gifMovie = Movie.decodeStream(gifInputStream);
} else {
byte[] array = streamToBytes(gifInputStream);
gifMovie = Movie.decodeByteArray(array, 0, array.length);
}
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
invalidate();
requestLayout();
}
}
}
2) Create showgif.xml file under layout folder.
Copy the below code
Here addView used to attach .gif view to this layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/addView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
</LinearLayout>
package com.androidsurya.giffromurl;
import android.app.Activity;
import android.os.Bundle;
import android.widget.RelativeLayout;
public class ShowGifActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.showgif);
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.addView);
//code to add gif image view to RelativeLayout -here created object to ShowGifView.class and pass the current object and url
myLayout.addView(new com.androidsurya.giffromurl.ShowGifView(this,
"http://www.dan-dare.org/Dan%20Sonic/SonicTailsPlaneAni.gif"));
}
}
4) Last but important thing is AndroidManifest.xml
Note : Add Internet permission and android:hardwareAccelerated="false" Tags.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidsurya.giffromurl"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.androidsurya.giffromurl.ShowGifActivity"
android:hardwareAccelerated="false"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package="com.androidsurya.giffromurl"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.androidsurya.giffromurl.ShowGifActivity"
android:hardwareAccelerated="false"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Output Screenshot: