java - 加载图像时应用程序崩溃

标签 java android eclipse image load

所以我正在尝试制作一个应用程序,当您单击一个按钮时,它会显示大量图像。问题是当我点击按钮时,应用程序崩溃了。 这是我的 XML 文件的一部分。它有 36 张不同的图像:

<ImageView
    android:id="@+id/imageView31"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:src="@drawable/veh1" />

    <ImageView
    android:id="@+id/imageView32"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:src="@drawable/veh2" />

    <ImageView
    android:id="@+id/imageView33"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:src="@drawable/veh3" />

...

这是 LogCat:

02-18 22:47:00.263: E/AndroidRuntime(366): FATAL EXCEPTION: main
02-18 22:47:00.263: E/AndroidRuntime(366): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.guzi.samphelptools/com.guzi.samphelptools.Vehicles}: android.view.InflateException: Binary XML file line #81: Error inflating class <unknown>
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.os.Looper.loop(Looper.java:130)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread.main(ActivityThread.java:3683)
02-18 22:47:00.263: E/AndroidRuntime(366):  at java.lang.reflect.Method.invokeNative(Native Method)
02-18 22:47:00.263: E/AndroidRuntime(366):  at java.lang.reflect.Method.invoke(Method.java:507)
02-18 22:47:00.263: E/AndroidRuntime(366):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-18 22:47:00.263: E/AndroidRuntime(366):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-18 22:47:00.263: E/AndroidRuntime(366):  at dalvik.system.NativeStart.main(Native Method)
02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: android.view.InflateException: Binary XML file line #81: Error inflating class <unknown>
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.createView(LayoutInflater.java:518)
02-18 22:47:00.263: E/AndroidRuntime(366):  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
02-18 22:47:00.263: E/AndroidRuntime(366):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.Activity.setContentView(Activity.java:1657)
02-18 22:47:00.263: E/AndroidRuntime(366):  at com.guzi.samphelptools.Vehicles.onCreate(Vehicles.java:14)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
02-18 22:47:00.263: E/AndroidRuntime(366):  ... 11 more
02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: java.lang.reflect.InvocationTargetException
02-18 22:47:00.263: E/AndroidRuntime(366):  at java.lang.reflect.Constructor.constructNative(Native Method)
02-18 22:47:00.263: E/AndroidRuntime(366):  at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.view.LayoutInflater.createView(LayoutInflater.java:505)
02-18 22:47:00.263: E/AndroidRuntime(366):  ... 24 more
02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.content.res.Res`enter code here`ources.loadDrawable(Resources.java:1709)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.widget.ImageView.<init>(ImageView.java:118)
02-18 22:47:00.263: E/AndroidRuntime(366):  at android.widget.ImageView.<init>(ImageView.java:108)
02-18 22:47:00.263: E/AndroidRuntime(366):  ... 27 more

好的,所以我找到了这个简单的 ListView ,但我无法让它运行。

        import android.os.Bundle;
import android.app.Activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    // Array of integers points to images stored in /res/drawable-hdpi/
    int[] vehs = new int[]{
        R.drawable.veh1,         
        R.drawable.veh2,   
        R.drawable.veh3,
        R.drawable.veh4,
        R.drawable.veh5,
        R.drawable.veh6,
        R.drawable.veh7,
        R.drawable.veh8,
        R.drawable.veh9,
        R.drawable.veh10,
        R.drawable.veh11,         
        R.drawable.veh12,   
        R.drawable.veh13,
        R.drawable.veh14,
        R.drawable.veh15,
        R.drawable.veh16,
        R.drawable.veh17,
        R.drawable.veh18,
        R.drawable.veh19,
        R.drawable.veh20,
        R.drawable.veh21,         
        R.drawable.veh22,   
        R.drawable.veh23,
        R.drawable.veh24,
        R.drawable.veh25,
        R.drawable.veh26,
        R.drawable.veh27,
        R.drawable.veh28,
        R.drawable.veh29,
        R.drawable.veh30,
        R.drawable.veh31,
        R.drawable.veh32,
        R.drawable.veh33,
        R.drawable.veh34,
        R.drawable.veh35,
        R.drawable.veh36,
    };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Each row in the list stores country name, currency and flag
        List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();

        for(int i=0;i<10;i++){
            HashMap<String, String> hm = new HashMap<String,String>();
            hm.put("", Integer.toString(vehs[i]) );
            aList.add(hm);
        }

        // Keys used in Hashmap
        String[] from = { "flag","txt","cur" };

        // Ids of views in listview_layout
        int[] to = { R.id.vehs};

        // Instantiating an adapter to store each items
        // R.layout.listview_layout defines the layout of each item
        SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);

        // Getting a reference to listview of main.xml layout file
        ListView listView = ( ListView ) findViewById(R.id.listview);

        // Setting the adapter to the listView
        listView.setAdapter(adapter);
    }
}

如果你能帮我解决这个问题,那就太好了! :D

最佳答案

我猜你这里的问题是你同时加载了所有东西。您应该尝试使用 ListView 并为每一行充气!这样做的方式是您的应用程序将一次加载一个或两个 ImageView,其余的将留在一边,直到用户滚动靠近它。

我为此找到的教程是(观看#71 到大约#87 - 你可以在 slidenerd.com 上获得他的所有视频):
http://www.youtube.com/watch?v=uic3TVp_j3M#t=0

您还应该调整位图的大小,这样它们就不会以全分辨率加载。例如,540*420 屏幕不需要 1920x1080 图像。以下链接向您展示了如何解决这个问题。 http://developer.android.com/training/displaying-bitmaps/index.html

所以,最后,您将只有 1 个 ListView、1 个 ImageView,而且代码更少,困惑也更少 :P

编辑:快速指南: 我将只向您介绍 ListView 方法,因为我认为 Google 缩小图像示例很容易理解。

因此,首先,您将拥有以下内容:

  1. myActivity.xml(您需要这些图像的主要 Activity)
  2. 单行(单行的布局)
  3. MyActivity.java(您的 Activity 的 java 类)

myActivity.xml 将包含一个 ListView:

<ListView
    android:id="@+id/lvList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >
</ListView>

singleRow.xml 将仅包含一个 ImageView - 您将使用相同的 ImageView 的 LayoutParamaters 并将它们镜像 36 次:

<ImageView
    android:id="@+id/ivImage"
    android:layout_width="50dp"
    android:layout_height="85dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:src="@drawable/ic_launcher" />

MyActivity.java - 所有魔法都在这里发生!

public class MyActivity extends Activity implements OnItemClickListener {
    ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        lv = (ListView) findViewById(R.id.lvList);
        MyAdapter adapter = new MyAdapter(this);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        MyView holder = (MyView) view.getTag(); // This will get the tag of the item click - that is set up below
    }

    //Create a holder for the image that will be in an ImageView
    class SingleRowData {
        int img;

        SingleRowData(int img) {
            this.img = img;
        }
    }

    //A reference to the ImageView that needs to be copied
    private class MyView {
        ImageView ivImg;

        MyView(View v) {
            ivImg = (ImageView) v.findViewById(R.id.ivHomePageRow);
        }
    }

    class MyAdapter extends BaseAdapter{
        ArrayList<SingleHPSRow> list;
        Context context;

        public MyAdapter(Context context) {
            this.context = context;
            list = new ArrayList<SingleRowData>();
            ...
            int[] imgId = ...; // let's say you are getting all the images from your resources .. you will have to set this up, I'm guessing you know how to.
            for(int item = 0; item < imgUrl.length; i++) {
                list.add(imgId[item]);
            }
        }

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

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            view row = convertView; //This will try to see if the row has already been loaded b4
            MyView holder = null; initialize our custome View for the row
            if(row == null) { // new row
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //Get the LayoutInflater
                row = inflater.inflate(R.layout.singleRow, parent, false); //Reference to the row layout
                holder = new MyView(row);
                row.setTag(holder); // Give the row a tag - the holder that contains the item
            } else { // old row
                holder = (MyView) row.getTag(); //Get the tag that was assigned
            }
            SingleRowData item = list.get(position); //Get the item at the current position
            int image = item.img; //Get the imgId assigned to the current item
            holder.ivImg.setImageResource(image); //Load image for the current position
            return row; // Return the current row
        }
    }
}

希望这得到很好的解释,我复制并缩短了我的一个代码。有什么不明白的可以私信我

关于java - 加载图像时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21867298/

相关文章:

Windows 7 上的 Eclipse

java - 通过某些组件名称模式将组件/类加载到 ArrayList 中

java - 需要有关链表排序插入的帮助

java - 解析 XML 并检索信息 多层节点 Deep Java/Android

android - android phonegap 应用程序数据保存在哪里?

java - 如何将插件(从现有 jar 创建)转换为 Maven

java - Joda api 不返回正确的伊斯兰日期

java - 为 Spring Controller 自动生成客户端

java - com.twitter.sdk.android.core.TwitterApiException : HTTP request failed, 状态:403

eclipse - eclipse的vi插件?