只要服务生活,如何持有对象?

时间:2013-11-08 09:16:56

标签: android service singleton

我有一个Object,我在我的所有活动中使用它,其中包含大量复杂数据,使用Android框架保存对象状态并将其从活动传递到活动将是非常麻烦的,所以我认为只要应用程序存在,就可以创建一个管理这个对象的Singleton并使其生效。

尝试使用常规Java Singleton方案,使用普通类和普通静态实例,但实例在一段时间后变为null(这非常令人困惑,为什么仍然引用的Object会变为null并且垃圾被收集?) 。所以我决定与Android设计师合作并创建一个服务来管理这个对象,服务看起来像这样:

public class DataService extends Service {
    private Data data;
    private static DataService instance;
    @Override
    public void onCreate() {
        instance = this;
        data= new Data(...);
        instance.data.addProgressListener(listener);
        (new Thread() {
            @Override
            public void run() {
                data.doInitProgress();
                listener = null;
            };
        }).start();

    }


    public static void listenToInitDataProcess(final ProgressBar progressBar,final Runnable onDone) {

        listener = new ProgressListener() {
            private int progress;
            private int max;
            @Override
            public void onUpdateProgress(final long i) {
                progressBar.setProgress(progress+=i);
            }

            @Override
            public void onProgressEndComputed(final long n) {
                progressBar.setMax(max=(int) n);
            }

            @Override
            public void onDone() {
                progressBar.setProgress(max);
                onDone.run();
            }
        };
            if (instance!=null) instance.data.addProgressListener(listener);
    }

    public static Data getData() {
        return instance.data;
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}

现在的问题是,应用程序启动后一段时间我得到的实例导致的NPE为空...注意我正在听数据对象创建,我试图只是在它之后得到它一旦被引入,那么该实例就不会被认为是空的......

如何做到这一点呢?

2 个答案:

答案 0 :(得分:2)

如果你想要一个与你的应用程序存在一样长的对象(即只要它的进程不被OS杀死),你可以扩展android.app.Application,将你的'全局'数据放在那里并使用该子类作为您的应用上下文(需要在清单中声明)

然而,许多人认为单身人士提供与自定义上下文基本相同的结果,例如 Singletons vs. Application Context in Android?

答案 1 :(得分:-1)

  

但实例在一段时间后变为null

首先,了解Effective Java的单身推荐,以及某些内容不会变为空:

// Singleton with public final field
public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }

    public void leaveTheBuilding() { ... }
}

但服务是不同的,因为那里没有公共构造函数。因此,首先检查服务是否正在运行(在本文中引用:Check if Service is running from a Broadcast Receiver):

private boolean isMyServiceRunning(Context context) {
    ActivityManager manager = (ActivityManager)      context.getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (DataService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }

    return false;
}

然后在服务中定义一些方法以返回所需的状态变量。