Getting image from asynctask to custom Gridview Adapter - android

i am making a gallery app and when i execute my asynctask in Getview of Adapter class then only onPreExecution part of Asynctask gets execute and others don't.
So, what i see is a progress bar But not the image after downloading...on my activity just a progress bar keeps on rolling
Here is my code of Getview method
enter public View getView(int position, View convertview, ViewGroup parent) {
// TODO Auto-generated method stub
img=new ImageView(mContext);
new DownloadImage().execute();
return img;
}
and this is my Asynctaskclass
private class DownloadImage extends AsyncTask<String, Void, Bitmap>{
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(mContext);
// Set progressdialog title
mProgressDialog.setTitle("Download Image");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Bitmap doInBackground(String... URL) {
// TODO Auto-generated method stub
String imageURL = URL[0];
Bitmap bitmap = null;
try {
// Download Image from URL
InputStream input = new java.net.URL(imageURL).openStream();
// Decode Bitmap
bitmap = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
// Set the bitmap into ImageView
img.setImageBitmap(result);
// Close progressdialog
mProgressDialog.dismiss();
}
}
I think Just right after executing onPreExecution my GetView method return img variable to my MainActivity class..here it is
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setTitle("My Gallery");
GridView g=(GridView)findViewById(R.id.gallery);
// Gallery g=(Gallery)findViewById(R.id.gallery);
// ImageAdapter width=new ImageAdapter(context);
g.setAdapter(new ImageAdapter(this));
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
GRID_PADDING, r.getDisplayMetrics());
g.setNumColumns(NUM_OF_COLUMN);
g.setColumnWidth(columnWidth);
g.setStretchMode(GridView.NO_STRETCH);
g.setPadding((int) padding, (int) padding, (int) padding,
(int) padding);
// g.setHorizontalSpacing((int) padding);
// g.setVerticalSpacing((int) padding);
g.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView parent, View v, int position,
long id) {
// TODO Auto-generated method stub
Intent i=new Intent(getApplicationContext(),ImageViewPager.class);
i.putExtra("id", position);
startActivity(i);
}
});
Can anybody tell me how to proceed?

You shouldn't be running your AsyncTask in getView(). Since it is asynchronous, getView() won't wait for it to return. It will return a blank ImageView.
You should run the task before setting the adapter and get all of the images first.
You can also use some image loading library like Picaso. You can Google and find other libraries, as well, and how to use them. And you shouldn't be using StrictMode.
To get the images before running getView()
Run the task in onCreate(). Then simply set your Adapter in onPostExecute() of your task.
Related explanation

Related

Using Cache in android application

I've developing a android application and there's a feature in it that loads some images using asynctask. I think if i can save these images as cache i can boost the performance of the app as i am loading a lot of images. How can i do this? How can i keep cache in my android application?
My class
public class MovieFragment extends Fragment {
private ViewPager viewPager;
private PageAdapter pageAdapter;
private ViewPageAdapter adapter;
private ArrayList<BaseElement> filmCategory;
private Fragment fragment;
private Activity activity;
private CommonVariable commonVariable;
private FilmCategory category;
private Dialog dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.movie_fragment, container, false);
fragment = this;
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
viewPager = (ViewPager) view.findViewById(R.id.news_page_viewpager);
dialog = new Dialog(this.getActivity(),
android.R.style.Theme_Translucent_NoTitleBar);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
filmCategory = JSONServices.getCategory();
return null;
}
#Override
protected void onPostExecute(Void result) {
commonVariable.setCategory(filmCategory);
if (filmCategory != null) {
pageAdapter = new PageAdapter(
fragment.getChildFragmentManager(), filmCategory,
activity);
viewPager.setAdapter(pageAdapter);
} else {
Toast.makeText(activity, "No Active Internet Connection",
Toast.LENGTH_LONG).show();
}
dialog.dismiss();
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
// commonVariable.setFilmDetails((FilmCategory)
// category.getFilm().get(position));
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog.setContentView(R.layout.dialog);
dialog.show();
super.onPreExecute();
}
}
if you are downloading images from server then i think Volley library help you out. it will remove boilerplate code and easy to read it support caching also. and if you want to implement cache then follow this link. and please avoid asyctask it will not survive config changes. use asynctaskLoader :-)
It seems that it might be easiest to use a third party library such as Picasso, Universal Image Loader, or Volley
I would check those out first before trying to implement your system for image caching. In most cases one of those three options will handle everything you need to accomplish.

How do I set up my doInBackground's params in my AsyncTask?

my screen when I click on a button is slow to load (because of downloading images? the image files are really small though) so I tried to use AsyncTask to help. The program works, but I moved the image loading to an AsyncTask to see if it would load faster and the app crashes every time. I'm guessing it has to do with the way I have it set up. How would I fix it? Would using a runnable thread be better instead? Thanks!
The class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// no title
requestWindowFeature(Window.FEATURE_NO_TITLE);
// set full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// inflate listview
setContentView(R.layout.gmg);
**new Load.execute(); // executes AsyncTask**
...
gmgListView = (ListView) findViewById(R.id.gmg_list2);
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
gmgListView.setOnItemClickListener(this);
}
The AsyncTask:
private class Load extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(GMGListViewActivity.this);
#Override
protected void onPreExecute() {
Dialog.setMessage("Doing something...");
Dialog.show();
}
#Override
protected Void doInBackground(String... params) {
SparseArray<Spanned> gmgText = null;
Integer[] right = null;
SparseArray<Drawable> appIcon = null;
try {
gmgText = ParseContent.queryGMGText();
right = ParseContent.queryGMGRight();
appIcon = ParseContent.queryDrawable();
} catch (ParseException e) {
e.printStackTrace();
}
// Inflate GMG's rows
rowItems = new ArrayList<GMGRowItem>();
for (int i = 0; i < gmgText.size(); i++) {
GMGRowItem item = new GMGRowItem(appIcon.get(i), gmgText.get(i), right[i]);
rowItems.add(item);
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
You need to apply some changes in your code like...
need to set list adapter in onPostExecute method and remove it from onCreate().
After completing background process it will interact with ui thread.
protected void onPostExecute(Void unused) {
Dialog.dismiss();
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
}
Try this and let me know if you got any isssue.

freezing progressbar before updating listview

i want to show an circle before updating the listview , everything is working fine, while doinbackground of async task fetch the data from server it shows the progressbar but while updating the listview it freezes for sometime and then listview is shown, i want to remove that freezing of progressbar before updating, here is my code
public class feeds extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>{
protected void onPreExecute() {
// SHOW THE SPINNER WHILE LOADING FEEDS
linlaHeaderProgress.setVisibility(View.VISIBLE);
}
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
new_request_feeds(); //here i am fetching data from server
return fetch;
}
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// HIDE THE SPINNER AFTER LOADING FEEDS
linlaHeaderProgress.setVisibility(View.GONE);
if(result.size()!=0)
{
adapter=new CustomListAdapter(getActivity(), R.id.list_ongoing, result);
list.setAdapter(adapter);
}
else
{
Toast.makeText(getActivity(), "no feeds", 3000).show();
}// Here if you wish to do future process for ex. move to another activity do here
}
my getview()
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos=position;
System.out.println(position);
View v = convertView;
final ViewHolder holder;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.feed_row, null);
holder = new ViewHolder();
holder.like=(ImageButton) v.findViewById(R.id.like);
holder.share=(ImageButton) v.findViewById(R.id.share);
holder.report=(ImageButton) v.findViewById(R.id.report);
holder.headline_text = (TextView) v.findViewById(R.id.lar);
holder.topic_text = (TextView) v.findViewById(R.id.mt);
holder.count_likes = (TextView) v.findViewById(R.id.count_likes);
holder.count_shares = (TextView) v.findViewById(R.id.count_shares);
holder.image = (ImageView) v.findViewById(R.id.img1);
holder.image2 = (ImageView) v.findViewById(R.id.img2);
v.setTag(holder);
}
else
holder=(ViewHolder)v.getTag();
mSharedPreferences= v.getContext().getSharedPreferences("mypref", 0);
holder.headline_text.setText(" "+entries.get(pos).get(TAG_FFN)+" had a chance with "+entries.get(pos).get(TAG_IFN)+"! ");
holder.topic_text.setText(entries.get(pos).get(TAG_TOPIC));
holder.image.setTag(entries.get(pos).get(TAG_FTID));
holder.image2.setTag(entries.get(pos).get(TAG_ITID));
holder.count_likes.setText(entries.get(pos).get(TAG_LIKERS)+" likes");
holder.count_shares.setText(entries.get(pos).get(TAG_SHARERS)+" shares");
if(entries.get(pos).get(TAG_LIKED).equals("True"))
{
holder.like.setImageResource(R.drawable.like);
holder.like.setTag("True");
}
else
{
holder.like.setTag("False");
}
if(entries.get(pos).get(TAG_SHARED).equals("True"))
{
holder.share.setImageResource(R.drawable.share);
holder.share.setEnabled(false);
}
//=======================setting image of user==========================================//
// Loader image - will be shown before loading image
// whenever you want to load an image from url
// call DisplayImage function
// url - image url to load
// loader - loader image, will be displayed before getting image
// image - ImageView
imgLoader.DisplayImage((image_url.getimage(Long.parseLong(entries.get(pos).get(TAG_FTID))))[0],loader, holder.image);
imgLoader.DisplayImage((image_url.getimage(Long.parseLong(entries.get(pos).get(TAG_ITID))))[0],loader, holder.image2);
//====================================================================================//
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if((holder.image.getTag()).equals(mSharedPreferences.getString("USERID", null)))
{
Toast.makeText(v.getContext(), "Your profile", Toast.LENGTH_LONG).show();
}
else
{
Intent i=new Intent(v.getContext(),OtherProfilePage.class);
i.putExtra("Image_id",entries.get(pos).get(TAG_FTID));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
(v.getContext()).startActivity(i);
}
}
});
holder.image2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.image2.getTag().equals(mSharedPreferences.getString("USERID", null)))
{
Toast.makeText(v.getContext(), "Your profile", Toast.LENGTH_LONG).show();
}
else
{
Intent i=new Intent(v.getContext(),OtherProfilePage.class);
i.putExtra("Image_id", entries.get(pos).get(TAG_ITID));
(v.getContext()).startActivity(i);
}
}
});
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.like.getTag()=="True")
{
holder.like.setImageResource(R.drawable.like_pressed);
holder.like.setTag("False");
new sendlikes().execute("link");
}
else
{ holder.like.setImageResource(R.drawable.like);
holder.like.setTag("True");
new sendlikes().execute("link");
}
}
});
holder.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.share.setImageResource(R.drawable.share);
holder.share.setEnabled(false);
new sendlikes().execute("http://gangster.cloudapp.net/share/",entries.get(pos).get(TAG_CID),mSharedPreferences.getString("person_id",null));
}
});
return v;
}
imageloader is a class that i used for caching the images.
Try to put this line linlaHeaderProgress.setVisibility(View.GONE); after if and else blocks. Hope this will work for you.
I think the issue could lie in a couple places:
1) You're doing a good deal of pre-processing of data in you Adapter's constructor.
Remember that everything in onPostExecute() runs on the application UI thread, so if your constructor for your adapter does some heavy processing, it could lock up the UI thread.
Creating an adapter can be done in doInBackground and then passed as the result to onPostExecute so that the setAdapter call is the only call there.
2) Your getView() method in your adapter isn't very efficient.
When you call setAdapter, the AdapterView must call getView for every cell that's going to be shown on screen. If there are a lot of cells and you're doing a lot of expensive operations like inflating views or findingViewsById, you could be locking up the UI thread for that initial load.
How's your scrolling performance? If it's lacking, the getView() would be the first place to start and I would watch Romain Guy's great talk on ListView performance for recommendations on how to create a good, efficient adapter.
http://www.youtube.com/watch?v=wDBM6wVEO70
add a listener when onpostexecute is completed in listener onsuccess method in your activity set adpater and then dismiss progress it will work
in you activity add this interface
public interface asyncListener{
public void onSucess(Object object);
public void onFailure(Exception exception);
}
and add a varible
asyncListener as= new asyncListener() {
#Override
public void onSucess(Object object) {
// TODO Auto-generated method stub
}
#Override
public void onFailure(Exception exception) {
// TODO Auto-generated method stub
}
};
send this varible(listenr) in construtor in your asynctask contruct asign this to yourlistener in onpostexecute write yourlistener.onSucess(result);

Android gallery and async loading

I'm trying to load images with an async taks from internet. The problem is that the image will not update. Code:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i ;
i = new ImageView(this.mContext);
AsycTask task = new AsycTask();
task.url = new URL(mImageIds.get(position));
task.iv = i;
task.execute(i);
return i;
}
public class AsycTask extends AsyncTask<ImageView, Void, Bitmap>{
public Bitmap bm2;
public ImageView iv;
public URL url;
#Override
protected Bitmap doInBackground(ImageView... arg0) {
iv = arg0[0];
try {
bm2 = BitmapFactory.decodeStream((InputStream)url.getContent());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bm2;
}
#Override
protected void onPostExecute(Bitmap result) {
// iv.setImageResource(R.drawable.sw10)
iv.setVisibility(View.VISIBLE);
iv.setBackgroundResource(R.drawable.search);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageBitmap(result);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Why isn't the Image updating after I set the Bitmap?
I'm using an async task to update my Image, is this possible?
Try to use UnivsersalImageLoader lib which will simplify your development.
Your code for image loading will be next:
ImageLoader.getInstance().displayImage(imageUrl, imageView); // Default options will be used
UniversalImageLoader

strange error on my android set frame application

i create an application that set a frame to a image bitmap... but when the process give a result, i don't know, why the result bitmap are also saved to my original bitmap variabel, this is my code :
main code :
#Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.frame);
tampilFrame = (ImageView)findViewById(R.id.ivframe);
oribmp = temporary.getBitmap();
temp = oribmp;
tampilFrame.setImageBitmap(temp);
frame00 = (ImageView)findViewById(R.id.frs00);
frame00.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr00));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame01 = (ImageView)findViewById(R.id.frs01);
frame01.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr01));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame02 = (ImageView)findViewById(R.id.frs02);
frame02.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr02));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame03 = (ImageView)findViewById(R.id.frs03);
frame03.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr03));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
}
}
the variabel frame00, frame01, frame02 are ImageView that I set as a Button. When the user click the frame image, it will load an image from drawable and stored in a variabel named "frame" and also call a asyncTask named "backtask".
this is the "backtask" code
public class backtask extends AsyncTask<Void, Void, Void> {
ProgressDialog prog;
#Override
protected void onPreExecute(){
super.onPreExecute();
prog = ProgressDialog.show(FrameActivity.this, "", "Progress...");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
temp = setFrame(oribmp);
Log.i("temp", "widht : "+String.valueOf(temp.getWidth())+" Height : "+String.valueOf(temp.getHeight()));
return null;
}
#Override
protected void onPostExecute(Void res){
super.onPostExecute(res);
tampilFrame.setImageBitmap(temp);
prog.dismiss();
Log.i("setFrame", "Complete");
}
}
this backtask code i used to make a loading progress when the application runs the "setFrame()" code. and this is my "setFrame" code :
public Bitmap setFrame(Bitmap bit){
for (int i=0;i<frame.getWidth();i++){
for(int j=0;j<frame.getHeight();j++){
if (Color.alpha(frame.getPixel(i, j))!=0){
bit.setPixel(i, j, frame.getPixel(i, j));
}
}
}
frame.recycle();
return bit;
}
the oribmp is a variabel that containt original bitmap get from class temporary.getBitmap()
when the "temp = setFrame(oribmp);" finish, the ori bmp has also changes same as the temp.
when i checked to class temporary, the bitmap variabel that contain original bitmap on the temporary class also changes to the result of the setFrame...
this is the code pf temporary class
public class temporary {
private static Bitmap Mbmp;
public static Bitmap getBitmap () {
return Mbmp;
}
public static void setBitmap(Bitmap oribimp) {
// TODO Auto-generated method stub
Mbmp = oribimp;
Log.i("editor", "simpen bitmap");
}
}
temporary class is a class that i used to send the bitmap value to another activity in my application.. this is what the FrameActivity looks like on the run..
strart activity
this is the look of FrameActivity when its first start, the original bitmap is that gecko
set frame 1
this is the looks when set the first frame
set frame 2
this is the looks when set the second frame, cause the oribmp has the same value like the result of the first seFrame, on the second setFrame they looks like pile up
im sory if my question is too long, maybe anyone can give me solution :D

Categories

Resources