glide和ViewPager的内存不足异常

时间:2017-07-10 06:36:29

标签: android android-recyclerview android-viewpager out-of-memory android-glide

我有一个图像库,用于显示再循环视图中的图像,使用滑动并通过单击Recyclerview中的每个图像,该图像在视图寻呼机中打开。一切都很好,一开始,recyclerview很好,在viewpager中打开的图像和在viewpager中滑动都很好。但当我按下关闭viewpager和goback到recyclerview突然分配的内存增加到约400 MB!     有8个图像约490 * 420像素和72 KB大小     MainGallery.xml                  

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recView_Gallery1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
       >
    </android.support.v7.widget.RecyclerView>

    <Button
        android:id="@+id/btn_retry_Gallery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="تلاش مجدد"
        android:textSize="16sp"
        android:visibility="gone"
        android:layout_gravity="center"
        android:gravity="center"/>
    </android.support.design.widget.CoordinatorLayout> 

GalleryEnter.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="@color/colorAccent">
     <ImageView
        android:id="@+id/iv_photoGallety"
        android:adjustViewBounds="true"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:layout_margin="2dp"
        android:layout_width="match_parent"
        android:background="@android:color/white"/>
     </LinearLayout>

ImageDetail.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/main_content"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@color/colorAccent"
      tools:context="com.parsroyan.restaurant.imageDetailActivity">
    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    </android.support.design.widget.CoordinatorLayout>

MainGalleryActivity.java

    public class GalleryMain_Activity extends AppCompatActivity {

      public static final int CONNECTION_TIMEOUT = 10000;
      public static final int READ_TIMEOUT = 15000;
      public static RecyclerView recListMenuTypes;
      public static ImageAdapter mta;
      ArrayList<ImageGallery> data = new ArrayList<>();
      Button btn_retry;
      TextView tv_message;
      ImageView imv_message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gallery_main_);
        btn_retry = (Button) findViewById(R.id.btn_retry_Gallery);

        recListMenuTypes = (RecyclerView) findViewById(R.id.recView_Gallery1) 
 ;
        recListMenuTypes.setHasFixedSize(true);
        GridLayoutManager mLayoutManager = new 
        GridLayoutManager(GalleryMain_Activity.this, 2);
        recListMenuTypes.setLayoutManager(mLayoutManager);
        //LinearLayoutManager llm = new 
        LinearLayoutManager(GalleryMain_Activity.this);
        //llm.setOrientation(LinearLayoutManager.VERTICAL);
        //recListMenuTypes.setLayoutManager(llm);
        recListMenuTypes.setItemAnimator(new DefaultItemAnimator());
        mta = new ImageAdapter(GalleryMain_Activity.this, data);
        recListMenuTypes.setAdapter(mta);

        Check_Connection_Retrive();
        btn_retry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Check_Connection_Retrive();
            }
        });
    }
    private void alertView1(String message,boolean success) {
        final TypedArray styledAttributes = 
    GalleryMain_Activity.this.getTheme().obtainStyledAttributes(new int[] { 
    android.R.attr.actionBarSize });
        int Y = (int) styledAttributes.getDimension(0, 0);
        styledAttributes.recycle();

        LayoutInflater inflater = getLayoutInflater();
        View toastLayout = inflater.inflate(R.layout.custom_toast, 
 (ViewGroup) 
    findViewById(R.id.custom_toast_layout));
        tv_message = (TextView) 
    toastLayout.findViewById(R.id.custom_toast_message);
        tv_message.setText(message);
        Toast toast = new Toast(getApplicationContext());
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP | Gravity.START | 
    Gravity.FILL_HORIZONTAL,0,Y);
        toast.setView(toastLayout);
        imv_message = (ImageView) 
    toastLayout.findViewById(R.id.custom_toast_image);
        if(!success){
            toastLayout.setBackgroundColor(Color.parseColor("#cc0000"));

    imv_message.setBackgroundResource(android.R.drawable.ic_dialog_alert);
        }
        else {

imv_message.setBackgroundResource(android.R.drawable.ic_dialog_info);
        }
        toastLayout.setAlpha(.8f);
        toast.show();
    }
    public void Check_Connection_Retrive()
    {
        if(InternetConnection.checkConnection(getApplicationContext(),this))
        {
            btn_retry.setVisibility(View.GONE);
            new FetchGallery().execute();
        }
        else
        {
            btn_retry.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    private class FetchGallery extends AsyncTask<String, String, String> {

        TransparentProgressDialog pdLoading = new 
 TransparentProgressDialog
(GalleryMain_Activity.this,R.drawable.progress_circle);
            HttpURLConnection conn;
            URL url = null;

        @Override
        protected void onPreExecute() {`enter code here`
            super.onPreExecute();

            //pdLoading.setMessage("\tLoading...");
            pdLoading.setCancelable(false);
            //pdLoading.setProgress(10);
            pdLoading.show();
        }

        @Override
        protected String doInBackground(String... params) {

            try {
                url = new URL("My_URL");

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

                return "1";
            }
            try {

                conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(READ_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("GET");

            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                return "2";
            }

            try {

                int response_code = conn.getResponseCode();

                // Check if successful connection made
                if (response_code == HttpURLConnection.HTTP_OK) {

                    // Read data sent from server
                    InputStream input = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                    StringBuilder result = new StringBuilder();
                    String line;

                    while ((line = reader.readLine()) != null) {
                        result.append(line);
                    }

                    // Pass data to onPostExecute method
                    return (result.toString());

                } else {
                    return "3";
                }

            } catch (IOException e) {
                return "4";
            } finally {
                conn.disconnect();
            }


        }

        @Override
        protected void onPostExecute(String result) {

            //this method will be running on UI thread

            pdLoading.dismiss();
            switch(result) {
                case "1":
                    break;
                case "2":
                    break;
                case "3":
                    break;
                case "4":
                    break;
                default:
                    try {
                        btn_retry.setVisibility(View.GONE);
                        JSONArray jArray = new JSONArray(result);

                        for (int i = 0; i < jArray.length(); i++) {
                            //JSONObject json_data = jArray.getJSONObject(i);
                            ImageGallery image = new ImageGallery();
                            //image.name = json_data.getString("name");
                            image.title = jArray.get(i).toString();
                            image.url = "MY_URL" + image.title;
                            data.add(image);
                        }

                        // Setup and Handover data to recyclerview
                        mta.notifyDataSetChanged();
                        recListMenuTypes.addOnItemTouchListener(new 
 RecyclerViewTouchListener(getApplicationContext(), recListMenuTypes, new 
 RecyclerViewClickListener() {
                            @Override
                            public void onClick(View view, int position) {

             Intent intent = new Intent(GalleryMain_Activity.this, 
             imageDetailActivity.class);
                   intent.putParcelableArrayListExtra("data", data);
                                intent.putExtra("pos", position);
                                startActivity(intent);
                            }

                            @Override
                            public void onLongClick(View view, int position){
                            }
                        }));

                    } catch (JSONException e) {
                        Toast.makeText(GalleryMain_Activity.this, 
                        e.toString(), Toast.LENGTH_LONG).show();
                    }
            }
        }
    }
}

ImageAdapter.java

public class ImageAdapter extends 
RecyclerView.Adapter<ImageAdapter.MenuViewHolder> {

    private List<ImageGallery> imageGalleryList;
    private Context context;
    protected int lastPosition = -1;

    public ImageAdapter(Context Context,List<ImageGallery> contactList)
    {
        this.imageGalleryList = contactList;
        this.context = Context;
    }

    @Override
    public int getItemCount() {
        return imageGalleryList.size();
    }

    @Override
    public void onBindViewHolder(ImageAdapter.MenuViewHolder menuViewHolder, 
int i) {
        final ImageGallery m = imageGalleryList.get(i);
        Glide.with(context).load("MyURL"+m.title)
                .thumbnail(.1f)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .override(200,200).placeholder(R.drawable.logoback)
                .into(menuViewHolder.vImage);

        setFadeAnimation(menuViewHolder,i);
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    public ImageAdapter.MenuViewHolder onCreateViewHolder(ViewGroup 
viewGroup, int i) {
        final View itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.activity_gallery_enter, viewGroup, false);
        return new ImageAdapter.MenuViewHolder(itemView);
    }
    @Override
    public void onViewDetachedFromWindow(ImageAdapter.MenuViewHolder holder) 
{
        ((ImageAdapter.MenuViewHolder)holder).itemView.clearAnimation();
    }
    public class MenuViewHolder extends RecyclerView.ViewHolder{

        protected ImageView vImage;

        public MenuViewHolder(View v) {
            super(v);
            vImage = (ImageView)  v.findViewById(R.id.iv_photoGallety);
        }
    }
    private void setFadeAnimation(ImageAdapter.MenuViewHolder view, int 
position) {
        if (position > lastPosition) {

            AlphaAnimation anim = new AlphaAnimation(0.0f, 2.0f);
            anim.setDuration(1000);
            view.itemView.startAnimation(anim);
            lastPosition = position;
        }
    }
}

ImageDetailActivity.java

public class imageDetailActivity extends AppCompatActivity {

    private SectionsPagerAdapter mSectionsPagerAdapter;

    public ArrayList<ImageGallery> data = new ArrayList<>();
    int pos;

    Toolbar aboveToolbar;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_detail);

        //aboveToolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.detail_toolbar);
        //setSupportActionBar(aboveToolbar);
        //getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        data = getIntent().getParcelableArrayListExtra("data");
        pos = getIntent().getIntExtra("pos", 0);

        setTitle(data.get(pos).getName());

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), data);
        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setPageTransformer(true, new DepthPageTransformer());

        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.setCurrentItem(pos);

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

                //noinspection ConstantConditions
                setTitle(data.get(position).getName());

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });


    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        public ArrayList<ImageGallery> data = new ArrayList<>();

        public SectionsPagerAdapter(FragmentManager fm, ArrayList<ImageGallery> data) {
            super(fm);
            this.data = data;
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            return PlaceholderFragment.newInstance(position, data.get(position).getName(), data.get(position).getUrl());
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return data.size();
        }

       // @Override
        //public CharSequence getPageTitle(int position) {
            //return data.get(position).getName();
       // }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        String name, url;
        ImageView ImageView;
        int pos;
        private static final String ARG_SECTION_NUMBER = "section_number";
        //private static final String ARG_IMG_TITLE = "image_title";
        private static final String ARG_IMG_URL = "image_url";

        @Override
        public void setArguments(Bundle args) {
            super.setArguments(args);
            this.pos = args.getInt(ARG_SECTION_NUMBER);
            //this.name = args.getString(ARG_IMG_TITLE);
            this.url = args.getString(ARG_IMG_URL);
        }

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber, String name, String url) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            //args.putString(ARG_IMG_TITLE, name);
            args.putString(ARG_IMG_URL, url);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public void onStart() {
            super.onStart();

        }

        @Override
        public void onDestroy() {
            super.onDestroy();
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_image_detail, container, false);

            this.ImageView = (ImageView) rootView.findViewById(R.id.detail_image);

            Glide.with(getActivity()).load(url).thumbnail(0.1f).crossFade()
                    .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                    .override(200,200).placeholder(R.drawable.tiara3)
                    .into(this.ImageView);

            return rootView;
        }

    }
}

错误日志:

 E/AndroidRuntime: FATAL EXCEPTION: main
                  java.lang.OutOfMemoryError
                      at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
                      at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:501)
                      at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:354)
                      at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
                      at android.content.res.Resources.loadDrawable(Resources.java:1970)
                      at android.content.res.Resources.getDrawable(Resources.java:660)
                      at com.bumptech.glide.request.GenericRequest.getPlaceholderDrawable(GenericRequest.java:416)
                      at com.bumptech.glide.request.GenericRequest.clear(GenericRequest.java:323)
                      at com.bumptech.glide.request.ThumbnailRequestCoordinator.clear(ThumbnailRequestCoordinator.java:106)
                      at com.bumptech.glide.manager.RequestTracker.clearRequests(RequestTracker.java:94)
                      at com.bumptech.glide.RequestManager.onDestroy(RequestManager.java:221)
                      at com.bumptech.glide.manager.ActivityFragmentLifecycle.onDestroy(ActivityFragmentLifecycle.java:64)
                      at com.bumptech.glide.manager.SupportRequestManagerFragment.onDestroy(SupportRequestManagerFragment.java:147)
                      at android.support.v4.app.Fragment.performDestroy(Fragment.java:2322)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1240)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1272)
                      at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:2186)
                      at android.support.v4.app.FragmentController.dispatchDestroy(FragmentController.java:271)
                      at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:388)
                      at android.support.v7.app.AppCompatActivity.onDestroy(AppCompatActivity.java:209)
                      at android.app.Activity.performDestroy(Activity.java:5273)
                      at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1110)
                      at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3438)
                      at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3469)
                      at android.app.ActivityThread.access$1200(ActivityThread.java:141)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:137)
                      at android.app.ActivityThread.main(ActivityThread.java:5041)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:511)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                      at dalvik.system.NativeStart.main(Native Method)

真实设备结果: enter image description here smulator结果: enter image description here

1 个答案:

答案 0 :(得分:0)

在Menifest文件中的Application标记中添加以下行:

  android:largeHeap="true"