我有一个使用cn.trinea.android.view.autoscrollviewpager的Viewpager:android-auto-scroll-view-pager:1.1.2库。我一直收到OOM错误(见底部)。我正在使用上面的库调用ViewPager,该库位于我正在使用TabManager的View Pager中的片段(见下文)。
编辑我已尝试过以下任务:
适配器位于以下位置:已修改
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);
}
}
我是从这里打电话的:
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);
}
}
没有任何改变,但可能是图像的大小(整体上的图像实际上已经缩小了)。在加载此片段之前,我将上一个活动中的五个图像加载到Cache目录中,然后检查它们是否在那里,如果没有下载它们。
我尝试增加堆大小,回收映像(请参阅适配器中的destroyItem。相反,当我尝试初始化适配器时,我收到以下错误: 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)
答案 0 :(得分:0)
以下链接提供了有关如何有效解码图像的一些提示。它解释了为什么,即使图像不是现在的标准太大(我们应该有Gbs的内存,而你有13 Mb的问题),你有系统架构所施加的限制。其中一篇文章告诉您如何对图像进行缩减采样:
http://developer.android.com/training/displaying-bitmaps/index.html
我同意Doug Stevenson的观点。我建议在将它们带入内存时使用下采样。</ p>
摘自文章:
告诉解码器对图像进行二次采样,将较小的版本加载到内存中,在BitmapFactory.Options对象中将inSampleSize设置为true。例如,使用inSampleSize为4解码的分辨率为2048x1536的图像会产生大约512x384的位图。将其加载到内存中对于完整图像使用0.75MB而不是12MB(假设ARGB_8888的位图配置)。这是一种根据目标宽度和高度计算样本大小值为2的幂的方法: