Ich habe einen Viewpager mit dem cn.trinea.android.view.autoscrollviewpager: Android-Auto-Scroll-View-Pager: 1.1.2-Bibliothek. Ich bekomme immer einen OOM-Fehler (siehe unten). Ich rufe einen ViewPager mit der obigen Bibliothek an, die sich in einem Fragment (siehe unten) befindet, das in einem View Pager sitzt, den ich mit einem TabManager verwende.Nicht genügend Speicher Fehler beim Laden von Bildern in einen View-Pager aus Datei
EDIT Ich habe folgende Aufgaben versucht:
- einen Schritt Hinzufügen der Bitmap zu recyceln (pro Anregung unten entfernt)
- zu einem großen Speichergröße in dem Mainfest geändert
- Hinzugefügt die vorgeschlagenen Bitmap-Bilder
- Hinzugefügt einen Cache
- Hinzugefügt Bitmap Worker Tasks per Android Vorschlag
- eine Async Drawble
Der Adapter ist unten am: Herausgegeben
public class HomeGalleryAdapter extends PagerAdapter implements OnPageChangeListener {
RequestQueue requestQueue;
int currentPage;
private LruCache<String, Bitmap> mMemoryCache;
static ArrayList<Integer> intentInfo = new ArrayList<>();
static ArrayList<String> quizImage = new ArrayList<>();
static ArrayList<String> downloads = new ArrayList<>();
CognitoCachingCredentialsProvider cp;
final Context c;
SharedPreferences sp;
String density;
public HomeGalleryAdapter(Context context){
c =context;
cp = AmazonS3.getProvider(c);
intentInfo.clear();
quizImage.clear();
sp = PreferenceManager.getDefaultSharedPreferences(c);
final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024);
final int cacheSize = maxMemory/8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount()/1024;
}
};
String cognitioID = sp.getString("Cognito","");
density = sp.getString("screenDensity", "");
String requestURL = "http://XXXXXX/top_5_sponsers.php?format=json&device_id="+cognitioID;
requestQueue = Volley.newRequestQueue(context);
JsonObjectRequest jor = new JsonObjectRequest(Request.Method.GET, requestURL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i("Home Gallery Adapter ", "Volley");
try{
JSONArray ja = response.getJSONArray("posts");
for(int i=0; i < ja.length(); i++){
JSONObject jsonObject = ja.getJSONObject(i);
JSONObject interior = jsonObject.getJSONObject("post");
intentInfo.add(i, interior.getInt("iquizontap_quiz_ID"));
quizImage.add(i, interior.getString("QUIZ_SPONSER_IMAGE"));
int a = c.getResources().getIdentifier(interior.getString
("QUIZ_SPONSER_IMAGE"),"drawable",c.getPackageName());
if(a == 0){
downloads.add(interior.getString
("QUIZ_SPONSER_IMAGE"));
Log.i("added a file", interior.getString("QUIZ_SPONSER_IMAGE"));
}
}
new imageDownloads().execute();
}catch(JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley","Error "+error);
}
}
);
requestQueue.add(jor);
notifyDataSetChanged();
}
@Override
public int getCount() {
notifyDataSetChanged();
return quizImage.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == (object);
}
@Override
public Object instantiateItem(ViewGroup container, int position){
Log.i("Home Gallery Adapter", "instantiateItem");
final int innerposition = position;
final ImageButton imageButton = new ImageButton(c);
int imageHeight = imageButton.getHeight();
int imageWidth = imageButton.getWidth();
String bitmapFileName = c.getCacheDir() + File.separator + quizImage.get(position).trim() + ".png";
imageDownloadParams params = new imageDownloadParams(bitmapFileName, imageWidth, imageHeight);
if(cancelPotentialWork(bitmapFileName, imageButton)) {
final Bitmap bitmap = getBitmapFromMemCache(bitmapFileName);
if(bitmap != null) {
BitmapWorkerTask task = new BitmapWorkerTask(imageButton);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(c.getResources(), BitmapFactory.decodeResource(c.getResources(), R.drawable.quizontap_default), task);
imageButton.setBackground(asyncDrawable);
task.execute(params);
}
}
Log.i("Home Gallery Adapter", "Insitate Item after set Image");
(container).addView(imageButton, 0);
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent quizIntent = new Intent(c,QuestionActivity.class);
quizIntent.putExtra("company", getItem(innerposition));
quizIntent.putExtra("tab",1);
c.startActivity(quizIntent);
Log.i("intent from onClick", quizIntent.getIntExtra("company" , 1)+"");
}
});
return imageButton;
}
public Integer getItem(int index){
return intentInfo.get(index);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object){
((ViewPager) container).removeView((ImageButton) object);
final int innerposition = position;
final ImageButton imageButton = new ImageButton(c);
Drawable drawable = imageButton.getDrawable();
if (drawable instanceof BitmapDrawable){
BitmapDrawable bd = (BitmapDrawable) drawable;
Bitmap bitmap = bd.getBitmap();
bitmap.recycle();
}
}
@Override
public void onPageSelected(int newPageIndex) {
currentPage = newPageIndex;
}
@Override
public void onPageScrollStateChanged(int newPageIndex) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public float getPageWidth(int position){
return 0.93f;
}
public class imageDownloads extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
Log.i("Home Gallery", "In home Gallery Image Download");
for(int i = 0 ; i<downloads.size(); i++){
Log.i("file name to dl",downloads.get(i));
String fileName = c.getCacheDir()+ File.separator+downloads.get(i).trim()+".png";
File d = new File(fileName);
if(!d.exists() || d.length() == 0) {
AmazonS3.createFile(downloads.get(i), c);
}
TransferUtility transferUtility = new TransferUtility(qotSingleton.getInstance(c).getAmazonS3Client(), c);
TransferObserver observer = transferUtility.download("quizontapimages/quizimages", downloads.get(i).trim()+ density+ ".png", d);
observer.setTransferListener(new TransferListener() {
@Override
public void onStateChanged(int fileName, TransferState transferState) {
}
@Override
public void onProgressChanged(int fileName, long l, long l1) {
int percentage = (int) (l/l1);
}
@Override
public void onError(int fileName, Exception e) {
Log.i("home gallery", e +"");
}
});
}return "test";
}
protected void onPreExecute(String test) {
}
// onPostExecute displays the results of the AsyncTask.
protected void onPostExecute(String test) {
notifyDataSetChanged();
}
}
class BitmapWorkerTask extends AsyncTask<imageDownloadParams, Void, Bitmap>{
private final WeakReference<ImageButton> imageButtonWeakReference;
private String filename = "";
private int height;
private int width;
public BitmapWorkerTask(ImageButton imageButton){
imageButtonWeakReference = new WeakReference<ImageButton>(imageButton);
}
@Override
protected Bitmap doInBackground(imageDownloadParams ... params){
filename = params[0].fileName;
height = params[0].height;
width = params[0].width;
final Bitmap bitmap =decodeSampledBitmap(filename, width, height);
addBitmapToMemoryCache(params[0].fileName, bitmap);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap){
if (imageButtonWeakReference != null && bitmap !=null){
final ImageButton imageButton = imageButtonWeakReference.get();
final BitmapWorkerTask bitmapWorkerTask = getBitmapWOrkerTask(imageButton);
if(this== bitmapWorkerTask && imageButton != null){
imageButton.setImageBitmap(bitmap);
}
}
}
}
public static Bitmap decodeSampledBitmap(String f, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(f, options);
// Calculate inSampleSize
options.inSampleSize = CommonUtilities.calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(f, options);
}
public static class imageDownloadParams {
String fileName;
int width;
int height;
imageDownloadParams(String fileName, int width, int height){
this.fileName = fileName;
this.width = width;
this.height = height;
}
}
static class AsyncDrawable extends BitmapDrawable{
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskWeakReference;
public AsyncDrawable(Resources res , Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask){
super(res, bitmap);
bitmapWorkerTaskWeakReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitMapWorkerTask(){
return bitmapWorkerTaskWeakReference.get();
}
}
public static boolean cancelPotentialWork(String filename, ImageButton imageButton){
final BitmapWorkerTask bitmapWorkerTask = getBitmapWOrkerTask(imageButton);
if (bitmapWorkerTask != null){
final String bitmapData = bitmapWorkerTask.filename;
if(bitmapData == "" || bitmapData != filename){
bitmapWorkerTask.cancel(true);
} else {
return false;
}
}
return true;
}
private static BitmapWorkerTask getBitmapWOrkerTask(ImageButton imageButton){
if(imageButton != null){
final Drawable drawable = imageButton.getDrawable();
if(drawable instanceof AsyncDrawable){
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitMapWorkerTask();
}
}
return null;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
}
ich es von hier bin Aufruf:
public class MainFragment extends Fragment {
ImageButton playquiz;
ImageButton watchvideo;
AutoScrollViewPager galleryPager;
static ArrayList <String> videos= new ArrayList<>();
static ArrayList<Integer> quizNo = new ArrayList<>();
boolean running;
HomeGalleryAdapter adapter;
View rootView;
RequestQueue requestQueue;
String cognitioID;
Context context;
Integer downloadFlag;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.fragment_mainfragment, container, false);
downloadFlag = 0;
SharedPreferences accountInfo = PreferenceManager.getDefaultSharedPreferences(getActivity());
cognitioID = accountInfo.getString("Cognito", "");
context = getActivity();
Log.i("context in MF", context + "");
running = true;
galleryPager = (AutoScrollViewPager) rootView.findViewById (R.id.homegallery);
playquiz = (ImageButton) rootView.findViewById(R.id.playquiz);
watchvideo = (ImageButton) rootView.findViewById(R.id.watchvideo);
if(quizNo.isEmpty()) {
QuizLoad();
}
adapter = new HomeGalleryAdapter(getActivity());
adapter.notifyDataSetChanged();
galleryPager.setAdapter(adapter);
galleryPager.setClipToPadding(false);
galleryPager.setPageMargin(10);
galleryPager.setInterval(4000);
galleryPager.startAutoScroll(4000);
playquiz.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent quizoutIntent = new Intent(getActivity(), QuestionActivity.class);
quizoutIntent.putExtra("company", getCompanyName(galleryPager.getCurrentItem()));
quizoutIntent.putExtra("tab", 0);
startActivity(quizoutIntent);
}
});
watchvideo.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(videos.get(galleryPager.getCurrentItem()))));
}
});
galleryPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (videos.get(position).isEmpty()){
watchvideo.setVisibility(View.INVISIBLE);
} else
watchvideo.setVisibility(View.VISIBLE);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
return rootView;
}
public Integer getCompanyName(int index){
return quizNo.get(index);
}
public MainFragment() {
// TODO Auto-generated constructor stub
}
@Override
public void onPause(){
super.onPause();
running = false;
galleryPager.stopAutoScroll();
}
@Override
public void onStop(){
super.onStop();
running = false;
galleryPager.stopAutoScroll();
}
@Override
public void onResume(){
super.onResume();
running = true;
if(quizNo.isEmpty()) {
QuizLoad();
}
adapter.notifyDataSetChanged();
galleryPager.startAutoScroll(4000);
}
public void QuizLoad(){
Log.i("MainFragment", "quizNo is Empty");
String requestURL = "XXX.php?format=json&device_id="+cognitioID;
requestQueue = Volley.newRequestQueue(context);
JsonObjectRequest jor = new JsonObjectRequest(Request.Method.GET, requestURL, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try{
JSONArray ja = response.getJSONArray("posts");
for(int i=0; i < ja.length(); i++){
JSONObject jsonObject = ja.getJSONObject(i);
JSONObject interior = jsonObject.getJSONObject("post");
quizNo.add(i, interior.getInt("iquizontap_quiz_ID"));
videos.add(i, interior.getString("VIDEO_URL"));
}
}catch(JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley","Error "+error);
}
}
);
requestQueue.add(jor);
}
}
Nichts hat sich geändert, aber vielleicht die Größe der Bilder (die Bilder sind insgesamt kleiner geworden). Ich lade fünf Bilder in der vorherigen Aktivität, bevor dieses Fragment geladen wird, in das Cache-Verzeichnis und überprüfe, ob sie da sind und wenn sie nicht heruntergeladen werden.
Ich habe versucht, die Heap-Größe zu erhöhen, die Bilder Recycling (destroyItem im Adapter sehen Stattdessen, wenn ich versuche, den Adapter ich die folgende Fehlermeldung zu initialisieren. ADDED
D/Error: ERR: stack=java.lang.StackOverflowError: stack size 8MB at android.support.v4.view.ViewPager.b(SourceFile:956)
....
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 13408152)
03-28 23:53:34.144 745-745/com.brillada.quizontap E/AndroidRuntime: Error reporting crash
android.os.TransactionTooLargeException: data parcel size 13408152 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:503)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4425)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:90)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
nicht viel Sie tun können, aber kleinere Bitmaps verwenden. Außerdem sollten Sie Ihre Bitmap nicht sofort wiederverwenden, nachdem Sie sie in einem ImageView platziert haben. Es muss vollständig zugewiesen werden, damit ImageView korrekt zeichnen kann. –
Versuchen Sie darüber hinaus, 'recycle()' nicht zu verwenden, sondern die 'Bitmap'-Objekte zum Laden in neue Bitmaps zu verwenden (siehe 'inBitmap' in' BitmapFactory.Options'). Eine Zuweisung von 4 MB ist zu den besten Zeiten schwierig. Sobald Sie einen haben, veröffentlichen Sie ihn nur, wenn Sie sich sicher sind, dass Sie ihn nicht wieder benötigen werden.Konstante Zuordnungen und Releases werden Ihren Heap insbesondere auf Android 4.4 und niedriger fragmentieren. – CommonsWare