In my application i get image from server and those image build animation.this all things are gone be right way and i create method for it.this is the method::
package com.animation;
import java.io.InputStream;
import java.net.URL;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
public class animation extends Activity {
Button Buttona;
AnimationDrawable animation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView img = (ImageView) findViewById(R.id.simple_anim);
animation = new AnimationDrawable();
try {
for(int i=0;i<54;i++)
{
xyz("girl000",i);
}
animation.setOneShot(false);
} catch (Exception e) {
}
img.setBackgroundDrawable(animation);
img.post(new Starter());
}
public void xyz(String str,int x)
{
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(
"http://201.109.115.111/MRESC/images/test/girl/"+"girl000"+x+".png")
.getContent());
Drawable frame =new BitmapDrawable(bitmap);
animation.addFrame(frame, 50);
} catch (Exception e) {
}
}
class Starter implements Runnable {
public void run() {
animation.start();
}
}
}
now my problem is it is take much time to load image from server so simply i plan to use asyncTask. but problem is i cant get judgment that how can i do this?
can you give me example(Note : i know asyncTask and use already but problem is passing argument as per my xyz() method declare)
Thanks
nik
Here is the code:
Note that the loop now is in the background thread
After each loop, you publish the progress to setup the animation frame
At the very end, you run onPostExecute to run the remaining code
Note, that this is just a skeleton and rough sketches, you need to understand and debug it if there is any problem. I haven't run the code yet
public class Animation extends Activity {
Button Buttona;
AnimationDrawable animation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
animation = new AnimationDrawable();
AsyncTask asyncTask =
new AsyncTask() {
#Override
protected Void doInBackground(Void... params) {
try {
// Execute this whole loop in background, so it doesn't
// block your UI Thread
for(int i=0;i<54;i++) {
xyz("girl000",i);
}
} catch (Exception e) {
return null;
}
}
public void xyz(String str,int x) {
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(
"http://201.109.115.111/MRESC/images/test/girl/"+"girl000"+x+".png")
.getContent());
// publish progress so that the bitmap is set on the UI Thread
publishProgress(bitmap);
} catch (Exception e) {
// handle error
}
}
#Override
protected void onProgressUpdate(Bitmap... result) {
// handle the progress update to add the animation frame
Bitmap bitmap = result[0];
Drawable frame =new BitmapDrawable(bitmap);
animation.addFrame(frame, 50);
}
#Override
protected void onPostExecute(Void result) {
if(result != null) {
// execute the rest of your instruction after the loop is over here
animation.setOneShot(false);
ImageView img = (ImageView) findViewById(R.id.simple_anim);
img.setBackgroundDrawable(animation);
img.post(new Starter());
} else {
// handle error
}
}
};
asyncTask.execute();
}
class Starter implements Runnable {
public void run() {
animation.start();
}
}
}
Related
I made a splash activity before my app's main activity. It has a movieview and an animated imageview. I have two problems with the imageview:
Before the fade-in animation starts the image is visible.
During the animation a see the frames. ( And it is not because of the emulator, I also tested it on a Sony Xperia SP.)
My java:
package com.koostamas.tbbt;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.VideoView;
public class SplashActivity extends Activity {
private ImageView circle;
private Animation anim;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
VideoView loading = (VideoView)findViewById(R.id.videoView_loading);
circle = (ImageView) findViewById(R.id.imageView_circle);
loading.setVideoPath("android.resource://com.koostamas.tbbt/raw/splash_loading");
loading.setZOrderOnTop(true);
loading.start();
anim = AnimationUtils.loadAnimation(this, R.anim.fade_in);
}
#Override
public void onWindowFocusChanged (boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus)
circle.startAnimation(anim);
}
Thread thread = new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
try {
sleep(5000);
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
{
thread.start();
}
}
Please help me solve these problems. Thanks in advance.
Instead of using the onWindowFocusChanged register on the videoView's setOnCompletionListener. there you can start your animation.
To call the next activity use :
new Handler().postDelayed(new Runnable() {
public void run()
{ startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish(); }
} , animationTime);
I'm simply loading an image on button click via url , i want progress bar to show downloadin done,0-100 now i had changed the code not showing the progress updation but only progress bar
kindly help. XML has a button [downloadbtn], and a progressbar, imageview and a quit button
mainfest.xml has acsess permission internet
code:
*
package com.example.t4;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
ProgressBar prgs;
ProgressTask task = new ProgressTask();
Button showProgressBtn;
Button stopProgressBtn;
ImageView img;
Bitmap bmp ;
TextView tv1;
int filesize,filedyn;
public void startdownload(){
try { URL url;
url = new URL("http://whywedoit.files.wordpress.com/2009/04/smile.jpg");
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
filesize = urlConnection.getContentLength();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1=(TextView)findViewById(R.id.tv1);
img = (ImageView) findViewById(R.id.imageView1) ;
stopProgressBtn = (Button) findViewById(R.id.btnCancel);
prgs = (ProgressBar) findViewById(R.id.progress);
showProgressBtn = (Button) findViewById(R.id.btn);
prgs.setVisibility(View.INVISIBLE);
img.setVisibility(View.INVISIBLE);
tv1.setVisibility(View.INVISIBLE);
final ProgressTask pgt = new ProgressTask();
showProgressBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(pgt.getStatus()==Status.RUNNING){Toast.makeText(getApplicationContext(), "Status"+pgt.getStatus(), Toast.LENGTH_SHORT).show();}
if(pgt.getStatus()==Status.FINISHED||pgt.getStatus()==Status.PENDING){
Toast.makeText(getApplicationContext(), "Status"+pgt.getStatus(), Toast.LENGTH_SHORT).show();
prgs.setVisibility(View.VISIBLE);
task.execute(10);
tv1.setVisibility(View.VISIBLE);
}}
});
stopProgressBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
stopProgress();
}
});
}
private class ProgressTask extends AsyncTask<Integer,Integer,Void>{
protected void onPreExecute() {
super.onPreExecute();
prgs.setMax(100); // set maximum progress to 100.
}
protected void onCancelled() {
prgs.setMax(0); // stop the progress
Log.v("Progress","Cancelled");
finish();
}
protected Void doInBackground(Integer... params) {
startdownload();
//for(int j=0;j<=filesize;j++){
publishProgress((int) ((filedyn / (float) filesize) * 100));
//}
Log.v("Progress","Downloading");
return null;
}
protected void onProgressUpdate(Integer... values) {
prgs.setProgress(0);
Log.v("Progress","Updating");
}
protected void onPostExecute(Void result) {
img.setVisibility(View.VISIBLE);
tv1.setVisibility(View.INVISIBLE);
img.setImageBitmap(bmp);
prgs.setVisibility(View.INVISIBLE);
Log.v("Progress", "Finished");
}
}
public void stopProgress() {
task.cancel(true);
}
}
*
Sorry, I don't think you only have progress bar update problems. There are too many points needs to be repaired.
1st inside your OnClickListener, you are doing task.execute(10);showProgress(); AsnycTask is asynchronous task, you cannot put your showProgress() there. Do something with your code.
private boolean init = true;
private Void doInBackground(Integer... params) {
init = true;
startdownload();
Log.v("Progress", "Downloading");
return null;
}
protected void onProgressUpdate(Integer... values) {
if (init){
showProgress();
init = false;
}else{
prgs.setProgress(5);
Log.v("Progress", "Once");
}
}
2nd startdownload method, are you sure your startdownload method doing downloading? or just getting the length of filesize. Make it clear else you will get yourself confuse.
3nd To invoke onProgressUpdate, you need to call publishProgress(progressValue); Here's the sample.
private Void doInBackground(Integer... params) {
init = true;
startdownload();
publishProgress(5); // onProgressUpdate invoked
//
// doing download
//
Log.v("Progress", "Downloading");
return null;
}
use this code and use progressdialog instead of progressbar
#Override
protected void onProgressUpdate(Integer... progress) {
//Set the pertange done in the progress dialog
pd.setProgress((int) (progress[0]));
}
You need set the ProgressBar max value and you need to update the progress in onProgressUpdate
protected void onProgressUpdate(Integer... values) {
prgs.setProgress(values[0]);
Log.v("Progress","Once");
}
and call
publishProgress(progress)
in the doInBackground of ProgressTask to update the progress
Check for more ref
I am new to java and andriod and i think that i did something wrong with thread
Program starts without any errors.
I have inserted one button just for test and it shows without problem. Text view doesnt even displays "Hello world" default string.
Here is the code
package com.example.studentservis;
import android.R.string;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.w3c.dom.Text;
public class MainActivity extends Activity {
StringHandler stringHandler = new StringHandler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thread.run();
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
}
};
public String webRequest() throws Exception{
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
public class StringHandler
{
public String str = "test";
public void setString(String s)
{
str = s;
}
public String getString()
{
return str;
}
}
}
When you start a new Thread, the UI thread won't wait until the new thread is complete. That is the purpose of the Threads.
Here :
thread.run();
When you a start the new thread to update the stringHandler, the UI thread tries to process the next command which is :
txtView.setText(stringHandler.getString());
When the UI thread gets to this, the stringHandler hasn't updated yet, so It's null and thus it will show nothing in the textview.
All you should do is to try to update the textview from the new Thread when it's finished.
Try this:
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
});
}
};
You can use a handler or a asyctask for this purpose. Asynctask is easier.
http://developer.android.com/reference/android/os/AsyncTask.html
You can create your own thread but remember to update ui on the ui thread.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="166dp"
android:text="Loading..." />
</RelativeLayout>
MainActivity.java
Removed StringHandler cause i felt it was unnecessary in this context.
public class MainActivity extends Activity {
TextView txtView ;
String s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtView = (TextView)this.findViewById(R.id.textView1); // initialize textview
//txtView.setText(stringHandler.getString());
new Thread(new Runnable() { // thread
#Override
public void run(){
try {
s = webRequest(); // get string
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() //run on ui threa
{
public void run()
{
txtView.setText(s); // update ui on the ui thread.
}
});
}
}).start();
}
public String webRequest() throws Exception{ // web request
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
}
Resulting snap shot
This part of your code : txtView.setText(stringHandler.getString());
should be put after the thread finished.
thread.run(); <------ Start running thread in background
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
// the textView was set without knowing whether the Thread is finished or not.
// thus, textView is shown as empty, because stringHandler.getString() still has empty string
My suggestion is that you implement it inside an asyncTask, so that you can set the text within onPostExecute()
Good luck ^^
EDIT :
here's some example AsyncTask
private class StringSet extends AsyncTask <Void,Void,Void> {
#Override
protected void doInBackground(Void... params) {
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
stringHandler.setString(e.getMessage());
}
}
#Override
protected void onPostExecute(Void... results) {
txtView.setText(stringHandler.getString());
}
}
And replace your thread.run() with new StringSet().execute();
I'm a newbie programmer an I'm making an android program that displays an image on ImageView from a given url. My problem is how do you use this on the AsyncTask?
These codes work on min SDK 2.2 but I switched to min SDK 3.0 so it needs to run on the AsyncTask. Thank you for your help! :)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
satellite(); //satellite's image from main menu
}
//******satellite url
private void satellite() {
// TODO Auto-generated method stub
ImageView imgView =(ImageView)findViewById(R.id.satellite);
Drawable drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
imgView.setImageDrawable(drawable);
}
private Drawable LoadImageFromWeb(String url){
try{
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
well, I dont know why android SDK does not provide support for it (yet) I extended the ImageView class by UrlImageView class with asynchronous loading and caching support. I put the code of my class below, which is plug and play. The class body is at the end of my post, now I write two lines how to use it the convenient way.
Two more methods now are supported:
setImageUrl(URL url) // sets the bitmap by its URL
cancelLoading(); // tell this view to cancel pending load
How to use your java-code:
// [somewhere in your activity]
UrlImageView urlImg = new UrlImageView(this).setImageUrl("http://abc.png");
...
urlImg.setImageUrl("http://abc2.png"); // works like expected
How to bind in your layouts:
<!-- thumbnail -->
<com.gplushub.android.view.UrlImageView
android:id="#+id/thumbnail"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:scaleType="fitXY" />
..and again in your activity java code:
((UrlImageView)findViewById(R.id.thumbnail)).setImageUrl("http://foo.bar.png");
I use it in lists with more than 100 entries - flinging very well. Here the class body, you can use it, modify it, extend it, whatever you like:
package com.gplushub.android.view;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* an {#link ImageView} supporting asynchronous loading from URL. Additional
* APIs: {#link #setImageURL(URL)}, {#link #cancelLoading()}.
*
* #author ep#gplushub.com / Eugen Plischke
*
*/
public class UrlImageView extends ImageView {
private static class UrlLoadingTask extends AsyncTask<URL, Void, Bitmap> {
private final ImageView updateView;
private boolean isCancelled = false;
private InputStream urlInputStream;
private UrlLoadingTask(ImageView updateView) {
this.updateView = updateView;
}
#Override
protected Bitmap doInBackground(URL... params) {
try {
URLConnection con = params[0].openConnection();
// can use some more params, i.e. caching directory etc
con.setUseCaches(true);
this.urlInputStream = con.getInputStream();
return BitmapFactory.decodeStream(urlInputStream);
} catch (IOException e) {
Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e);
return null;
} finally {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
; // swallow
} finally {
this.urlInputStream = null;
}
}
}
}
#Override
protected void onPostExecute(Bitmap result) {
if (!this.isCancelled) {
// hope that call is thread-safe
this.updateView.setImageBitmap(result);
}
}
/*
* just remember that we were cancelled, no synchronization necessary
*/
#Override
protected void onCancelled() {
this.isCancelled = true;
try {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
;// swallow
} finally {
this.urlInputStream = null;
}
}
} finally {
super.onCancelled();
}
}
}
/*
* track loading task to cancel it
*/
private AsyncTask<URL, Void, Bitmap> currentLoadingTask;
/*
* just for sync
*/
private Object loadingMonitor = new Object();
public UrlImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public UrlImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UrlImageView(Context context) {
super(context);
}
#Override
public void setImageBitmap(Bitmap bm) {
cancelLoading();
super.setImageBitmap(bm);
}
#Override
public void setImageDrawable(Drawable drawable) {
cancelLoading();
super.setImageDrawable(drawable);
}
#Override
public void setImageResource(int resId) {
cancelLoading();
super.setImageResource(resId);
}
#Override
public void setImageURI(Uri uri) {
cancelLoading();
super.setImageURI(uri);
}
/**
* loads image from given url
*
* #param url
*/
public void setImageURL(URL url) {
synchronized (loadingMonitor) {
cancelLoading();
this.currentLoadingTask = new UrlLoadingTask(this).execute(url);
}
}
/**
* cancels pending image loading
*/
public void cancelLoading() {
synchronized (loadingMonitor) {
if (this.currentLoadingTask != null) {
this.currentLoadingTask.cancel(true);
this.currentLoadingTask = null;
}
}
}
}
If the image is not that big you can just use an anonymous class for the async task. This would like this:
ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";
mChart.setTag(URL);
new DownloadImageTask.execute(mChart);
and the task class is
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
#Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
#Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
private Bitmap download_Image(String url) {
...
}
Try this code, make your drawable variable global and change your satellite function like this:
private void satellite() {
// TODO Auto-generated method stub
ImageView imgView =(ImageView)findViewById(R.id.satellite);
new yourTask().execute();
}
then create asyncTask class like this:
private class yourTask extends AsyncTask<Integer, Void, Integer> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//show a progress bar
}
#Override
protected String doInBackground(Integer... params) {
drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
return 0;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
imgView.setImageDrawable(drawable);
}
}
Here is the code for the Aynctask implementation
Make your drawable object as global in Aynctask class.
Class MyDownloader extends AsyncTask<Void,Void,String>{
Drawable drawable;
#Override
public String doInBackground(Void... args){
drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
return null; // here you can pass any string on response as on error or on success
}
public void onPostExecute(String result){
if(drawable!=null){
imgView.setImageDrawable(drawable);
}
}
}
now create object of this class and execute it
private void satellite() {
// TODO Auto-generated method stub
ImageView imgView =(ImageView)findViewById(R.id.satellite);
new MyDownloader.execute();
}
Here is good example link for caching the image check out this link and example
https://github.com/novoda/ImageLoader
You are right when u do any network operation later Android 2.2(Froyo) Must use Asynctask
This is the best example to understand AsyncTask
based on the answer from comeGetSome i created my own implementation which works with normal ImageView class instead of creating a new class UrlImageView, also new options are provided like - what to do when the loading completes or cancels
Now load image as you want, like this from any of the three loadImage methods
UrlImageLoader urlImageLoader=new UrlImageLoader();
ImageView imageView=new ImageView(context);
//load and set the image to ImageView
urlImageLoader.loadImage(imageView, "http://www......com/.....jpg");
//for loading a image only - load image and do any thing with the bitmap
urlImageLoader.loadImage("http://www......com/.....jpg", new UrlImageLoader.OnLoadingCompleteListener() {
#Override
public void onComplete(ImageView imageView, Bitmap bmp) {
// do anything with the Bitmap
// here imageView will be null
}
#Override
public void onCancel(ImageView imageView) {
}
});
urlImageLoader.loadImage(imageView, "http://www......com/.....jpg", new UrlImageLoader.OnLoadingCompleteListener() {
#Override
public void onComplete(ImageView imageView, Bitmap bmp) {
// do anything with the Bitmap
// here imageView is not null
imageView.setImageBitmap(bmp);
}
#Override
public void onCancel(ImageView imageView) {
}
});
create this class for loading UrlImageLoader
/*special thanks to stackoverflow.com user comeGetSome for UrlImageLoadingTask code
* question - http://stackoverflow.com/questions/14332296/how-to-set-image-from-url-using-asynctask/15797963
* comeGetSome - http://stackoverflow.com/users/1005652/comegetsome
*/
package com.GameG.SealTheBox;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
public class UrlImageLoader {
public static interface OnLoadingCompleteListener {
public void onComplete(ImageView imageView, Bitmap bmp);
public void onCancel(ImageView imageView);
}
ArrayList<UrlImageLoadingTask> loadingList=new ArrayList<UrlImageLoadingTask>();
/**
* Loads a image from url and calls onComplete() when finished<br>
* #Note you should manually set the loaded image to ImageView in the onComplete()
* #param imageView
* #param url
* #param onComplete
*/
public void loadImage(ImageView imageView, String url, OnLoadingCompleteListener onComplete){
try {
URL url2=new URL(url);
if(imageView!=null){
for(int i=0;i<loadingList.size();i++){
UrlImageLoadingTask tmptask=loadingList.get(i);
if(tmptask.updateView!=null && tmptask.updateView.equals(imageView)){
tmptask.cancel(true);
break;
}
}
}
UrlImageLoadingTask loadtask=new UrlImageLoadingTask(imageView,onComplete,url);
loadtask.execute(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* Loads a image from url and calls onComplete() when finished
* #param url
* #param onComplete
*/
public void loadImage(String url, OnLoadingCompleteListener onComplete){
loadImage(null,url,onComplete);
}
/**
* Loads a image from url and sets the loaded image to ImageView
* #param imageView
* #param url
*/
public void loadImage(ImageView imageView, String url){
loadImage(imageView,url,null);
}
/**
* Cancel loading of a ImageView
*/
public void cancel(ImageView imageView){
for(int i=0;i<loadingList.size();i++){
UrlImageLoadingTask tmptask=loadingList.get(i);
if(tmptask.updateView.equals(imageView)){
loadingList.remove(i);
tmptask.cancel(true);
break;
}
}
}
/**
* Cancel loading of a Url
*/
public void cancel(String url){
for(int i=0;i<loadingList.size();i++){
UrlImageLoadingTask tmptask=loadingList.get(i);
if(tmptask.url.equals(url)){
loadingList.remove(i);
tmptask.cancel(true);
break;
}
}
}
/**
* Cancel all loading tasks
*/
public void cancelAll(){
while(loadingList.size()>0){
UrlImageLoadingTask tmptask=loadingList.get(0);
loadingList.remove(tmptask);
tmptask.cancel(true);
}
}
private class UrlImageLoadingTask extends AsyncTask<URL, Void, Bitmap> {
public ImageView updateView=null;
public String url;
private boolean isCancelled = false;
private InputStream urlInputStream;
private OnLoadingCompleteListener onComplete=null;
private UrlImageLoadingTask(ImageView updateView, OnLoadingCompleteListener onComplete, String url) {
this.updateView=updateView;
this.onComplete=onComplete;
this.url=url;
}
#Override
protected Bitmap doInBackground(URL... params) {
try {
URLConnection con = params[0].openConnection();
// can use some more params, i.e. caching directory etc
con.setUseCaches(true);
this.urlInputStream = con.getInputStream();
return BitmapFactory.decodeStream(urlInputStream);
} catch (IOException e) {
Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e);
return null;
} finally {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
; // swallow
} finally {
this.urlInputStream = null;
}
}
}
}
#Override
protected void onPostExecute(Bitmap result) {
if (!this.isCancelled) {
// hope that call is thread-safe
if(onComplete==null){
if(updateView!=null)
this.updateView.setImageBitmap(result);
}else{
onComplete.onComplete(updateView, result);
}
}
loadingList.remove(this);
}
/*
* just remember that we were cancelled, no synchronization necessary
*/
#Override
protected void onCancelled() {
this.isCancelled = true;
try {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
;// swallow
} finally {
this.urlInputStream = null;
}
}
} finally {
super.onCancelled();
if(onComplete!=null)
onComplete.onCancel(updateView);
loadingList.remove(this);
}
}
}
}
Just create a new class "DownloadImageTask" like following one and put it at the same folder where you have your Activity.
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;
import android.os.AsyncTask;
import java.io.*;
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap myImage = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
myImage = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return myImage;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
After this add line to crate that class in your Activity.
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;
import android.widget.ImageView;
public class HomeScreen extends ActionBarActivity {
private final String TAG = "test1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_home_screen);
InitHomeScreen();
}
protected void InitHomeScreen()
{
String imageUrl = "http://s20.postimg.org/4t9w2pdct/logo_android_png.png";
Log.d(TAG, "Get an Image");
// Get an Image
try{
AsyncTask<String, Void, Bitmap> execute = new DownloadImageTask((ImageView) findViewById(R.id.imageView))
.execute(imageUrl);
// R.id.imageView -> Here imageView is id of your ImageView
}
catch(Exception ex)
{
}
}
// Other code...
Don't forget to allow access to INTERNET to your Android app.
Check your manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dmitry.myapplication1" >
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".HomeScreen"
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>
The following code is for a splash screen in my app.What I need to be done is when the activity loads the image should be displayed as default and then after few seconds the image should be changed to another in the same activity. I have another image like the first one with different color. I wanted to change the screen for that image after few seconds.
I have done it like this in my code.
package com.ruchira.busguru;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class SplashScreen extends Activity {
ImageView imgBus;
MediaPlayer introSound, bellSound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
imgBus = (ImageView) findViewById(R.id.imgBus);
imgBus.setImageResource(R.drawable.blackbus);
introSound = MediaPlayer.create(SplashScreen.this, R.raw.enginestart);
introSound.start();
Thread timer = new Thread(){
public void run(){
try{
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
imgBus.setImageResource(R.drawable.bluekbus);
}
}
};
timer.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.splash_screen, menu);
return true;
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
introSound.stop();
finish();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
introSound.stop();
finish();
}
}
but the problem is the program stops by executing in the thread saying...
"android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."
How I can achieve this target ? Does anybody please help me to sort out this problem. I am new to android development..
Thanks.
You should use the ImageView's Handler and a Runnable. Handler's are schedulers specific to Android and they can run on the UI thread. Try this:
ImageView imgBus;
MediaPlayer introSound, bellSound;
Runnable swapImage = new Runnable() {
#Override
public void run() {
imgBus.setImageResource(R.drawable.bluekbus);
}
};
And inside onCreate() call:
imgBus = (ImageView) findViewById(R.id.imgBus);
imgBus.setImageResource(R.drawable.blackbus);
imgBus.postDelayed(swapImage, 3000); // Add me!
Understand that splash screens are frowned upon because you should focus on starting the app as soon as possible (while loading the slower element in the background). However sometimes a slight delay is unavoidable.
Write this inside finally
runOnUiThread(new Runnable() {
public void run() {
SplashScreen.class.img.setImageResource(R.drawable.bluekbus);
}
});
You should always update your UI from the UI Thread itself...
Try the following,
We cannot access and update the UI from worker threads, only we can access the UI from UIThread. If we need it to update with background thread then we can use Handler to do this like in the following code.
this.imgBus = (ImageView) findViewById(R.id.splashImageView);
imgBus.setImageResource(R.drawable.your_first_image);
this.handler = new Handler();
introSound = MediaPlayer.create(SplashTestForSO.this, R.raw.enginestart);
introSound.start();
Thread timer = new Thread(){
public void run(){
try{
sleep(2000);
YourActivity.this.handler.post(runnable);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
}
}
};
timer.start();
this.runnable = new Runnable() {
public void run() {
//call the activity method that updates the UI
YourActivity.this.imgBus.setImageResource(R.drawable.your_scond_image_view);
}
};