ورود

View Full Version : مشکل با تاخیر در لود شدن تصاویر لیست ویو که از اینترنت میگیره



dalmif
دوشنبه 21 اردیبهشت 1394, 17:54 عصر
سلام دوستان.
من نه مشکل دارم که ارور رو بنویسم نه چیز دیگه ای فقط یکی بیاد بگه چرا سرعت لود تصاویر به 2 ثانیه میکشه. (:گریه::گریه:
این کد منه





import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;


import org.json.JSONObject;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;


import android.widget.TextView;
import android.widget.Toast;


public class MyClass extends Activity{

GridView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_kala);
if(isNetworkConnected()){ // check internet connection
// your codes

String strUrl = "http://192.168.231.1/json/json.html";

// Creating a new non-ui thread task to download json data
DownloadTask downloadTask = new DownloadTask();


// Starting the download process
downloadTask.execute(strUrl);

// Getting a reference to ListView of activity_main
mListView = (GridView) findViewById(R.id.gridView1);
}
else {
Toast.makeText(getApplicationContext(), "اتصال گوشی خود را چک کنید", Toast.LENGTH_LONG).show();
this.finish();
}
}

/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
try{
URL url = new URL(strUrl);

// Creating an http connection to communicate with url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();


// Connecting to url
urlConnection.connect();


// Reading data from url
iStream = urlConnection.getInputStream();

BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

StringBuffer sb = new StringBuffer();

String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}

data = sb.toString();

br.close();


}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
}


return data;
}




/** AsyncTask to download json data */
private class DownloadTask extends AsyncTask<String, Integer, String>{
String data = null;
@Override
protected String doInBackground(String... url) {
try{
data = downloadUrl(url[0]);

}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}


@Override
protected void onPostExecute(String result) {

// The parsing of the xml data is done in a non-ui thread
ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();

// Start parsing xml data
listViewLoaderTask.execute(result);

}
}

/** AsyncTask to parse json data and load ListView */
private class ListViewLoaderTask extends AsyncTask<String, Void, AdapterView>{


JSONObject jObject;
// Doing the parsing of xml data in a non-ui thread
@Override
protected AdapterView doInBackground(String... strJson) {
try{
jObject = new JSONObject(strJson[0]);
CountryJSONParser countryJsonParser = new CountryJSONParser();
countryJsonParser.parse(jObject);
}catch(Exception e){
Log.d("JSON Exception1",e.toString());
}

// Instantiating json parser class
CountryJSONParser countryJsonParser = new CountryJSONParser();

// A list object to store the parsed countries list
List<HashMap<String, Object>> countries = null;

try{
// Getting the parsed data as a List construct
countries = countryJsonParser.parse(jObject);
}catch(Exception e){
Log.d("Exception",e.toString());
}


// Keys used in Hashmap
String[] from = { "country","flag","details"};


// Ids of views in listview_layout
int[] to = { R.id.textView1,R.id.imageView1,R.id.textView2};


// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
AdapterView adapter = new AdapterView(getBaseContext(), countries, R.layout.custom_adapter, from, to);
// MyAdapter adapter = new MyAdapter(getBaseContext(), android.R.layout.simple_list_item_1, R.id.textView1, from);
return adapter;
}

/** Invoked by the Android on "doInBackground" is executed */
@Override
protected void onPostExecute(AdapterView adapter) {

// Setting adapter for the listview
mListView.setAdapter(adapter);

for(int i=0;i<adapter.getCount();i++){
Object hm1 = adapter.getItem(i);

HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i);

String imgUrl = (String) hm.get("flag_path");
ImageLoaderTask imageLoaderTask = new ImageLoaderTask();

HashMap<String, Object> hmDownload = new HashMap<String, Object>();
hm.put("flag_path",imgUrl);
hm.put("position", i);

// Starting ImageLoaderTask to download and populate image in the listview
imageLoaderTask.execute(hm);
}
}
}

/** AsyncTask to download and load an image in ListView */
private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>{


@Override
protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) {

InputStream iStream=null;

String imgUrl = (String) hm[0].get("flag_path");
int position = (Integer) hm[0].get("position");

URL url;
try {

url = new URL(imgUrl);

// Creating an http connection to communicate with url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

// Connecting to url
urlConnection.connect();


// Reading data from url
iStream = urlConnection.getInputStream();

// Getting Caching directory
File cacheDirectory = getBaseContext().getCacheDir();

// Temporary file to store the downloaded image
File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+position+".png");

// The FileOutputStream to the temporary file
FileOutputStream fOutStream = new FileOutputStream(tmpFile);

// Creating a bitmap from the downloaded inputstream
Bitmap b = BitmapFactory.decodeStream(iStream);

// Writing the bitmap to the temporary file as png file
b.compress(Bitmap.CompressFormat.PNG,100, fOutStream);

// Flush the FileOutputStream
fOutStream.flush();

//Close the FileOutputStream
fOutStream.close();
// Create a hashmap object to store image path and its position in the listview
HashMap<String, Object> hmBitmap = new HashMap<String, Object>();

// Storing the path to the temporary image file
hmBitmap.put("flag",tmpFile.getPath());

// Storing the position of the image in the listview
hmBitmap.put("position",position);

// Returning the HashMap object containing the image path and position
return hmBitmap;



}catch (Exception e) {
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(HashMap<String, Object> result) {
// Getting the path to the downloaded image
AdapterView adapter = (AdapterView) mListView.getAdapter();
String path = (String) result.get("flag");

// Getting the position of the downloaded image
int position = (Integer) result.get("position");

// Getting adapter of the listview


// Getting the hashmap object at the specified position of the listview
HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position);

// Overwriting the existing path in the adapter
hm.put("flag",path);

// Noticing listview about the dataset changes
adapter.notifyDataSetChanged();

}
}


private boolean isNetworkConnected() { // check internet connection
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}

public class MyAdapter extends ArrayAdapter<String> {


public MyAdapter(Context context, int resource, int textViewResourceId,
String[] from) {
super(context, resource, textViewResourceId, from);
// TODO Auto-generated constructor stub
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_IN FLATER_SERVICE);
final View row = inflater.inflate(R.layout.custom_adapter, parent, false);
Typeface face=Typeface.createFromAsset(getAssets(), "Byekan.ttf");
TextView tv = (TextView) row.findViewById(R.id.textView1);
tv.setText("eerrer");
return row;
}



}
}

JYasProgramer
سه شنبه 22 اردیبهشت 1394, 08:39 صبح
چند دلیل مختلف:
سرعت نت پایینه
سرعت امولاتورپایینه
دانلود دیتا نزدیک دو ثانیه طول میکشه
و دلایل مختلف چیز غیر عادی نیست به قول خودت مشکلی نیست

djtrex
چهارشنبه 23 اردیبهشت 1394, 11:36 صبح
شما خیلی راحت میتونید به جای نوشتن چندین خط کد با Picasso با یه خط هم عکستونو دانلود کنید هم نشون بدید هم توی مموری کش میشه.



Picasso.with(context).load(url).into(imageView);



اگه میخواید عکس ریسایز بشه و یا center Crop بشه:


Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView);


اگه میخواید قبل از لود شودن یه عکس رو نشون بده (مثلا لودینگ یا عکس پیشفرض) و موقع خطا یه عکس دیگه:


Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView);


اطلاعات بیشتر و طریقه نصب:

http://square.github.io/picasso/

-------------------------
تاخیر شما یه دلیلش اینه که عکس رو دانلود کنید بعد میارید روی رم بعد دوباره توی یه فایل موقت روی دیسک ذخیره میکنید بعد آدرس اونو میدید به آداپتور دوباره اونو از روی دیسک میخونید میارید رو رم.

مشکل دیگه اینه که فرآیند دانلود تصاویر رو به صورت دستی خودتون انجام میدید و همه تصاویر توی یه asyncTask به ازای هر عکس دانلود میشه حالا اکه تعداد عکس هاتون زیاد باشه همه اینا با هم دانلود میشه در نتیجه پهنای باند کمتری برای هر دانلود هر عکس میمونه.
البته async task یه ماکسیمم اندازه thread pool داره ولی خوب تعدادش خیلی زیاده! (اطلاعات بیشتر: http://stackoverflow.com/questions/26075422/how-many-async-task-can-be-used-in-a-class-android?lq=1)

اینجور مواقع Picasso یا Volley Network Image view و ... این فرآیندهارو بهتر مدیریت میکنند. بهتره به جای اینکه از اول همه چیز رو خودتون کد بزنید از این ها استفاده کنید.

اطلاعات بیشتر برای volley :
https://developer.android.com/training/volley/request.html

dalmif
چهارشنبه 23 اردیبهشت 1394, 13:00 عصر
آقا یه دنیا ممنون.
حیف بیش از زدن اون دکمه تشکر کار دیگه ای نمیتونم بکنم.:قلب::قلب:

hamedg1366
چهارشنبه 23 اردیبهشت 1394, 17:17 عصر
شما خیلی راحت میتونید به جای نوشتن چندین خط کد با Picasso با یه خط هم عکستونو دانلود کنید هم نشون بدید هم توی مموری کش میشه.



Picasso.with(context).load(url).into(imageView);



اگه میخواید عکس ریسایز بشه و یا center Crop بشه:


Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView);


اگه میخواید قبل از لود شودن یه عکس رو نشون بده (مثلا لودینگ یا عکس پیشفرض) و موقع خطا یه عکس دیگه:


Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView);


اطلاعات بیشتر و طریقه نصب:

http://square.github.io/picasso/

-------------------------
تاخیر شما یه دلیلش اینه که عکس رو دانلود کنید بعد میارید روی رم بعد دوباره توی یه فایل موقت روی دیسک ذخیره میکنید بعد آدرس اونو میدید به آداپتور دوباره اونو از روی دیسک میخونید میارید رو رم.

مشکل دیگه اینه که فرآیند دانلود تصاویر رو به صورت دستی خودتون انجام میدید و همه تصاویر توی یه asyncTask به ازای هر عکس دانلود میشه حالا اکه تعداد عکس هاتون زیاد باشه همه اینا با هم دانلود میشه در نتیجه پهنای باند کمتری برای هر دانلود هر عکس میمونه.
البته async task یه ماکسیمم اندازه thread pool داره ولی خوب تعدادش خیلی زیاده! (اطلاعات بیشتر: http://stackoverflow.com/questions/26075422/how-many-async-task-can-be-used-in-a-class-android?lq=1)

اینجور مواقع Picasso یا Gson Network Image view و ... این فرآیندهارو بهتر مدیریت میکنند. بهتره به جای اینکه از اول همه چیز رو خودتون کد بزنید از این ها استفاده کنید.

اطلاعات بیشتر برای gson :
https://developer.android.com/training/volley/request.html





سلام دوست عزیز شما از کتابخونه Universal image Downloader هم استفاده کردین ؟

میشه یه توضیحی در این باره هم بدین ، (که چطور ازش استفاده کنیم)

با تشکر

djtrex
چهارشنبه 23 اردیبهشت 1394, 17:45 عصر
سلام دوست عزیز شما از کتابخونه Universal image Downloader هم استفاده کردین ؟

میشه یه توضیحی در این باره هم بدین ، (که چطور ازش استفاده کنیم)

با تشکر

من استفاده نکردم ولی خوب الان دیدم امکانات خوبی داشت مثل کش روی حافظه و دیسک + مدت زمان کش. یا thumbnail برای ویدیو ها و یا کنترل و شخصی سازی های بیشتر نسبت به بقیه.

ولی خوب اگه استفاده ساده تری دارید میتونید از همین picasso و ... استفاده کنید. ولی خوب اگه نیاز دارید تا حرفه ای تر باشه میتونید از همین universal image downloader استفاده کنید.

برای image loading پکیج های خوبی اومده یه سریشو اینجا میتونید ببینید:
https://android-arsenal.com/tag/46
یه سری هم اینجاست:



DroidParts : ImageFetcher (http://droidparts.org/image_fetcher.html)
Volley : ImageLoader (https://android.googlesource.com/platform/frameworks/volley/)
AndroidQuery : ImageLoading (https://code.google.com/p/android-query/wiki/ImageLoading)

==============
مستنداتش هست اینجا با یه سری مثال:
https://github.com/nostra13/Android-Universal-Image-Loader/wiki


استفاده ساده اش اینه:


DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options);

doctorapp
شنبه 11 اردیبهشت 1395, 18:16 عصر
من استفاده نکردم ولی خوب الان دیدم امکانات خوبی داشت مثل کش روی حافظه و دیسک + مدت زمان کش. یا thumbnail برای ویدیو ها و یا کنترل و شخصی سازی های بیشتر نسبت به بقیه.

ولی خوب اگه استفاده ساده تری دارید میتونید از همین picasso و ... استفاده کنید. ولی خوب اگه نیاز دارید تا حرفه ای تر باشه میتونید از همین universal image downloader استفاده کنید.

برای image loading پکیج های خوبی اومده یه سریشو اینجا میتونید ببینید:
https://android-arsenal.com/tag/46
یه سری هم اینجاست:



DroidParts : ImageFetcher (http://droidparts.org/image_fetcher.html)
Volley : ImageLoader (https://android.googlesource.com/platform/frameworks/volley/)
AndroidQuery : ImageLoading (https://code.google.com/p/android-query/wiki/ImageLoading)

==============
مستنداتش هست اینجا با یه سری مثال:
https://github.com/nostra13/Android-Universal-Image-Loader/wiki


استفاده ساده اش اینه:


DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options);




دوست گلم درود
میشه منم راهنمایی کنیدرود
من با یه کلاس که اونم از اینترنت گرفتم عکسهارو دانلود و روی sd کش میکنم بعدم داخل لیستویو نشون میدم
اما یه مشکل دارم
مثلا وارد اکتیویتی که میشم و لیست عکسها رو از نت میگیرم و داخل لیست ویو نشون میدم یه چیزی نزدیک 15 مگ رم اشغال میشه!اینش مهم نیست،زمانی که اکتیویتی رو میبندم و فرم اصلی میرم رم آزاد نمیشه و وقتی برمیگردم به اکتیویتی دوم و دوباره همون عکسا رو نشون میدم باز 15 مگ به رم اضافه میشه!!چرا!!میشه30 مگ(با یه تابع میزان رم اشغالی برنامه رو هرلحظه نشون میده داخل log)
با یه تست فهمیدم وقتی عکس و داخل imageview ست میکنم این اتفاق میوفته!!
اگه داخل بیت مپ باشه مشکل نداره اما تا روی ایمیج ویو ست میشه رم میگیره.
آیا این picasoo یا بقیه مشکل من و حل میکنه!!
بعدم مگه آدابتر فقط سطرهایی که درحال نمایشن و نگه نمیدار؟پس چرا اکتیویتی و میبندم آزاد نمیشه
ممنون میشم کمکم کنید
اگه میشه کامل بگید چیکار کنم
عکسها روی سرور بعد باید روی sd ذخیره شه زمان دانلود عکس هم بجا عکس لودینگ باشه
مشکل رم هم حل شه و وقتی اکتیوی بسته شد رم آزاد بشه
سپاس

doctorapp
چهارشنبه 22 اردیبهشت 1395, 00:12 صبح
دوست گلم درود
میشه منم راهنمایی کنیدرود
من با یه کلاس که اونم از اینترنت گرفتم عکسهارو دانلود و روی sd کش میکنم بعدم داخل لیستویو نشون میدم
اما یه مشکل دارم
مثلا وارد اکتیویتی که میشم و لیست عکسها رو از نت میگیرم و داخل لیست ویو نشون میدم یه چیزی نزدیک 15 مگ رم اشغال میشه!اینش مهم نیست،زمانی که اکتیویتی رو میبندم و فرم اصلی میرم رم آزاد نمیشه و وقتی برمیگردم به اکتیویتی دوم و دوباره همون عکسا رو نشون میدم باز 15 مگ به رم اضافه میشه!!چرا!!میشه30 مگ(با یه تابع میزان رم اشغالی برنامه رو هرلحظه نشون میده داخل log)
با یه تست فهمیدم وقتی عکس و داخل imageview ست میکنم این اتفاق میوفته!!
اگه داخل بیت مپ باشه مشکل نداره اما تا روی ایمیج ویو ست میشه رم میگیره.
آیا این picasoo یا بقیه مشکل من و حل میکنه!!
بعدم مگه آدابتر فقط سطرهایی که درحال نمایشن و نگه نمیدار؟پس چرا اکتیویتی و میبندم آزاد نمیشه
ممنون میشم کمکم کنید
اگه میشه کامل بگید چیکار کنم
عکسها روی سرور بعد باید روی sd ذخیره شه زمان دانلود عکس هم بجا عکس لودینگ باشه
مشکل رم هم حل شه و وقتی اکتیوی بسته شد رم آزاد بشه
سپاس

کسی نبود راهنمایی کنه؟

NeoFighT
چهارشنبه 22 اردیبهشت 1395, 23:09 عصر
سلام دوستان ،
برای لود عکس فکر میکنم الان دیگه picasso بهترین گزینه نیست ، چون الان google یک لایبرری به اسم Glide داده که دقیقا همون کار رو انجام میده و با تقریبا پرفورمنس 2 برابر ،
این لینک (https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en)رو ببینید ، اومده Glide رو با Picasso مقایسه کرده ، پیشنهاد میکنم همش رو بخونید :چشمک: