在我的应用中,我有这个错误:
E/AndroidRuntime(16123): FATAL EXCEPTION: main
E/AndroidRuntime(16123): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.bisemanuDEV.mathTools/it.bisemanuDEV.mathTools.MainActivity}: android.view.InflateException: Binary XML file line #58: Error inflating class <unknown>
E/AndroidRuntime(16123): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2073)
E/AndroidRuntime(16123): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2098)
E/AndroidRuntime(16123): at android.app.ActivityThread.access$600(ActivityThread.java:138)
E/AndroidRuntime(16123): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1204)
E/AndroidRuntime(16123): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(16123): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(16123): at android.app.ActivityThread.main(ActivityThread.java:4872)
E/AndroidRuntime(16123): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(16123): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(16123): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
E/AndroidRuntime(16123): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
E/AndroidRuntime(16123): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(16123): Caused by: android.view.InflateException: Binary XML file line #58: Error inflating class <unknown>
E/AndroidRuntime(16123): at android.view.LayoutInflater.createView(LayoutInflater.java:613)
E/AndroidRuntime(16123): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
E/AndroidRuntime(16123): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
E/AndroidRuntime(16123): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
E/AndroidRuntime(16123): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
05-11 20:21:56.843:E / AndroidRuntime(16123):在android.view.LayoutInflater.rInflate(LayoutInflater.java:749) E / AndroidRuntime(16123):在android.view.LayoutInflater.inflate(LayoutInflater.java:489) E / AndroidRuntime(16123):在android.view.LayoutInflater.inflate(LayoutInflater.java:396) E / AndroidRuntime(16123):在android.view.LayoutInflater.inflate(LayoutInflater.java:352) E / AndroidRuntime(16123):at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:361) E / AndroidRuntime(16123):在android.app.Activity.setContentView(Activity.java:2043) E / AndroidRuntime(16123):at it.bisemanuDEV.mathTools.MainActivity.onCreate(MainActivity.java:27) E / AndroidRuntime(16123):在android.app.Activity.performCreate(Activity.java:5191) E / AndroidRuntime(16123):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1082) E / AndroidRuntime(16123):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2037) E / AndroidRuntime(16123):... 11更多 E / AndroidRuntime(16123):引起:java.lang.reflect.InvocationTargetException E / AndroidRuntime(16123):at java.lang.reflect.Constructor.constructNative(Native Method) E / AndroidRuntime(16123):at java.lang.reflect.Constructor.newInstance(Constructor.java:417) E / AndroidRuntime(16123):在android.view.LayoutInflater.createView(LayoutInflater.java:587) E / AndroidRuntime(16123):......还有25个 E / AndroidRuntime(16123):引起:java.lang.OutOfMemoryError E / AndroidRuntime(16123):在android.graphics.BitmapFactory.nativeDecodeAsset(Native方法) E / AndroidRuntime(16123):在android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:500) E / AndroidRuntime(16123):在android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:353) E / AndroidRuntime(16123):在android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:781) E / AndroidRuntime(16123):在android.content.res.Resources.loadDrawable(Resources.java:1969) E / AndroidRuntime(16123):在android.content.res.Resources.getDrawable(Resources.java:673) E / AndroidRuntime(16123):在android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173) E / AndroidRuntime(16123):在android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881) E / AndroidRuntime(16123):在android.graphics.drawable.Drawable.createFromXml(Drawable.java:818) E / AndroidRuntime(16123):在android.content.res.Resources.loadDrawable(Resources.java:1954) E / AndroidRuntime(16123):在android.content.res.TypedArray.getDrawable(TypedArray.java:601) E / AndroidRuntime(16123):在android.view.View。(View.java:3347) E / AndroidRuntime(16123):在android.widget.TextView。(TextView.java:494) E / AndroidRuntime(16123):在android.widget.Button。(Button.java:107) E / AndroidRuntime(16123):在android.widget.Button。(Button.java:103) E / AndroidRuntime(16123):... 28更多
可以解决什么问题?
答案 0 :(得分:2)
你的应用程序内存增长太快......这就是Android管理每个应用程序的内存的方式:让我们说当你启动你的应用程序时,它有10MB的内存。当您的应用程序使用例如8MB时,Android会预测剩余的2MB可能还不够。因此Android为您的应用程序提供了额外的内存所以现在你有13MB(例如)。每次Android决定重映射内存可能不足以满足您的应用程序时,这种情况会重复出现。这样,来自应用程序的已用内存增长缓慢,Android可以更有效地管理它。
在您的示例中,您有一个解码图像的循环。这样,应用程序使用的内存大小增长得太快,Android没有时间为您提供更多内存。
答案 1 :(得分:1)
这条消息非常自我解释......你的内存已经不足了。
检查您传递给此方法的参数,可能只有太多的位图被解码并存储在内存中。
考虑缓存而不是预加载所有位图 - 只在实际需要使用时加载位图。然后将其添加到hasmap(从其ID到实际位图)。在解码位图之前,检查它是否已经在地图中,如果是,则不需要再次对其进行解码。在解码新位图之前一定要检查地图的大小,并在必要时清除缓存,这样就不会耗尽内存。
编辑:这是一个如何做到这一点的例子
Edit2:这是完整的类代码。希望我没有做任何拼写错误。
public class CurrencyRateListAdapter extends BaseAdapter {
// This variable is used for debug log (LogCat)
private static final String TAG = "CC:CurrencyRateListAdapter";
private LayoutInflater mInflater;
private String[] mName;
private Integer[] mBitmapIds;
private HashMap<Integer, Bitmap> mBitmaps;
private Context mContext;
private Cursor mRateData;
private double mRate[];
private String mDisplayrate[];
private int mBaseCurrencyPosition;
public CurrencyRateListAdapter(Context context, Integer[] name, Integer[] bitmapID, Cursor rate_data) {
mInflater = LayoutInflater.from(context);
mBitmaps = new HashMap<Integer, Bitmap>();
mBitmapIds = bitmapID;
mContext = context;
mName = new String[name.length];
for(int j=0; j<name.length; j++) {
mName[j] = context.getString(name[j]);
}
mRateData = rate_data;
// update currency rate
updateCurrencyRate();
// set default currency
mBaseCurrencyPosition = 0;
}
@Override
public void finalize() {
Log.d(TAG, "Close SQL cursor...");
mRateData.close();
}
public int getCount() {
return mBitmapIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
//Log.d(TAG, ">>>>> getView: position=" + Integer.toString(position));
try {
if(convertView == null) {
// uses currencyratelist.xml to display each currency selection
convertView = mInflater.inflate(R.layout.currencyratelist, null);
// then create a holder for this view for faster access
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.ratelist_icon);
holder.name = (TextView) convertView.findViewById(R.id.ratelist_text);
holder.rate = (TextView) convertView.findViewById(R.id.ratelist_ratetext);
// store this holder in the list
convertView.setTag(holder);
} else {
// load the holder of this view
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setImageBitmap(getIcon(mBitmapIds[position]));
holder.name.setText(mName[position]);
holder.rate.setText(mDisplayrate[position]);
} catch (Exception e) {
Log.e(TAG, "getView:" + e.toString());
}
//Log.d(TAG, "<<<<< getView: position=" + Integer.toString(position));
return convertView;
}
public void SetBaseCurrencyIndex(int value) {
mBaseCurrencyPosition = value;
// update display rate
double rate_base = 1.0;
if(mBaseCurrencyPosition < mRate.length) {
rate_base = mRate[mBaseCurrencyPosition];
}
mDisplayrate = new String[mRateData.getCount()];
for(int i=0; i<mRateData.getCount(); i++) {
mDisplayrate[i] = String.format(Locale.US, "%.3f", mRate[i] / rate_base);
}
}
public String getDisplayString(int position) {
String result = "1.000";
if(position < mRate.length) {
result = mDisplayrate[position];
}
return result;
}
public void updateCurrencyRate() {
Log.d(TAG, ">>>>> updateCurrencyRate");
// update currency rate data
mRateData.requery();
mRate = new double[mRateData.getCount()];
int cnt = mRateData.getCount();
int colcnt = mRateData.getColumnCount();
for(int i=0; i<cnt; i++) {
if(mRateData.moveToPosition(i) == true) {
if(colcnt == 1) {
// only currency rate data in the query result set
mRate[i] = mRateData.getDouble(0);
} else {
// all data in the query result set
// So the rate data in the 2nd column (refer to CurrencyConverterDB class
mRate[i] = mRateData.getDouble(1);
}
} else {
mRate[i] = 1.0;
}
}
// deactive currency rate data
mRateData.deactivate();
Log.d(TAG, "<<<<< updateCurrencyRate");
}
public double getCurrencyRate(int position) {
double rate_sel = 1.0;
if(position < mRate.length) {
rate_sel = mRate[position];
}
return rate_sel;
}
/* class ViewHolder */
private class ViewHolder {
ImageView icon;
TextView name;
TextView rate;
}
private Bitmap getIcon(Integer bitmapId) {
Bitmap icon = mBitmaps.get(bitmapId);
if (icon == null) {
icon = BitmapFactory.decodeResource(mContext.getResources(), bitmapId);
mBitmaps.put(bitmapId, icon);
}
return icon;
}
}
答案 2 :(得分:0)
你得到了java.lang.OutOfMemoryError,因为你正在运行这个for循环
for(int i=0; i<bitmapID.length; i++) {
mIcon[i] = BitmapFactory.decodeResource(context.getResources(), bitmapID[i].intValue());
}
请注意,decodeResource可能会导致这种情况。我建议你尝试其他方法,因为这个函数确实需要很多内存。
您可能还想计算所需的尺寸而不是解码。在大多数情况下,你并不需要完整的尺寸。