【问题标题】:Memory leaks android内存泄漏android
【发布时间】:2011-06-28 15:27:25
【问题描述】:

我的应用程序有一个大问题,因为它经常崩溃,但从不在同一个地方。

在它工作正常之前,我在每个应用程序中都重复了一个方法来检查语言。我决定将该方法放在一个名为 Utils 的静态类中,也许这就是问题所在???

这是我所有活动的开始方式:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //set up idioma
    sharedPrefs =PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    idioma = sharedPrefs.getString("listPref2", "catala");
    idioma=Utils.updateLanguage(getApplicationContext(), idioma);

    setContentView(R.layout.list_event);

}

这会造成内存泄漏吗?我应该避免为此使用静态类吗?我怎么能不重复相同的代码 20 次?

我得到的错误:

06-28 15:24:31.411: INFO/ActivityManager(52): Starting activity: Intent { act=android.intent.action.VIEW cmp=com.tresipunt.butxaca.com/com.tresipunt.butxaca.AllEventsDetailsTabs (has extras) }
06-28 15:24:31.551: ERROR/dalvikvm-heap(341): 2160000-byte external allocation too large for this process.
06-28 15:24:31.551: ERROR/(341): VM won't let us allocate 2160000 bytes
06-28 15:24:31.551: DEBUG/AndroidRuntime(341): Shutting down VM
06-28 15:24:31.551: WARN/dalvikvm(341): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
06-28 15:24:31.561: ERROR/AndroidRuntime(341): Uncaught handler: thread main exiting due to uncaught exception
06-28 15:24:31.592: ERROR/AndroidRuntime(341): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tresipunt.butxaca.com/com.tresipunt.butxaca.AllEventsDetailsTabs}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tresipunt.butxaca.com/com.tresipunt.butxaca.AllEventsDetailsTabList}: android.view.InflateException: Binary XML file line #21: Error inflating class java.lang.reflect.Constructor
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.access$2100(ActivityThread.java:116)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.os.Looper.loop(Looper.java:123)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.main(ActivityThread.java:4203)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at java.lang.reflect.Method.invokeNative(Native Method)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at java.lang.reflect.Method.invoke(Method.java:521)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at dalvik.system.NativeStart.main(Native Method)
06-28 15:24:31.592: ERROR/AndroidRuntime(341): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tresipunt.butxaca.com/com.tresipunt.butxaca.AllEventsDetailsTabList}: android.view.InflateException: Binary XML file line #21: Error inflating class java.lang.reflect.Constructor
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:2242)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:631)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.widget.TabHost.setCurrentTab(TabHost.java:317)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.widget.TabHost.addTab(TabHost.java:210)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.tresipunt.butxaca.AllEventsDetailsTabs.onCreate(AllEventsDetailsTabs.java:101)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     ... 11 more
06-28 15:24:31.592: ERROR/AndroidRuntime(341): Caused by: android.view.InflateException: Binary XML file line #21: Error inflating class java.lang.reflect.Constructor
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.createView(LayoutInflater.java:512)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:562)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:617)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:313)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.Activity.setContentView(Activity.java:1620)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at com.tresipunt.butxaca.AllEventsDetailsTabList.onCreate(AllEventsDetailsTabList.java:117)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     ... 20 more
06-28 15:24:31.592: ERROR/AndroidRuntime(341): Caused by: java.lang.reflect.InvocationTargetException
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.widget.ListView.<init>(ListView.java:148)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at java.lang.reflect.Constructor.constructNative(Native Method)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.view.LayoutInflater.createView(LayoutInflater.java:499)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     ... 31 more
06-28 15:24:31.592: ERROR/AndroidRuntime(341): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.Bitmap.nativeCreate(Native Method)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:476)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322)
06-28 15:24:31.592: ERROR/AndroidRuntime(341):     at android.graphics.drawable.Drawable.createFromResourceStr

它是在谈论位图,但这里的唯一位图可以是所有活动都相同的背景图像,但我该如何解决呢?

谢谢

【问题讨论】:

    标签: android memory bitmap memory-leaks static-methods


    【解决方案1】:

    我应该避免为此使用静态类吗?

    我认为使用静态类是可以的,但您必须记住,您使用的上下文只能在您从中获取它的应用程序或活动对象的生命周期内使用。这意味着如果您访问上下文对象并且它所附加的原始对象已经被销毁,您可能会得到一个空异常。

    我怎么能不重复相同的代码 20 次?

    一种方法是创建一个基 Activity 类,其中包含所有需要在所有活动中完成的常见事情。然后,只需让您的每个独特活动都扩展这个公共活动类。

    例如,在你常见的 Activity 类中:

    public CommonActivityBase extends Activity {
        public onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
    
        //set up idioma
        sharedPrefs =PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        idioma = sharedPrefs.getString("listPref2", "catala");
        idioma=Utils.updateLanguage(getApplicationContext(), idioma);
    
        }
        ...
    }
    

    在你的活动课程中:

    public ActivityA extends CommonActivityBase {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstance);
            ....  // do other stuff specific to this activity
            setContentView(R.layout.list_event);
        }
        ....
    }
    
    public ActivityB extends CommonActivityBase {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstance);
            ....  // do other stuff specific to this activity
            setContentView(R.layout.list_for_activity_b);
        }
        ....
    }
    

    【讨论】:

      【解决方案2】:

      在查看日志后,我猜想您要膨胀的 xml 文件存在一些问题。

      【讨论】:

      • 是的,但不应该。它实际上说错误是可绘制的第 21 行,第 21 行是这样的: android:background="@drawable/fonsbutxacadroid2" 在它正常工作之前应该没有任何问题。
      • hmm...先清理后重建您的项目...也许这可以解决问题
      • 我的问题不完全是关于那个,我想知道我的代码是否使用静态类引发内存泄漏并将上下文传递给它?谢谢