Android,应用已停止

时间:2013-10-15 14:17:16

标签: android memory-leaks broadcastreceiver intentservice

我有一个android(4.1)应用程序据说(无法重新创建)chrashes消息“app as stopped”。然而,问题是用户必须在弹出的警报中按“确定”。仅当应用程序未处于活动状态时(屏幕上)才会出现chrash。这表明Android由于记忆或顽皮而杀死了我的应用。我一直在调查内存泄漏,因为我在应用程序中处理位图,但没有得到回报。

我有一个catch并记录所有默认处理程序,如下所示:

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            public void uncaughtException(Thread thread, Throwable ex) {
                Log.e(StaticData.LogTag, "Unhandled exception app", ex);
            }
        });

记录所有异常。之后我打电话给原始的异常处理程序。此处理程序放在Apps主要活动上。当“停止”骚扰发生时,永远不会调用该方法,但在其他情况下也是如此。

我的应用使用IntentService在后台将数据发送到服务器。这不是一个长期服务,1-10s。我将尝试在服务上放置一个默认的异常处理程序。我提到这项服务是因为应用程序在“屏幕外”被杀,所以我认为这可能与问题有关,但是原因让我感到厌烦。

此外,我使用BroadcastReceiver通知应用程序主要活动有关网络连接更改,因为该应用程序用于动荡的网络条件。这是相关的,因为当人们谈论可能的内存泄漏问题时,我看过BroadcastReceiver。我对BradcastReceiver的实现是这样的:

服务方:

sendOrderedBroadcast(uploadedIntent, null);

活动方:

public static class NetworkStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent in) {
        // super.onReceive(context, intent);
        Log.d(StaticData.LogTag, "Network connectivity change");
        if (in.getExtras() != null) {
            NetworkInfo ni = (NetworkInfo) in.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i(StaticData.LogTag, "Network " + ni.getTypeName() + " connected");
                ...                 
            }
        }
        if (in.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d(StaticData.LogTag, "There's no network connectivity");
        }
    }
}

正如我在开始时提到的,问题主要是用户的烦恼,因为他在查看邮件或接听电话时必须在弹出窗口按ok。该应用程序足够强大,可以处理它不时被杀死,但是,我想弄清楚为什么我的应用程序被淘汰。

PS。我试图让用户通过mx log logcollector发送bug报告,但没有雪茄。

1 个答案:

答案 0 :(得分:0)

我似乎已经解决了这个问题。我认为罪魁祸首是对应用程序中主要活动的静态引用。我使用这个静态来获取对应用程序Context的引用。然而,这在Service和BroadcastReceiver中是不必要的,因为它们有自己的引用“Context”。

为什么长脸?

对Android视图的静态引用(如Activity)保留在内存中,垃圾收集器无法释放。这是让它静止的背后的想法。我希望将来能够引用该对象,但这是错误的方法。

当更改方向(例如)时,Android会重新创建当前活动(和子视图),并且旧的GC将被释放。当您对视图进行静态引用时,它不会被收集,现在您有2个Activity实例。算一算,意识到这显然会随着时间的推移填补内存(泄漏),Android会在某个时候点击应用程序。

当遇到这个问题时,您必须意识到必须将数据/状态传递给新的Activity,例如使用共享内存,本地数据库或savedInstanceState:

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
       int value = savedInstanceState.getInteger("key");
    }
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
    outState.putInteger("key", value);
}