如題,概述一下背景:
這個Bug是突然發生的,我在撰寫另外一部分的程式碼後,測試時在跳轉頁面時突然就crash了
除錯之後發現是錯在 「跳轉頁面之後 該Acticity 的setContentView(layout.xml)」
讓我很納悶的是,我修改後產生bug的程式碼跟此佈局(activity_baggage.xml)並無相關
之前在測試上時,跳轉到這個頁面也不曾crash過,所以我猜測這個bug是出在系統方面的錯誤。但我看Log並沒有很確定,爬了一下似乎是OutofMemory(OOM)但我不是很確定。因為之前沒有寫過這麼大的Android專案,加上沒碰過這樣的問題不太敢確定怎麼會突然發生這樣的問題。
另一點比較特殊的是,原本的模擬器(API_23)不行,我後來開了另外一個模擬器(API_27)來執行,跳轉到這個頁面卻完全沒有問題。
更新:
我嘗試過修改AVD的 VMHeap大小 (228->512MB)
crash的問題已經改善,可能是我這頁的Component個數太多
跳轉此Activity確實花費多了一些時間
(checkbox 一共有100多個 以Fragment方式呈現)
想請問在實務上會這樣操作嗎?還是真的要想辦法降低在該xml的元件個數?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("ching","db0");
setContentView(R.layout.activity_baggage); //Crash here
Log.v("ching","db1");
Initialize();
}
activity_baggage.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BaggageActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"></FrameLayout>
<RelativeLayout
android:id="@+id/funcLine"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:elevation="10dp"
android:background="@color/colorPrimary">
<at.markushi.ui.CircleButton
android:id="@+id/carried_baggage"
android:elevation="4dp"
android:layout_alignParentLeft="true"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/baggage"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="CarriedBaggagePage"
/>
<at.markushi.ui.CircleButton
android:id="@+id/life_baggage"
android:elevation="4dp"
android:layout_toRightOf="@id/carried_baggage"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/house"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="LifeBaggagePage"/>
<at.markushi.ui.CircleButton
android:id="@+id/camping_baggage"
android:elevation="4dp"
android:layout_toRightOf="@id/life_baggage"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/camping"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="CampingBaggagePage"/>
<at.markushi.ui.CircleButton
android:id="@+id/electronic_baggage"
android:elevation="4dp"
android:layout_toRightOf="@id/camping_baggage"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/camera"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="ElectronicBaggagePage"/>
<at.markushi.ui.CircleButton
android:id="@+id/selfDefined_baggage"
android:elevation="4dp"
android:layout_toRightOf="@id/electronic_baggage"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/setting"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="SelfDefinedBaggagePage"/>
<at.markushi.ui.CircleButton
android:id="@+id/btn_nextPage"
android:elevation="4dp"
android:layout_alignParentRight="true"
android:layout_width="64dip"
android:layout_height="128dip"
android:src="@drawable/nextpage"
app:cb_color="@color/material_light_orange"
app:cb_pressedRingWidth="6dip"
android:onClick="baggageSettingFinished"/>
</RelativeLayout>
</LinearLayout>
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tripmanager, PID: 10751
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tripmanager/com.example.tripmanager.BaggageActivity}: android.view.InflateException: Binary XML file line #52: Binary XML file line #52: Error inflating class
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #52: Binary XML file line #52: Error inflating class
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.example.tripmanager.BaggageActivity.onCreate(BaggageActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.InflateException: Binary XML file line #52: Error inflating class
at android.view.LayoutInflater.createView(LayoutInflater.java:645)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.example.tripmanager.BaggageActivity.onCreate(BaggageActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at android.view.LayoutInflater.createView(LayoutInflater.java:619)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.example.tripmanager.BaggageActivity.onCreate(BaggageActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 21344412 byte allocation with 4194304 free bytes and 15MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
at android.content.res.Resources.loadDrawable(Resources.java:2540)
at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
at android.widget.ImageView.(ImageView.java:152)
at android.widget.ImageView.(ImageView.java:140)
at android.widget.ImageView.(ImageView.java:136)
at at.markushi.ui.CircleButton.(CircleButton.java:43)
Binary XML file line #52: Binary XML file line #52: Error inflating class
這個錯指的是 activity_baggage.xml 的第52行,
看起來是用的這個第三方元件at.markushi.ui.CircleButton
https://github.com/markushi/android-circlebutton
他的github有說已經DEPRECATED,建議改用FAB。
100個checkbox的話,除了效能,更重要的是使用體驗的問題。
對使用者來說,在同一個畫面有100個checkbox,應該是太複雜了。
如果真的需要這麼多的話,可以考慮將功能分類,開啟不同的頁面來選取checkbox。
感謝回答 我會再去看看GITHUB的部分
提到checkbox的部分我是讓使用者勾選想要的行李
是在activity_baggage利用fragment拆成四個子頁面種類
所以同時顯示在頁面倒是沒有100個這麼多
不過這邊也衍伸一個之前寫這部分的問題
在實務上,這種大量的checkbox要勾選,有沒有什麼變數方式可以來命名(給予id)這些類型相同的大量重複元件。
因為checkbox勢必要對每一個元件都進行操作
我只能開Checkbox[] m_checkbox
但每一個都還是要獨自去find他的id
例如m_checkbox[0] =findViewById(R.id.baggage_1);
難道這樣大量的元件都要每一個獨自給他一個名稱嗎?
(可能講的不是很清楚 程式碼大概是像我寫的這樣的部分)
(findId的部分好像無法以變數來當那個位置)
public void checkbox_initialize(View view){
for (int i=0 ;i<checkbox_size ;i++){
switch (i){
case 0:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_1);
break ;
case 1:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_2);
break ;
case 2:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_3);
break ;
case 3:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_4);
break ;
case 4:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_5);
break ;
case 5:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_6);
break ;
case 6:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_7);
break ;
case 7:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_8);
break ;
case 8:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_9);
break ;
case 9:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_10);
break ;
case 10:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_11);
break ;
case 11:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_12);
break ;
case 12:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_13);
break ;
case 13:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_14);
break ;
case 14:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_15);
break ;
case 15:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_16);
break ;
case 16:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_17);
break ;
case 17:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_18);
break ;
case 18:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_19);
break ;
case 19:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_20);
break ;
case 20:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_21);
break ;
case 21:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_22);
break ;
case 22:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_23);
break ;
case 23:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_24);
break ;
case 24:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_25);
break ;
case 25:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_26);
break ;
case 26:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_27);
break ;
case 27:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_28);
break ;
case 28:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_29);
break ;
case 29:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_30);
break ;
case 30:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_31);
break ;
case 31:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_32);
break ;
case 32:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_33);
break ;
case 33:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_34);
break ;
case 34:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_35);
break ;
case 35:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_36);
break ;
case 36:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_37);
break ;
case 37:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_38);
break ;
case 38:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_39);
break ;
case 39:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_40);
break ;
case 40:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_41);
break ;
case 41:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_42);
break ;
case 42:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_43);
break ;
case 43:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_44);
break ;
case 44:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_45);
break ;
case 45:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_46);
break ;
case 46:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_47);
break ;
case 47:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_48);
break ;
case 48:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_49);
break ;
case 49:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_50);
break ;
case 50:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_51);
break ;
case 51:
camping_checkbox_array[i]= view.findViewById(R.id.checkbox_camping_52);
break ;
}
}
}
Checkbox[] m_checkbox;
for(int i=0; i<m_checkbox.length; i++) {
{
String chkID = "checkbox_camping_" + (i+1);
int resID = getResources().getIdentifier(chkID, "id", getPackageName());
m_checkbox[i] = ((Checkbox) findViewById(resID));
m_checkbox[i].setOnClickListener(this);
}
原來如此可以這樣使用 感謝
我一直以來這種大量都是這樣命名
原來我一直在用笨方法 謝謝