【问题标题】:App crashes when Custom listview Scrolling自定义列表视图滚动时应用程序崩溃
【发布时间】:2014-03-20 12:57:37
【问题描述】:

我使用 Webservice 并获取 Data 。我使用了自定义 lisatview 。我在 imagebutton 中设置图像。但我向上滚动然后应用程序崩溃。我的代码如下。

public class HomeFragment extends Fragment {

    ListView lv;
    ArrayList<All_list_home_dto> list = new ArrayList<All_list_home_dto>();
    MyListAdapter adt;
    All_list_home_dto list_home;
    String cityName;
    View rootView;
    private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
    private long lastPressTime;
    boolean mHasDoubleClicked;
    private ProgressDialog progress;
    MyApplication app;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.home, container, false);
        app = (MyApplication) getActivity().getApplicationContext();
        lv = (ListView) rootView.findViewById(R.id.home_listview);

        cityName = getActivity().getIntent().getExtras().getString("cityName")
                .toString();

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        if (cityName.trim().equals("")) {

            Toast.makeText(getActivity().getApplicationContext(),
                    " No City Name Available ", Toast.LENGTH_LONG).show();
        } else {
            progress = new ProgressDialog(getActivity());
            progress.setMessage("Loading...");

            new JSONTask(progress).execute("Home");

        }

        return rootView;
    }

    public class JSONTask extends AsyncTask<String, Void, String> {

        public JSONTask(ProgressDialog progress) {
            progress = progress;
        }

        public void onPreExecute() {
            progress.show();
        }

        @Override
        protected String doInBackground(String... arg) {
            String listSize = "";
            Log.v("log_tag", "list DoinBaCK ");

            list = DBAdpter.getNewsData(cityName);

            Log.v("log_tag", "list_size :: " + list.size());
            listSize = list.size() + "";
            return listSize; // This value will be returned to your
                                // onPostExecute(result) method
        }

        @Override
        protected void onPostExecute(String result) {
            // Create here your JSONObject...
            Log.v("log_tag", "list ON Post");

            if (Integer.parseInt(result) > 0) {
                adt = new MyListAdapter(getActivity());
                lv.setAdapter(adt);
            } else {

                Toast.makeText(getActivity().getApplicationContext(),
                        " No Stroe Data Available ", Toast.LENGTH_LONG).show();
            }
            progress.dismiss();

        }

        // You'll have to override this method on your other tasks that extend
        // from this one and use your JSONObject as needed

    }

    public class MyListAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        public MyListAdapter(Context context) {
            mInflater = LayoutInflater.from(context);

        }

        public int getCount() {
            return list.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(final int position, View convertView,
                ViewGroup parent) {
            convertView = mInflater.inflate(R.layout.custom_home_list, null);

            ImageButton home_ic_img = (ImageButton) convertView
                    .findViewById(R.id.list_home_logo_image);
            ImageButton home_big_img = (ImageButton) convertView
                    .findViewById(R.id.sarees_big_img);
            TextView home_username_txt = (TextView) convertView
                    .findViewById(R.id.home_list_username);
            TextView home_view_txt = (TextView) convertView
                    .findViewById(R.id.home_view_txt_view);

            TextView itemName_txt = (TextView) convertView
                    .findViewById(R.id.itemName_txt);

            Button close_btn = (Button) convertView
                    .findViewById(R.id.close_home_btn);

            home_username_txt.setText(list.get(position).store_name.toString());
            home_view_txt.setText("Views: "
                    + list.get(position).views.toString());
            itemName_txt.setText(list.get(position).name.toString());
            final String uid = app.getUserID();

            if (list.get(position).image.toString().trim().equals("")) {

                Log.v("log_tag", "image :::: ");
                home_big_img.setImageResource(R.drawable.ic_launcher);
            } else {

                byte[] Image_getByte;
                try {
                    Image_getByte = Base64.decode(list.get(position).image);
                    ByteArrayInputStream bytes = new ByteArrayInputStream(
                            Image_getByte);
                    BitmapDrawable bmd = new BitmapDrawable(bytes);
                    Bitmap bm = bmd.getBitmap();
                    home_big_img.setImageBitmap(bm);

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

            }



            if (list.get(position).picture.toString().trim().equals("")) {
                Log.v("log_tag", "picture :::: " );
                home_ic_img.setImageResource(R.drawable.ic_launcher);
            } else {

                byte[] Image_getByte1;
                try {
                    Image_getByte1 = Base64.decode(list.get(position).picture);
                    ByteArrayInputStream bytes1 = new ByteArrayInputStream(
                            Image_getByte1);
                    BitmapDrawable bmd1 = new BitmapDrawable(bytes1);
                    Bitmap bm1 = bmd1.getBitmap();
                    home_ic_img.setImageBitmap(bm1);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

            home_big_img.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub

                    findDoubleClick(list.get(position).store_id,
                            list.get(position).item_id);

                    if (mHasDoubleClicked) {
                        String msg = DBAdpter.userClosestStore(
                                list.get(position).item_id,
                                list.get(position).store_id, uid);
                        Toast.makeText(getActivity().getApplicationContext(),
                                msg, 1).show();
                    }

                }
            });
            close_btn.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub

                    String msg = DBAdpter.userClosestStore(
                            list.get(position).item_id,
                            list.get(position).store_id, uid);
                    Toast.makeText(getActivity().getApplicationContext(), msg,
                            1).show();
                }
            });

            return convertView;
        }
    }

    private boolean findDoubleClick(final String str_id, final String itemId) {
        // Get current time in nano seconds.
        long pressTime = System.currentTimeMillis();
        // If double click...
        if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
            mHasDoubleClicked = true;

            // double click event....
        } else { // If not double click....
            mHasDoubleClicked = false;
            Handler myHandler = new Handler() {
                public void handleMessage(Message m) {

                    if (!mHasDoubleClicked) {
                        // single click event
                        FragmentManager fm = getFragmentManager();
                        FragmentTransaction fragmentTransaction = fm
                                .beginTransaction();
                        StoreDetailFragment fm2 = new StoreDetailFragment();
                        fragmentTransaction.replace(R.id.rela_home_fragment,
                                fm2, "HELLO");
                        fragmentTransaction.addToBackStack(null);
                        fragmentTransaction.commit();
                        Bundle bundle = new Bundle();
                        bundle.putString("position", str_id);
                        fm2.setArguments(bundle);

                        DBAdpter.updateItemView(itemId);
                    }
                }
            };
            Message m = new Message();
            myHandler.sendMessageDelayed(m, DOUBLE_PRESS_INTERVAL);
        }
        lastPressTime = pressTime;
        return mHasDoubleClicked;
    }

}

并得到错误:

03-20 18:26:20.819: E/AndroidRuntime(7041): FATAL EXCEPTION: main
03-20 18:26:20.819: E/AndroidRuntime(7041): java.lang.OutOfMemoryError
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:695)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.graphics.drawable.BitmapDrawable.<init>(BitmapDrawable.java:152)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at com.marketplacestore.fragment.HomeFragment$MyListAdapter.getView(HomeFragment.java:207)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.AbsListView.obtainView(AbsListView.java:2570)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.ListView.makeAndAddView(ListView.java:1838)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.ListView.fillDown(ListView.java:681)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.ListView.fillGap(ListView.java:645)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6464)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3642)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:4456)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.View.dispatchTouchEvent(View.java:7669)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2395)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2119)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2401)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2134)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2284)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1578)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.app.Activity.dispatchTouchEvent(Activity.java:2468)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2232)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.View.dispatchPointerEvent(View.java:7876)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3894)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3778)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5030)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5009)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5107)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:174)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5080)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5126)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.Choreographer.doCallbacks(Choreographer.java:591)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.Choreographer.doFrame(Choreographer.java:559)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.os.Handler.handleCallback(Handler.java:725)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.os.Looper.loop(Looper.java:137)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at android.app.ActivityThread.main(ActivityThread.java:5283)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at java.lang.reflect.Method.invokeNative(Native Method)
03-20 18:26:20.819: E/AndroidRuntime(7041):     at java.lang.reflect.Me

【问题讨论】:

  • 您遇到了 outOfMemoryError。您在手机中缓存的图像有多大?
  • 是的,你是对的!!!但是如何解决这个问题。
  • 您应该阅读有关您的适配器的efficient Bitmap handlingholder pattern。这应该可以帮助您解决 OOM 异常并使您的应用更加流畅。

标签: android listview android-intent bitmap


【解决方案1】:

首先,您的 getView 方法在 UI 线程上做了太多工作。

例如

Image_getByte = Base64.decode(list.get(position).image);
ByteArrayInputStream bytes = new ByteArrayInputStream(
Image_getByte);
BitmapDrawable bmd = new BitmapDrawable(bytes);
Bitmap bm = bmd.getBitmap();

您应该使用任务来处理图像,然后将图像缓存在例如 LRUCache 中。 这个link should be helpful

另外,您应该观看google io 2009 的视频

它向您展示了如何回收您的视图,使用 ViewHolder 避免在每次调用 getView 时调用消耗的 findViewById()...

这是一个如何实现视图持有者的示例:

/** Holder pattern to recycle your view **/
    public static class ViewHolder { 
        public ImageButton home_ic_img;
        public ImageButton home_big_img;
        public TextView home_username_txt;
        and so on..
    }
    
    public View getView(final int position, View convertView,
            ViewGroup parent) {
            
        if (convertView != null && convertView.getTag() instanceof ViewHolder) {
            holder = (ViewHolder) convertView.getTag(); //reuse the "cached" view
        } else {

            convertView = mInflater.inflate(R.layout.custom_home_list, parent, false);
            holder = new ViewHolder();
            holder.home_ic_img = (ImageButton) convertView.findViewById(R.id.list_home_logo_image);
            holder.home_big_img = convertView.findViewById(R.id.sarees_big_img);
            holder.home_username_txt = (TextView) convertView .findViewById(R.id.home_list_username);
            and so on..
            convertView.setTag(holder); //most important thing.. it "caches" your view
        }
        ....

        return convertView;
    }
}

但同样,我强烈建议您观看视频以了解其工作原理。

希望对你有帮助

【讨论】:

    【解决方案2】:

    我建议你使用Aquery来下载图片。只需从下面的链接下载jarfile

    https://code.google.com/p/android-query/downloads/detail?name=android-query.0.26.7.jar
    

    并使用

    调用它
    AQuery _aq = new AQuery(youractivity context);
    

    //从网络上获取和设置图片,缓存到文件和内存中

    aq.id(R.id.Your imageview  object).image("http://www.vikispot.com/z/images/vikispot/android-w.png");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多