Android 当应用程序处于后台时,如何防止配置类被释放

Android 当应用程序处于后台时,如何防止配置类被释放,android,Android,我制作了一个Android应用程序,它有一个配置结构,其中包含我在所有活动中需要的数据和服务 我现在面临的问题是,如果我的应用程序在后台运行一段时间,我的应用程序就会崩溃,因为我的配置结构已被删除 在我的配置结构中,我也有数据,我不能在运行时轻松地重新创建 因此,在我的第一个活动中,我创建了配置结构 FreightWeightConfig config = new FreightWeightConfig(getApplicationContext()); // make sure our con

我制作了一个Android应用程序,它有一个配置结构,其中包含我在所有活动中需要的数据和服务

我现在面临的问题是,如果我的应用程序在后台运行一段时间,我的应用程序就会崩溃,因为我的配置结构已被删除

在我的配置结构中,我也有数据,我不能在运行时轻松地重新创建

因此,在我的第一个活动中,我创建了配置结构

FreightWeightConfig config = new FreightWeightConfig(getApplicationContext()); // make sure our config is up and running
我的config类的开头看起来像

public FreightWeightConfig(Context appContext) {
        instance = this;
        mApplicationContext = appContext;
        tcBlue.setCallingContext(appContext);
        tcBlueConfig = Config.getInstance(); // to make sure it is available straight away
        mFirebaseAuth = FirebaseAuth.getInstance();
        ....
}
我在config结构中还有第二个函数,它允许我获取config类的实例,我需要它来访问config和services中的函数和接口

public static synchronized FreightWeightConfig getInstance () {
        //if (FreightWeightConfig.instance == null) {
        //    FreightWeightConfig.instance = new FreightWeightConfig(getApplication().getApplicationContext());
        //}

        if (FreightWeightConfig.instance == null){
            FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Fatal Error : FreightWeightConfig.getInstance()==null. Try restarting the APP");
            FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Fatal Error : Killing ourself, as we have no chance to go on");
            //System.exit(0); // we are in a bad state
            // Toast.makeText(mApplicationContext, "Fatal Error : FreightWeightConfig.getInstance()==null. Try restarting the APP", Toast.LENGTH_SHORT).show();
  }

    return FreightWeightConfig.instance;
}
在每个活动中,我都创建了一个变量来保存实例的副本。这很简单,因为我认为它告诉系统,我仍然需要这个类,不要杀死它。这似乎不起作用

我首先想到,每当我发现我的配置类死了,我就可以重新创建它。但这不是一项简单的任务,因为我需要应用程序上下文,并且需要在后台重新创建我的服务。在浏览我的应用程序时,我还会存储所做的选择

谁有好主意,如何解决卸载/删除我的配置类

根据建议,我将应用程序扩展如下:

public class FreightWeightApp extends Application implements DialogInterface.OnCancelListener {

    private String LOG_TAG = "FreightWeightApp";
    private FreightWeightConfig config;

    public static int GOOGLE_PLAY_SERVIE_ABBORTED = 1001;

    public void onCreate() {
        super.onCreate();
        // We first check if the google services are present, if not, better abort!!
        int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
        switch (result) {
            case SUCCESS:
                Log.d(LOG_TAG, "Google Services available");
                break;
            case SERVICE_MISSING:
                Log.e(LOG_TAG, "Google Services missing, STOP");
                googleServiceNotUpToDateDialog(result);
                break;
            case SERVICE_VERSION_UPDATE_REQUIRED:
                Log.w(LOG_TAG, "Service update required");
                googleServiceNotUpToDateDialog(result);
                break;
            case SERVICE_DISABLED:
                Log.e(LOG_TAG, "Service disabled, STOP");
                googleServiceNotUpToDateDialog(result);
                break;
        }


        config = new FreightWeightConfig(getApplicationContext()); // make sure our config is up and running
    }

    private void googleServiceNotUpToDateDialog(int result) {
        // Try to ask the user to update or finish off
//        GoogleApiAvailability gaa = GoogleApiAvailability.getInstance();
//        Dialog dialog = gaa.getErrorDialog(this, result, GOOGLE_PLAY_SERVIE_ABBORTED, this);    //<==== Can not call this, as I have no Activity Context
//        dialog.show();
    }

    @Override
    public void onCancel(DialogInterface dialogInterface) {
        // Now I should abbort the APP, or we will crash.
    }
}

因为我没有活动上下文。

创建自己的实现,然后在方法中初始化配置对象(在本例中,getInstance()方法也可以初始化对象)

在应用程序的模块清单中声明您的实现:

<?xml version="1.0" encoding="utf-8"?>                                         
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package">                                            

    <application
        android:name="your.package.MyApplication"                                                              
        android:icon="@mipmap/ic_launcher"                                     
        android:label="@string/app_name"                                       
        android:theme="@style/AppTheme">
        ...            

    </application>                                                             

</manifest>                                                                    

...            

现在,您可以像调用getInstance()一样在活动中使用配置实例;应用程序onCreate将完成加载工作。但是没有办法“在应用程序进程被终止/缓存之前卸载资源”,你只需要了解Android组件的生命周期是如何工作的。

在活动暂停时保持状态,在活动恢复时读取状态?我喜欢这个想法,但在创建配置之前,我必须检查我的谷歌服务是否是最新的。否则我会撞车。我在配置中使用谷歌API,例如FireBase数据库。到目前为止,我调用了getErrorDialog(Activity,int,int,DialogInterface.OnCancelListener);由于我没有活动上下文,我又有点卡住了。1-从应用程序类中删除DialogInterface实现;2-从应用程序onCreate方法中删除所有Google代码;3-将你的谷歌代码放入你的配置类;4-将onCreate方法中的配置初始化为单例。5-在您的活动中实现DialogInterface,并回调您的配置;6-从活动中调用配置,如下所示:FreightWeightConfing.genInstance().isPlayServicesOk(this),其中这是在播放服务逻辑完成时配置将调用的回调的活动实现。如果我像你说的那样,我回到了我的原始问题。如果我执行了第4步,并且我的配置在后台运行了一段时间,那么操作系统会终止并释放我的配置。这就是我对应用程序类采用新方法的原因。我的配置需要在创建时访问Google(Firebase)代码。我有点运气。我在配置中早期使用的函数已经存在于旧的PlayServices中。因此,我可以像“Diego dos Santos”所建议的那样移动我的测试和对话功能。
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FreightWeightConfig config = FreightWeightConfig.getInstance(getApplicationContext());
    }
}
<?xml version="1.0" encoding="utf-8"?>                                         
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package">                                            

    <application
        android:name="your.package.MyApplication"                                                              
        android:icon="@mipmap/ic_launcher"                                     
        android:label="@string/app_name"                                       
        android:theme="@style/AppTheme">
        ...            

    </application>                                                             

</manifest>