从Eclipse运行我的应用程序时出现异常

42

我已经遇到这个问题将近两个月了,但无法解决。问题在于如果我的应用程序正在运行,而我从Eclipse重新运行(重新安装)我的应用程序,我会收到一个错误消息,指示我的应用程序崩溃了“很抱歉, 已停止”。我注意到,当我离开我的PC/Eclipse后运行它时,也会出现这种情况,我认为只有在我不运行一段时间后才会发生。

只有在应用程序处于第三个活动(BaseDiagramActivity)并且我再次从Eclipse运行该应用程序时,才会出现此问题。我基本上剥离了所有应用程序,除了这3个活动之外,但问题仍然存在。

我已经搜索并寻找解决此问题的方法,但找不到任何好的答案或适用于我的答案。

这似乎不是硬件或Android版本的问题,因为我正在我的平板电脑(4.0.3)和手机(4.0.2,在更新之前发生在4.0.1)上运行它。除非这是一个冰淇淋三明治的错误。

如果需要更多信息,请告诉我。

异常(标签=AndroidRuntime)

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate application android.app.Application: java.lang.NullPointerException
   at android.app.LoadedApk.makeApplication(LoadedApk.java:482)
   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3938)
   at android.app.ActivityThread.access$1300(ActivityThread.java:123)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4424)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
   at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
   at android.app.LoadedApk.initializeJavaContextClassLoader(LoadedApk.java:362)
   at android.app.LoadedApk.getClassLoader(LoadedApk.java:305)
   at android.app.LoadedApk.makeApplication(LoadedApk.java:474)
   ... 11 more

Android代码

LoadedApk.initializeJavaContextClassLoader() - 第362行似乎是罪魁祸首

以下是相关文件:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="[my package]"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="14" />

    <application 
        android:icon="@drawable/ic_launcher" 
        android:label="@string/app_name" >
        <activity 
            android:name="HomeActivity" 
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="LoadDiagramActivity" android:label="Load Diagram"></activity>
        <activity android:name="BaseDiagramActivity" android:label="Base Diagram"></activity>
    </application>

</manifest>

HomeActivity.java

public class HomeActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.home);

        Button diagramButton = (Button)findViewById(R.id.diagram);
        diagramButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startActivity(new Intent(HomeActivity.this, LoadDiagramActivity.class));
            }
        });
    }
}

LoadDiagramActivity.java

public class LoadDiagramActivity extends Activity {

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

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.load_diagram_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
            case R.id.add_new_diagram:
                startActivity(new Intent(this, BaseDiagramActivity.class));
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

BaseDiagramActivity.java(基础流程图活动)

实际上,无论是哪个活动,只要启动了“第三”个活动(或点击LoadDiagramActivity上的添加按钮),异常就会发生。

public class BaseDiagramActivity extends Activity {
}

home.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/diagram"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Diagram" />

</LinearLayout>

附加信息

当我把我的项目简化以便提问时,我将所有东西都移动到了包的命名空间中。在实际项目中有5个命名空间,但是当我用简化版本进行测试时它们仍然存在,只是没有被调用(至少在我看来是这样的)。

以下是这些包:

  • [package] - 通用逻辑
  • [package].activities - 所有活动和基本活动
  • [package].database - 与数据库的所有交互
  • [package].models - 用于保存/加载数据的模型
  • [package].renderables - 绘制到画布上的对象

我尝试在清单文件中添加`android:sharedUserId'属性,但是两次尝试似乎都没有起作用。当我最初调查此问题时,我得出结论,共享用户ID仅适用于不同的项目,而不是不同的包。

另外,我认为在我剥离一切时没有任何与数据库的交互。第三个活动可以是任何活动,甚至是HomeActivity,这是反对这个理论的证据之一。

有用的链接

2012年1月11日更新

最近几天我回到了这个项目中,我在Eclipse Juno中创建了一个全新的项目,并手动转移了所有内容,以便让Eclipse和Android工具处理几乎所有的清单文件交互,但是问题仍然存在。我将在接下来的几天里再仔细研究一下,如果发现任何有用信息,我将进行更新。

FYI,我的新项目目标如下:

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="15" />

新的项目结构现在将所有活动都置于根包中(即[package],而不是 [package].activities)。我还使用了(新的?)语法来显示父 activity:
<meta-data
    android:name="android.support.PARENT_ACTIVITY"
    android:value="[my package].LoadDiagramActivity" />

我的Galaxy Nexus已更新到Jellybean 4.1.2,但问题仍在发生。


你可以在 Github 或其他地方提供简单的应用程序代码吗? - Jin35
我现在很难做到,因为我刚搬家,桌面电脑没有无线网络,无法上网。我用手机发帖。我相信如果你在Eclipse项目中创建这些文件,代码应该可以正常工作。 - Daniel Imms
尝试在HoneyComb或GingerBread上复制此行为,但在ICS中可能是一个错误 - yorkw
无论它在2.3或3.0中是否工作,它都不会真正解决问题。反正我本来就没有打算针对低于4.0的版本。其中一个有用的链接似乎将最低SDK版本定为8。 - Daniel Imms
1
“...11 more” 是logcat中的最后一个错误/红线。 - Daniel Imms
显示剩余3条评论
9个回答

9
尝试在清单文件中添加一个东西,我相信你已经尝试过了...
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="[my package]" 
    android:versionCode="1" 
    android:versionName="1.0"
    android:sharedUserId="com.mj.app" > 

看起来您的项目中有多个包,如 com.package.p1 , com.package.p2 ,com.package.p3..

在启动时,您位于 p1 然后移动到 p2 - p3... 在这个过程中,如果尝试再次运行,Android 将会报错。


这是我在询问stackoverflow之前调查的事情之一。我注意到你的sharedUserId存在一个小问题,即名称中必须至少有一个句点。我的项目实际上分为5个包,我将在问题底部更详细地解释。不过我对此表示怀疑,因为当我提出问题时,我剥离了大部分项目并将其全部放入项目的命名空间中,但问题仍然存在。然而,这基本上就是Android代码中异常所抱怨的内容。 - Daniel Imms
1
异常堆栈跟踪与这个类似的问题完全相同,请查看我在那里的答案是否有所帮助。 - yorkw
@yorkw 一个非常好的答案..但在我的情况下,当我通过不同的活动更改方向5-6次时,我的应用程序崩溃了,出现了相同的错误..因此,我需要解决此错误的解决方案。 - MKJParekh
据我所知,这个异常本身可能不会导致应用程序崩溃,但正如我在相关问题中所解释的那样,它试图重用或回收先前打开的活动/视图,因此我会仔细检查所有的构造/析构代码,并查看组件是否在正确的运行生命周期内正确地初始化/创建和销毁/完成,例如,在设备旋转时,会导致某些条件下的Activity被销毁并重新创建。 - yorkw
@MKJParekh,我应该给“sharedUserId”赋什么值?你能给像我这样的新手解释一下吗? - M. Usman Khan

2
如果我没记错的话,这种情况只会在我们通过Eclipse Run->As重新安装应用程序时发生。因此,当用户通过Play进行升级时,这种情况不太可能发生。我可以很自信地说这一点,因为我在通过Eclipse重新安装期间注意到我的应用程序也出现了这个异常,但是Crittercism上没有任何异常。
要解决这个问题,我努力解决了我的应用程序的内存消耗问题。
  1. 如果您只有1组可绘制对象,请更改它。创建一个drawables-mdpi并从那个1个drawables文件夹(drawables,drawable-ldpi)复制所有文件。如果您只有1组,则Android会将其调整大小以在更大的屏幕上使用,从而在内部占用过多的内存,并且此类内存(位图)的清除容易出错。听起来很疯狂,但确实非常有效。不要相信我,在进行此更改之前和之后,在堆内存使用情况监视下运行它,您会注意到您的应用程序对于常见情况少了25%的内存。
  2. 如果您正在执行任何位图操作,则可能需要考虑缩小。至少在设置选项时,您肯定要缩小它。查看这里这里。搜索或缩小。
  3. 最后,不要忘记在您的onDestroy之前和所有System.exit(0)之前bitmap.recycle(); bitmap = null;
Android会执行很多后台工作,并且重新安装是应用程序的突然清理期望。未清理的内存可能会导致问题。此异常是其中之一internal。因此,请不要认为它很简单。

如果我有时间的话,今晚我会去检查它。这不仅发生在从Eclipse运行时,还会在我打开应用程序、使用其他应用程序然后返回时发生(当它无法恢复并需要重新启动时,我认为)。 - Daniel Imms
很可能是位图问题。我到目前为止还没有看到你的东西。但异常看起来相似。我认为这是一个位图.recycle,null的问题。 - Siddharth
@Siddharth 在我的情况下,这个答案根本不相关。错误发生在有多个包含活动的包中运行应用程序并在它们之间移动、更改方向并来回跳转时。 - MKJParekh
更改方向时,Android会进行大量的调整和布局位置的假设。可绘制对象是绝对必要的。请执行此操作,同时观察您的堆内存运行情况。进行此更改并重新运行您的场景,再次观察您的堆内存。如果这不起作用,我会收回我的答案。 - Siddharth

2
如果您将minSdkVersion设置为13,它应该可以工作。
或者,在其他活动的onCreate()中需要setDisplayHomeAsUpEnabled(false)
这两种解决方案都应该有效。
根据文档,从API Level 14开始,默认情况下不再为您执行setHomeButtonEnabled(true),并且文档还指出:

设置DISPLAY_HOME_AS_UP显示选项将自动启用主页按钮。

因此,我们可以推断出setDisplayHomeAsUpEnabled(false)setHomeButtonEnabled(false)的作用方式类似。

我无法让任何一种方法起作用。我尝试注释掉所有与“ActionBar”交互的内容,添加“DISPLAY_HOME_AS_UP”标志,设置“setDisplayHomeAsUpEnabled(false)”等,但结果都相同。我仍然对SDK版本抱有一些希望,因为我还没有下载版本13,所以我无法针对低于4.0的任何内容进行目标定位。 - Daniel Imms
下载了13并将其定位,除去ICS特定的内容后,设置为最小SDK,但仍然出现相同的异常。 - Daniel Imms

0

你需要在Menifest中的activity名称前添加“.”。

像这样:

<?xml version="1.0" encoding="utf-8"?>

<uses-sdk android:minSdkVersion="14" />

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" >
    <activity 
        android:name=".HomeActivity" 
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".LoadDiagramActivity" android:label="Load Diagram"></activity>
    <activity android:name=".BaseDiagramActivity" android:label="Base Diagram"></activity>
</application>

我更新了您的清单(activity)。请您检查一下...


这不是它,这是a.ch回答的内容。 - Daniel Imms

0

为此,在清理项目时,请确保选中“自动构建”(Project -> Build Automatically)。


0

如果你的应用程序在第二次运行时崩溃,请稍等片刻。应用程序将在崩溃后再次启动。我有时也会遇到这种情况。如果您也遇到了同样的问题,请不要忘记每次运行之前清理项目。


这对我来说不是解决方案。 - MKJParekh

0
通过检查您的代码,我感觉您在LoadDiagramActivity中跳过了设置"setContentView(rid)"。请尝试在onCreate()中设置视图。
希望这能帮到您。

0

到目前为止,您提供的代码没有任何问题。我刚刚在一个新项目中尝试了一下,包名为com.test,它完美地工作了。我只添加了文件中的包声明。(当然,我还添加了load_diagram_menu.xml。)

如果可能的话,如果您能让我们访问完整的项目,那就太好了。如果该项目在其他人的计算机上运行正常,那么很可能是Eclipse或Android Eclipse插件出现了问题。重新安装Eclipse可以解决这个问题。(虽然我理解离线状态可能会使这变得困难。:-))


0

您在清单文件的android:name属性中未添加活动名称后面的句号。这可能导致问题。


不幸的是,那不是问题所在。我已经尝试过删除/添加句号来解决问题。 - Daniel Imms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接