viewpager的每個視圖都有一個圖像視圖,並帶有從url獲取的位圖。將url中的圖像加載到viewpager中 - outofmemory
如果我加載小圖像 - 100 X 80像素 - 我永遠不會失去內存,即使我加載10000。 如果我加載更大的圖像800×60像素 - 28 - 30圖像後,我得到outofmemory。
我看到視圖尋呼機回收已經被刷過的視圖中的圖像。 (當我趕緊刷卡後,我看到被再次載入圖像。)
我想不通 - 爲什麼10000張的小圖片不死機的應用程序,但只有30更大的圖像做呢?
請看看下面的代碼:
<PRE>
public class MainActivity extends FragmentActivity implements OnClickListener {
final String appurl = "http://drafts.bestsiteeditor.com/cgi-bin/bookcalendar/promoters.pl";
final String imgurl = "http://drafts.bestsiteeditor.com/promoters/";
ArrayList<Event> events = new ArrayList<Event>();
ViewPager mPager;
GetServerData mt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(Calendar.HOUR_OF_DAY, 0);cal.set(Calendar.MINUTE, 0);cal.set (Calendar.SECOND, 0);cal.set(Calendar.MILLISECOND, 0);
int monday = (int) (cal.getTimeInMillis()/1000);
if (cal.get(Calendar.DAY_OF_WEEK) == 2) {} else {for (int d = 1; d <= 7; d++) {monday = monday - 86400;cal.setTimeInMillis((long) monday * 1000);if (cal.get(Calendar.DAY_OF_WEEK) == 2) {break;}}}
makeWeek(monday);
mPager = (ViewPager) findViewById(R.id.pager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return ActionBar.HandleMenu(this, item.getItemId());
}
@Override
public void onClick(View v) {
// if (v == show_calendar) {
// Intent openMenu;
// openMenu = new Intent(this, WeekCalendar.class);
// startActivity(openMenu);
// }
}
public class CustomPagerAdapter extends PagerAdapter {
ArrayList<Event> events;
LayoutInflater inflater;
Context c;
public CustomPagerAdapter(Context context, ArrayList<Event> events) {
this.inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.events = events;
this.c = context;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
@Override
public int getCount() {
return events.size();
}
@Override
public void destroyItem(View container, int position, Object object) {
// ((ViewPager) container).removeView((View)object);
System.out.println("DESTROY destroying view at position "
+ position);
View view = (View) object;
((ViewPager) container).removeView(view);
view = null;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView;
itemView = inflater.inflate(R.layout.first_frag, container, false);
Event e = events.get(position);
TextView topTextItem = (TextView) itemView.findViewById(R.id.tvFragFirst);
TextView bottomTextItem = (TextView) itemView.findViewById(R.id.tv2);
ImageView iv = (ImageView) itemView.findViewById(R.id.imageView1);
e.setImageView(iv);
//if (position == 0) {
ShowImage shim = new ShowImage(imgurl + "th" + e.getId()+ "1.jpg", iv,c);
shim.execute();
//}
Button btn = (Button) itemView.findViewById(R.id.button1);
final String showtoast = String.valueOf(events.size());
btn.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getBaseContext(),
"Event expired before:" + showtoast,
Toast.LENGTH_LONG).show();
}
});
topTextItem.setText(e.getDsc());
bottomTextItem.setText(String.valueOf(position) + e.getTitle());
((ViewPager) container).addView(itemView);
return itemView;
}
}
public class Event {
String id;
String title;
String description;
ImageView iv;
public Event(String id, String ttl, String dsc) {
this.id = id;
this.title = ttl;
this.description = dsc;
}
public void setImageView(ImageView niv) {
this.iv = niv;
}
public String getId() {
return id;
}
public String getTitle() {
return title;
}
public String getDsc() {
return description;
}
public ImageView getIV() {
return iv;
}
}
public class Pair {
public String isonline;
public ArrayList<Event> events;
}
private class GetServerData extends AsyncTask<Void, Void, Pair> {
Context context;
String targetUrl;
String imgUrl;
public GetServerData(Context context, String url, String imgurl) {
this.context = context;
this.targetUrl = url;
this.imgUrl = imgurl;
}
@Override
protected Pair doInBackground(Void... params) {
ArrayList<Event> eventsar = new ArrayList<Event>();
String isonline = "no";
Event newevent = null;
Document doc;
try {
doc = Jsoup.connect(targetUrl).get();
isonline = doc.select("div#isonline").text();
Elements promoters = doc.select("div.promoters");
Elements events = doc.select("div.events");
Elements eventsfull = doc.select("div.eventsfull");
if (eventsfull.size() > 0) {
for (Element event : eventsfull) {
String temp = event.text().toString();
String title = event.select("div.title").text();
String event_id = event.select("div.event_id").text();
String promoter_id = event.select("div.promoter_id")
.text();
String promoter_name = event.select("div.promoter_name").text();
String promoter_email = event.select("div.promoter_email").text();
String promoter_phone = event.select("div.promoter_phone").text();
String promoter_dsc = event.select("div.promoter_dsc").text();
Integer imgs = Integer.parseInt(event.select("div.event_images").text());
String[] eventSplit = temp.split("\\|");
newevent = new Event(event_id, title, promoter_dsc);
eventsar.add(newevent);
}
}
} catch (IOException e) {
e.printStackTrace();
}
Pair p = new Pair();
p.isonline = isonline;
p.events = eventsar;
return p;
}
@Override
// protected void onPostExecute(ArrayList<Integer> rows) {
protected void onPostExecute(Pair p) {
String isonline = p.isonline;
events = p.events;
if (isOnline()) {
if (isonline.equals("yes")) {
Calendar clt = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Long nowt = clt.getTimeInMillis();
CustomPagerAdapter customPagerAdapter = new CustomPagerAdapter(context, events);mPager.setAdapter(customPagerAdapter);
// mPager.setOffscreenPageLimit(4);
} else {
Toast.makeText(getApplicationContext(),
"No Internet Connection with this page.",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(),"No Internet Connection at all.", Toast.LENGTH_LONG).show();
}
}
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
public void makeWeek(Integer start_day) {
try {
Random rand = new Random();
int myRandom = rand.nextInt() % 3;
mt = new GetServerData(MainActivity.this, appurl+ "?action=getevents&weekmonday=" + start_day + "&rand="+ myRandom, imgurl);
mt.execute();
} catch (Exception e) {
}
}
private class ShowImage extends AsyncTask<Void, Void, Bitmap> {
ImageView imgV;
String imgsrc;
Bitmap d;
Context c;
public ShowImage(String src, final ImageView v,Context cntx) {
this.imgV = v;
this.imgsrc = src;
this.c=cntx;
}
@Override
protected Bitmap doInBackground(Void... params) {
//InputStream is = null;
//try {
// is = (InputStream) new URL(imgsrc).getContent();
//URL url = new URL(imgsrc);
//d = BitmapFactory.decodeStream(url.openConnection()
//.getInputStream());
//} catch (MalformedURLException e) {
//e.printStackTrace();
//} catch (IOException e) {
//e.printStackTrace();
//}
InputStream in = null;
try{
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(imgsrc));
in = response.getEntity().getContent();
} catch(Exception e){
e.printStackTrace();
}
try {
d = BitmapFactory.decodeStream(in);
} finally {
if (in != null) { try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
return d;
}
@Override
protected void onPostExecute(Bitmap dr) {
imgV.setImageBitmap(dr);
if (dr != null) {
dr=null;
}
}
}
}
畢加索的表現非常好 - 謝謝你,但是OOM仍然顯示,但是應用程序不會崩潰,奇怪的是 - OOM顯示的視圖編號與28完全相同 - 然後3個視圖開始再次顯示圖像,然後顯示幾個通常與圖像查看,然後再次3沒有圖像,這種方式永遠:)也許我應該減少這些圖像的確。 – BestSiteEditor
@BestSiteEditor我認爲畢加索的API提供了一種方法,您可以將所需結果圖像的寬度和高度傳遞給它,並且它應該適當調整位圖以匹配這些參數。 –
你是絕對正確的朱利奧,我目前正在探索畢加索提供的選擇,他們可以將它命名爲莫扎特 - 更好的功能,再次感謝。 – BestSiteEditor